Esempio n. 1
0
int gmx_nmtraj(int argc,char *argv[])
{
    const char *desc[] = 
    {
        "[TT]g_nmtraj[tt] generates an virtual trajectory from an eigenvector, ",
        "corresponding to a harmonic cartesian oscillation around the average ",
        "structure. The eigenvectors should normally be mass-weighted, but you can ",
        "use non-weighted eigenvectors to generate orthogonal motions. ",
        "The output frames are written as a trajectory file covering an entire period, and ",
        "the first frame is the average structure. If you write the trajectory in (or convert to) ",
        "PDB format you can view it directly in PyMol and also render a photorealistic movie. ",
        "Motion amplitudes are calculated from the eigenvalues and a preset temperature, ",
        "assuming equipartition of the energy over all modes. To make the motion clearly visible ",
        "in PyMol you might want to amplify it by setting an unrealistic high temperature. ", 
        "However, be aware that both the linear cartesian displacements and mass weighting will ",
        "lead to serious structure deformation for high amplitudes - this is is simply a limitation ",
        "of the cartesian normal mode model. By default the selected eigenvector is set to 7, since ",
        " the first six normal modes are the translational and rotational degrees of freedom." 
    };

    static real refamplitude=0.25;
    static int  nframes=30;
    static real temp=300.0;
    static const char *eignrvec = "7";
    static const char *phasevec  = "0.0";
    
    t_pargs pa[] =
    {
        { "-eignr",     FALSE, etSTR,  {&eignrvec}, "String of eigenvectors to use (first is 1)" },
        { "-phases",    FALSE, etSTR,  {&phasevec}, "String of phases (default is 0.0)" },
        { "-temp",      FALSE, etREAL, {&temp},      "Temperature in Kelvin" },
        { "-amplitude", FALSE, etREAL, {&refamplitude}, "Amplitude for modes with eigenvalue<=0" },
        { "-nframes",   FALSE, etINT,  {&nframes},   "Number of frames to generate" }
    };
    
#define NPA asize(pa)
  
  int        out;
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;
  rvec       *xtop,*xref,*xav,*xout;
  int        nvec,*eignr=NULL;
  int        *eigvalnr;
  rvec       **eigvec=NULL;
  matrix     box;
  int        natoms;
  int        i,j,k,kmode,d,s,v;
  bool       bDMR,bDMA,bFit;
  char *     indexfile;
  
  char *     grpname;
  real *     eigval;
  int        neigval;
  int *      dummy;
  real *     invsqrtm;
  char       title[STRLEN];
  real       fraction;
  int        *out_eigidx;
  real       *out_eigval;
  rvec *     this_eigvec;
  real       omega,Ekin,sum,m,vel;
  bool       found;
  int        nmodes,nphases;
  int        *imodes;
  real       *amplitude;
  real       *phases;
  real       dum;
  const char       *p;
  char *pe;  
    
  t_filenm fnm[] = 
  { 
      { efTPS, NULL,    NULL,          ffREAD },
      { efTRN, "-v",    "eigenvec",    ffREAD  },
      { efTRO, "-o",    "nmtraj",      ffWRITE }
  }; 
  
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL); 

  read_eigenvectors(opt2fn("-v",NFILE,fnm),&natoms,&bFit,
		    &xref,&bDMR,&xav,&bDMA,&nvec,&eignr,&eigvec,&eigval);

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,bDMA);
	
  /* Find vectors and phases */
  
  /* first find number of args in string */
  nmodes=0;
  p=eignrvec;
  while(*p!=0)
  {
      dum=strtod(p,&pe);
      p=pe;
      nmodes++;
  }

  snew(imodes,nmodes);
  p=eignrvec;
  for(i=0;i<nmodes;i++)
  {
	  /* C indices start on 0 */
      imodes[i]=strtol(p,&pe,10)-1;
      p = pe;
  }
 
  /* Now read phases */
  nphases=0;
  p=phasevec;
  while(*p!=0)
  {
      dum=strtod(p,&pe);
      p=pe;
      nphases++;
  }
  if(nphases>nmodes)
  {
      gmx_fatal(FARGS,"More phases than eigenvector indices specified.\n");
  }
    
  snew(phases,nmodes);
  p=phasevec;

  for(i=0;i<nphases;i++)
  {
      phases[i]=strtod(p,&pe);
      p = pe;
  }

  if(nmodes>nphases)
  {
      printf("Warning: Setting phase of last %d modes to zero...\n",nmodes-nphases);
  }
    
  for(i=nphases;i<nmodes;i++)
  {
      phases[i]=0;
  }
        
  atoms=&top.atoms;

  if(atoms->nr != natoms)
  {
      gmx_fatal(FARGS,"Different number of atoms in topology and eigenvectors.\n");
  }
  
  snew(dummy,natoms);
  for(i=0;i<natoms;i++)
      dummy[i]=i;

  /* Find the eigenvalue/vector to match our select one */ 
  snew(out_eigidx,nmodes);
  for(i=0;i<nmodes;i++)
    out_eigidx[i]=-1;
  
  for(i=0;i<nvec;i++)
  {
      for(j=0;j<nmodes;j++)
      {
          if(imodes[j]==eignr[i])
              out_eigidx[j]=i;
      }
  }
    for(i=0;i<nmodes;i++)
        if(out_eigidx[i]==-1)
            gmx_fatal(FARGS,"Could not find mode %d in eigenvector file.\n",imodes[i]);
    
  
  snew(invsqrtm,natoms);
  
  if (bDMA) 
  {
      for(i=0; (i<natoms); i++)
          invsqrtm[i] = invsqrt(atoms->atom[i].m);
  }
  else 
  {
      for(i=0; (i<natoms); i++)
          invsqrtm[i]=1.0;
  }

  snew(xout,natoms);
  snew(amplitude,nmodes);

  	printf("mode phases: %g %g\n",phases[0],phases[1]);
	
  for(i=0;i<nmodes;i++)
  {
      kmode = out_eigidx[i];
      this_eigvec=eigvec[kmode];
   
      if( (kmode >= 6) && (eigval[kmode] > 0))
      {		  		  
          /* Derive amplitude from temperature and eigenvalue if we can */
          
          /* Convert eigenvalue to angular frequency, in units s^(-1) */
          omega = sqrt(eigval[kmode]*1.0E21/(AVOGADRO*AMU));
          /* Harmonic motion will be x=x0 + A*sin(omega*t)*eigenvec.
           * The velocity is thus:
           * 
           * v = A*omega*cos(omega*t)*eigenvec.
           *
           * And the average kinetic energy the integral of mass*v*v/2 over a
           * period:
           *
           * (1/4)*mass*A*omega*eigenvec
           *
           * For t =2*pi*n, all energy will be kinetic, and v=A*omega*eigenvec.
           * The kinetic energy will be sum(0.5*mass*v*v) if we temporarily set A to 1,
		   * and the average over a period half of this.
           */
          
          Ekin = 0;
          for(k=0;k<natoms;k++)
          {
              m = atoms->atom[k].m;
              for(d=0;d<DIM;d++)
              {
                  vel   = omega*this_eigvec[k][d];
                  Ekin += 0.5*0.5*m*vel*vel;
              }
          }
		  
          /* Convert Ekin from amu*(nm/s)^2 to J, i.e., kg*(m/s)^2
           * This will also be proportional to A^2 
           */   
          Ekin *= AMU*1E-18;
          
          /* Set the amplitude so the energy is kT/2 */
          amplitude[i] = sqrt(0.5*BOLTZMANN*temp/Ekin);		  
	  }
	  else
	  {
		  amplitude[i] = refamplitude;
	  }
  }
	
  out=open_trx(ftp2fn(efTRO,NFILE,fnm),"w");
	
    /* Write a sine oscillation around the average structure, 
     * modulated by the eigenvector with selected amplitude.
     */
    
    for(i=0;i<nframes;i++)
    {
        fraction = (real)i/(real)nframes;
		for(j=0;j<natoms;j++)
		{
			copy_rvec(xav[j],xout[j]);
		}
		
        for(k=0;k<nmodes;k++)
        {
            kmode=out_eigidx[k];
            this_eigvec=eigvec[kmode];

            for(j=0;j<natoms;j++)
            {
                for(d=0;d<DIM;d++)
                {
					xout[j][d] += amplitude[k]*sin(2*M_PI*(fraction+phases[k]/360.0))*this_eigvec[j][d];
                }
            }
        }
        write_trx(out,natoms,dummy,atoms,i,(real)i/(real)nframes,box,xout,NULL,NULL);
    }    
    
    fprintf(stderr,"\n");
    close_trx(out);
    
    return 0;
}
Esempio n. 2
0
/*
 * Gromacs nonbonded kernel nb_kernel300
 * Coulomb interaction:     Tabulated
 * VdW interaction:         Not calculated
 * water optimization:      No
 * Calculate forces:        yes
 */
void nb_kernel300(
                    int *           p_nri,
                    int *           iinr,
                    int *           jindex,
                    int *           jjnr,
                    int *           shift,
                    real *          shiftvec,
                    real *          fshift,
                    int *           gid,
                    real *          pos,
                    real *          faction,
                    real *          charge,
                    real *          p_facel,
                    real *          p_krf,
                    real *          p_crf,
                    real *          Vc,
                    int *           type,
                    int *           p_ntype,
                    real *          vdwparam,
                    real *          Vvdw,
                    real *          p_tabscale,
                    real * VFtab,real * enerd1,real * enerd2,real * enerd3,real * enerd4,int * start,int * end,int * homenr,int * nbsum,
                    real *          invsqrta,
                    real *          dvda,
                    real *          p_gbtabscale,
                    real *          GBtab,
                    int *           p_nthreads,
                    int *           count,
                    void *          mtx,
                    int *           outeriter,
                    int *           inneriter,
                    real *          work)
{
    int           nri,ntype,nthreads;
    real          facel,krf,crf,tabscale,gbtabscale;
    int           n,ii,is3,ii3,k,nj0,nj1,jnr,j3,ggid;
    int           nn0,nn1,nouter,ninner;
    real          shX,shY,shZ;
    real          fscal,tx,ty,tz;
    real          iq;
    real          qq,vcoul,vctot;
    real          r,rt,eps,eps2;
    int           n0,nnn;
    real          Y,F,Geps,Heps2,Fp,VV;
    real          FF;
    real          fijC;
    real          ix1,iy1,iz1,fix1,fiy1,fiz1;
    real          jx1,jy1,jz1;
    real          dx11,dy11,dz11,rsq11,rinv11;
    int           index;

    nri              = *p_nri;         
    ntype            = *p_ntype;       
    nthreads         = *p_nthreads;    
    facel            = *p_facel;       
    krf              = *p_krf;         
    crf              = *p_crf;         
    tabscale         = *p_tabscale;    

    /* Reset outer and inner iteration counters */
    nouter           = 0;              
    ninner           = 0;              

    /* Loop over thread workunits */
    
    do
    {
#ifdef GMX_THREADS
        gmx_thread_mutex_lock((gmx_thread_mutex_t *)mtx);
        nn0              = *count;         
		
        /* Take successively smaller chunks (at least 10 lists) */
        nn1              = nn0+(nri-nn0)/(2*nthreads)+10;
        *count           = nn1;            
        gmx_thread_mutex_unlock((gmx_thread_mutex_t *)mtx);
        if(nn1>nri) nn1=nri;
#else
	    nn0 = 0;
		nn1 = nri;
#endif
        /* Start outer loop over neighborlists */
        
        for(n=nn0; (n<nn1); n++)
        {

            /* Load shift vector for this list */
            is3              = 3*shift[n];     
            shX              = shiftvec[is3];  
            shY              = shiftvec[is3+1];
            shZ              = shiftvec[is3+2];

            /* Load limits for loop over neighbors */
            nj0              = jindex[n];      
            nj1              = jindex[n+1];    

            /* Get outer coordinate index */
            ii               = iinr[n];        
            ii3              = 3*ii;           

            /* Load i atom data, add shift vector */
            ix1              = shX + pos[ii3+0];
            iy1              = shY + pos[ii3+1];
            iz1              = shZ + pos[ii3+2];

            /* Load parameters for i atom */
            iq               = facel*charge[ii];

            /* Zero the potential energy for this list */
            vctot            = 0;              

            /* Clear i atom forces */
            fix1             = 0;              
            fiy1             = 0;              
            fiz1             = 0;              
            
            for(k=nj0; (k<nj1); k++)
            {

                /* Get j neighbor index, and coordinate index */
                jnr              = jjnr[k];        
                j3               = 3*jnr;          

                if(enerd1)
                {
                 if(ii<jnr)
                 {
                  index = start[ii]**homenr - nbsum[start[ii]] + start[jnr];
                 }
                 else
                 {
                  index = start[jnr]**homenr - nbsum[start[jnr]] + start[ii];
                 }

                 enerd1[index] = enerd1[index] - vctot;
                }

                /* load j atom coordinates */
                jx1              = pos[j3+0];      
                jy1              = pos[j3+1];      
                jz1              = pos[j3+2];      

                /* Calculate distance */
                dx11             = ix1 - jx1;      
                dy11             = iy1 - jy1;      
                dz11             = iz1 - jz1;      
                rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;

                /* Calculate 1/r and 1/r2 */
                rinv11           = invsqrt(rsq11);

                /* Load parameters for j atom */
                qq               = iq*charge[jnr]; 

                /* Calculate table index */
                r                = rsq11*rinv11;   

                /* Calculate table index */
                rt               = r*tabscale;     
                n0               = rt;             
                eps              = rt-n0;          
                eps2             = eps*eps;        
                nnn              = 4*n0;           

                /* Tabulated coulomb interaction */
                Y                = VFtab[nnn];     
                F                = VFtab[nnn+1];   
                Geps             = eps*VFtab[nnn+2];
                Heps2            = eps2*VFtab[nnn+3];
                Fp               = F+Geps+Heps2;   
                VV               = Y+eps*Fp;       
                FF               = Fp+Geps+2.0*Heps2;
                vcoul            = qq*VV;          
                fijC             = qq*FF;          
                vctot            = vctot + vcoul;  
                fscal            = -((fijC)*tabscale)*rinv11;

                if(enerd1)
                {
                 enerd1[index] = enerd1[index] + vctot;
                }
                /* Calculate temporary vectorial force */
                tx               = fscal*dx11;     
                ty               = fscal*dy11;     
                tz               = fscal*dz11;     

                /* Increment i atom force */
                fix1             = fix1 + tx;      
                fiy1             = fiy1 + ty;      
                fiz1             = fiz1 + tz;      

                /* Decrement j atom force */
                faction[j3+0]    = faction[j3+0] - tx;
                faction[j3+1]    = faction[j3+1] - ty;
                faction[j3+2]    = faction[j3+2] - tz;

                /* Inner loop uses 42 flops/iteration */
            }
            

            /* Add i forces to mem and shifted force list */
            faction[ii3+0]   = faction[ii3+0] + fix1;
            faction[ii3+1]   = faction[ii3+1] + fiy1;
            faction[ii3+2]   = faction[ii3+2] + fiz1;
            fshift[is3]      = fshift[is3]+fix1;
            fshift[is3+1]    = fshift[is3+1]+fiy1;
            fshift[is3+2]    = fshift[is3+2]+fiz1;

            /* Add potential energies to the group for this list */
            ggid             = gid[n];         
            Vc[ggid]         = Vc[ggid] + vctot;

            /* Increment number of inner iterations */
            ninner           = ninner + nj1 - nj0;

            /* Outer loop uses 11 flops/iteration */
        }
        

        /* Increment number of outer iterations */
        nouter           = nouter + nn1 - nn0;
    }
    while (nn1<nri);
    

    /* Write outer/inner iteration count to pointers */
    *outeriter       = nouter;         
    *inneriter       = ninner;         
}
Esempio n. 3
0
/*
 * Gromacs nonbonded kernel nb_kernel231
 * Coulomb interaction:     Reaction field
 * VdW interaction:         Tabulated
 * water optimization:      SPC/TIP3P - other atoms
 * Calculate forces:        yes
 */
void nb_kernel231(
    int *           p_nri,
    int *           iinr,
    int *           jindex,
    int *           jjnr,
    int *           shift,
    real *          shiftvec,
    real *          fshift,
    int *           gid,
    real *          pos,
    real *          faction,
    real *          charge,
    real *          p_facel,
    real *          p_krf,
    real *          p_crf,
    real *          Vc,
    int *           type,
    int *           p_ntype,
    real *          vdwparam,
    real *          Vvdw,
    real *          p_tabscale,
    real * VFtab,real * enerd1,real * enerd2,real * enerd3,real * enerd4,int * start,int * end,int * homenr,int * nbsum,
    real *          invsqrta,
    real *          dvda,
    real *          p_gbtabscale,
    real *          GBtab,
    int *           p_nthreads,
    int *           count,
    void *          mtx,
    int *           outeriter,
    int *           inneriter,
    real *          work)
{
    int           nri,ntype,nthreads;
    real          facel,krf,crf,tabscale,gbtabscale;
    int           n,ii,is3,ii3,k,nj0,nj1,jnr,j3,ggid;
    int           nn0,nn1,nouter,ninner;
    real          shX,shY,shZ;
    real          fscal,tx,ty,tz;
    real          rinvsq;
    real          jq;
    real          qq,vcoul,vctot;
    int           nti;
    int           tj;
    real          Vvdw6,Vvdwtot;
    real          Vvdw12;
    real          r,rt,eps,eps2;
    int           n0,nnn;
    real          Y,F,Geps,Heps2,Fp,VV;
    real          FF;
    real          fijD,fijR;
    real          krsq;
    real          ix1,iy1,iz1,fix1,fiy1,fiz1;
    real          ix2,iy2,iz2,fix2,fiy2,fiz2;
    real          ix3,iy3,iz3,fix3,fiy3,fiz3;
    real          jx1,jy1,jz1,fjx1,fjy1,fjz1;
    real          dx11,dy11,dz11,rsq11,rinv11;
    real          dx21,dy21,dz21,rsq21,rinv21;
    real          dx31,dy31,dz31,rsq31,rinv31;
    real          qO,qH;
    real          c6,c12;

    nri              = *p_nri;
    ntype            = *p_ntype;
    nthreads         = *p_nthreads;
    facel            = *p_facel;
    krf              = *p_krf;
    crf              = *p_crf;
    tabscale         = *p_tabscale;

    /* Initialize water data */
    ii               = iinr[0];
    qO               = facel*charge[ii];
    qH               = facel*charge[ii+1];
    nti              = 2*ntype*type[ii];


    /* Reset outer and inner iteration counters */
    nouter           = 0;
    ninner           = 0;

    /* Loop over thread workunits */

    do
    {
#ifdef GMX_THREADS
        gmx_thread_mutex_lock((gmx_thread_mutex_t *)mtx);
        nn0              = *count;

        /* Take successively smaller chunks (at least 10 lists) */
        nn1              = nn0+(nri-nn0)/(2*nthreads)+10;
        *count           = nn1;
        gmx_thread_mutex_unlock((gmx_thread_mutex_t *)mtx);
        if(nn1>nri) nn1=nri;
#else
        nn0 = 0;
        nn1 = nri;
#endif
        /* Start outer loop over neighborlists */

        for(n=nn0; (n<nn1); n++)
        {

            /* Load shift vector for this list */
            is3              = 3*shift[n];
            shX              = shiftvec[is3];
            shY              = shiftvec[is3+1];
            shZ              = shiftvec[is3+2];

            /* Load limits for loop over neighbors */
            nj0              = jindex[n];
            nj1              = jindex[n+1];

            /* Get outer coordinate index */
            ii               = iinr[n];
            ii3              = 3*ii;

            /* Load i atom data, add shift vector */
            ix1              = shX + pos[ii3+0];
            iy1              = shY + pos[ii3+1];
            iz1              = shZ + pos[ii3+2];
            ix2              = shX + pos[ii3+3];
            iy2              = shY + pos[ii3+4];
            iz2              = shZ + pos[ii3+5];
            ix3              = shX + pos[ii3+6];
            iy3              = shY + pos[ii3+7];
            iz3              = shZ + pos[ii3+8];

            /* Zero the potential energy for this list */
            vctot            = 0;
            Vvdwtot          = 0;

            /* Clear i atom forces */
            fix1             = 0;
            fiy1             = 0;
            fiz1             = 0;
            fix2             = 0;
            fiy2             = 0;
            fiz2             = 0;
            fix3             = 0;
            fiy3             = 0;
            fiz3             = 0;

            for(k=nj0; (k<nj1); k++)
            {

                /* Get j neighbor index, and coordinate index */
                jnr              = jjnr[k];
                j3               = 3*jnr;

                /* load j atom coordinates */
                jx1              = pos[j3+0];
                jy1              = pos[j3+1];
                jz1              = pos[j3+2];

                /* Calculate distance */
                dx11             = ix1 - jx1;
                dy11             = iy1 - jy1;
                dz11             = iz1 - jz1;
                rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;
                dx21             = ix2 - jx1;
                dy21             = iy2 - jy1;
                dz21             = iz2 - jz1;
                rsq21            = dx21*dx21+dy21*dy21+dz21*dz21;
                dx31             = ix3 - jx1;
                dy31             = iy3 - jy1;
                dz31             = iz3 - jz1;
                rsq31            = dx31*dx31+dy31*dy31+dz31*dz31;

                /* Calculate 1/r and 1/r2 */
                rinv11           = invsqrt(rsq11);
                rinv21           = invsqrt(rsq21);
                rinv31           = invsqrt(rsq31);

                /* Load parameters for j atom */
                jq               = charge[jnr+0];
                qq               = qO*jq;
                tj               = nti+2*type[jnr];
                c6               = vdwparam[tj];
                c12              = vdwparam[tj+1];
                rinvsq           = rinv11*rinv11;

                /* Coulomb reaction-field interaction */
                krsq             = krf*rsq11;
                vcoul            = qq*(rinv11+krsq-crf);
                vctot            = vctot+vcoul;

                /* Calculate table index */
                r                = rsq11*rinv11;

                /* Calculate table index */
                rt               = r*tabscale;
                n0               = rt;
                eps              = rt-n0;
                eps2             = eps*eps;
                nnn              = 8*n0;

                /* Tabulated VdW interaction - dispersion */
                Y                = VFtab[nnn];
                F                = VFtab[nnn+1];
                Geps             = eps*VFtab[nnn+2];
                Heps2            = eps2*VFtab[nnn+3];
                Fp               = F+Geps+Heps2;
                VV               = Y+eps*Fp;
                FF               = Fp+Geps+2.0*Heps2;
                Vvdw6            = c6*VV;
                fijD             = c6*FF;

                /* Tabulated VdW interaction - repulsion */
                nnn              = nnn+4;
                Y                = VFtab[nnn];
                F                = VFtab[nnn+1];
                Geps             = eps*VFtab[nnn+2];
                Heps2            = eps2*VFtab[nnn+3];
                Fp               = F+Geps+Heps2;
                VV               = Y+eps*Fp;
                FF               = Fp+Geps+2.0*Heps2;
                Vvdw12           = c12*VV;
                fijR             = c12*FF;
                Vvdwtot          = Vvdwtot+ Vvdw6 + Vvdw12;
                fscal            = (qq*(rinv11-2.0*krsq))*rinvsq-((fijD+fijR)*tabscale)*rinv11;

                /* Calculate temporary vectorial force */
                tx               = fscal*dx11;
                ty               = fscal*dy11;
                tz               = fscal*dz11;

                /* Increment i atom force */
                fix1             = fix1 + tx;
                fiy1             = fiy1 + ty;
                fiz1             = fiz1 + tz;

                /* Decrement j atom force */
                fjx1             = faction[j3+0] - tx;
                fjy1             = faction[j3+1] - ty;
                fjz1             = faction[j3+2] - tz;

                /* Load parameters for j atom */
                qq               = qH*jq;
                rinvsq           = rinv21*rinv21;

                /* Coulomb reaction-field interaction */
                krsq             = krf*rsq21;
                vcoul            = qq*(rinv21+krsq-crf);
                vctot            = vctot+vcoul;
                fscal            = (qq*(rinv21-2.0*krsq))*rinvsq;

                /* Calculate temporary vectorial force */
                tx               = fscal*dx21;
                ty               = fscal*dy21;
                tz               = fscal*dz21;

                /* Increment i atom force */
                fix2             = fix2 + tx;
                fiy2             = fiy2 + ty;
                fiz2             = fiz2 + tz;

                /* Decrement j atom force */
                fjx1             = fjx1 - tx;
                fjy1             = fjy1 - ty;
                fjz1             = fjz1 - tz;

                /* Load parameters for j atom */
                rinvsq           = rinv31*rinv31;

                /* Coulomb reaction-field interaction */
                krsq             = krf*rsq31;
                vcoul            = qq*(rinv31+krsq-crf);
                vctot            = vctot+vcoul;
                fscal            = (qq*(rinv31-2.0*krsq))*rinvsq;

                /* Calculate temporary vectorial force */
                tx               = fscal*dx31;
                ty               = fscal*dy31;
                tz               = fscal*dz31;

                /* Increment i atom force */
                fix3             = fix3 + tx;
                fiy3             = fiy3 + ty;
                fiz3             = fiz3 + tz;

                /* Decrement j atom force */
                faction[j3+0]    = fjx1 - tx;
                faction[j3+1]    = fjy1 - ty;
                faction[j3+2]    = fjz1 - tz;

                /* Inner loop uses 130 flops/iteration */
            }


            /* Add i forces to mem and shifted force list */
            faction[ii3+0]   = faction[ii3+0] + fix1;
            faction[ii3+1]   = faction[ii3+1] + fiy1;
            faction[ii3+2]   = faction[ii3+2] + fiz1;
            faction[ii3+3]   = faction[ii3+3] + fix2;
            faction[ii3+4]   = faction[ii3+4] + fiy2;
            faction[ii3+5]   = faction[ii3+5] + fiz2;
            faction[ii3+6]   = faction[ii3+6] + fix3;
            faction[ii3+7]   = faction[ii3+7] + fiy3;
            faction[ii3+8]   = faction[ii3+8] + fiz3;
            fshift[is3]      = fshift[is3]+fix1+fix2+fix3;
            fshift[is3+1]    = fshift[is3+1]+fiy1+fiy2+fiy3;
            fshift[is3+2]    = fshift[is3+2]+fiz1+fiz2+fiz3;

            /* Add potential energies to the group for this list */
            ggid             = gid[n];
            Vc[ggid]         = Vc[ggid] + vctot;
            Vvdw[ggid]       = Vvdw[ggid] + Vvdwtot;

            /* Increment number of inner iterations */
            ninner           = ninner + nj1 - nj0;

            /* Outer loop uses 29 flops/iteration */
        }


        /* Increment number of outer iterations */
        nouter           = nouter + nn1 - nn0;
    }
    while (nn1<nri);


    /* Write outer/inner iteration count to pointers */
    *outeriter       = nouter;
    *inneriter       = ninner;
}
Esempio n. 4
0
/*
 * Gromacs nonbonded kernel nb_kernel410
 * Coulomb interaction:     Generalized-Born
 * VdW interaction:         Lennard-Jones
 * water optimization:      No
 * Calculate forces:        yes
 */
void nb_kernel410(
                    int *           p_nri,
                    int *           iinr,
                    int *           jindex,
                    int *           jjnr,
                    int *           shift,
                    real *          shiftvec,
                    real *          fshift,
                    int *           gid,
                    real *          pos,
                    real *          faction,
                    real *          charge,
                    real *          p_facel,
                    real *          p_krf,
                    real *          p_crf,
                    real *          Vc,
                    int *           type,
                    int *           p_ntype,
                    real *          vdwparam,
                    real *          Vvdw,
                    real *          p_tabscale,
                    real * VFtab,real * enerd1,real * enerd2,real * enerd3,real * enerd4,int * start,int * end,int * homenr,int * nbsum,
                    real *          invsqrta,
                    real *          dvda,
                    real *          p_gbtabscale,
                    real *          GBtab,
                    int *           p_nthreads,
                    int *           count,
                    void *          mtx,
                    int *           outeriter,
                    int *           inneriter,
                    real *          work)
{
    int           nri,ntype,nthreads;
    real          facel,krf,crf,tabscale,gbtabscale;
    int           n,ii,is3,ii3,k,nj0,nj1,jnr,j3,ggid;
    int           nn0,nn1,nouter,ninner;
    real          shX,shY,shZ;
    real          fscal,tx,ty,tz;
    real          rinvsq;
    real          iq;
    real          qq,vcoul,vctot;
    int           nti;
    int           tj;
    real          rinvsix;
    real          Vvdw6,Vvdwtot;
    real          Vvdw12;
    real          r,rt,eps,eps2;
    int           n0,nnn;
    real          Y,F,Geps,Heps2,Fp,VV;
    real          FF;
    real          fijC;
    real          isai,isaj,isaprod,gbscale,vgb,vgbtot;
    real          dvdasum,dvdatmp,dvdaj,fgb;
    real          ix1,iy1,iz1,fix1,fiy1,fiz1;
    real          jx1,jy1,jz1;
    real          dx11,dy11,dz11,rsq11,rinv11;
    real          c6,c12;
	gmx_gbdata_t *gbdata;
	real *        gpol;
	real          scale_gb;
	
	gbdata           = (gmx_gbdata_t *)work;
	gpol             = gbdata->gpol;
	
    nri              = *p_nri;         
    ntype            = *p_ntype;       
    nthreads         = *p_nthreads;    
    facel            = *p_facel;     
	scale_gb         = 1.0 - (1.0/gbdata->gb_epsilon_solvent);  
    krf              = *p_krf;         
    crf              = *p_crf;         
    tabscale         = *p_tabscale;    
    gbtabscale       = *p_gbtabscale;  

    /* Reset outer and inner iteration counters */
    nouter           = 0;              
    ninner           = 0;              

    /* Loop over thread workunits */
   
    do
    {
#ifdef GMX_THREADS
        gmx_thread_mutex_lock((gmx_thread_mutex_t *)mtx);
        nn0              = *count;         
		
        /* Take successively smaller chunks (at least 10 lists) */
        nn1              = nn0+(nri-nn0)/(2*nthreads)+10;
        *count           = nn1;            
        gmx_thread_mutex_unlock((gmx_thread_mutex_t *)mtx);
        if(nn1>nri) nn1=nri;
#else
	    nn0 = 0;
		nn1 = nri;
#endif
        /* Start outer loop over neighborlists */
        
        for(n=nn0; (n<nn1); n++)
        {

            /* Load shift vector for this list */
            is3              = 3*shift[n];     
            shX              = shiftvec[is3];  
            shY              = shiftvec[is3+1];
            shZ              = shiftvec[is3+2];

            /* Load limits for loop over neighbors */
            nj0              = jindex[n];      
            nj1              = jindex[n+1];    

            /* Get outer coordinate index */
            ii               = iinr[n];        
            ii3              = 3*ii;           

            /* Load i atom data, add shift vector */
            ix1              = shX + pos[ii3+0];
            iy1              = shY + pos[ii3+1];
            iz1              = shZ + pos[ii3+2];

            /* Load parameters for i atom */
            iq               = facel*charge[ii];
            isai             = invsqrta[ii];   
            nti              = 2*ntype*type[ii];

            /* Zero the potential energy for this list */
            vctot            = 0;              
            Vvdwtot          = 0;  
            vgbtot           = 0;
            dvdasum          = 0;              

            /* Clear i atom forces */
            fix1             = 0;              
            fiy1             = 0;              
            fiz1             = 0;              
            
            for(k=nj0; (k<nj1); k++)
            {

                /* Get j neighbor index, and coordinate index */
                jnr              = jjnr[k];        
                j3               = 3*jnr;          

                /* load j atom coordinates */
                jx1              = pos[j3+0];      
                jy1              = pos[j3+1];      
                jz1              = pos[j3+2];      

                /* Calculate distance */
                dx11             = ix1 - jx1;      
                dy11             = iy1 - jy1;      
                dz11             = iz1 - jz1;      
                rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;

                /* Calculate 1/r and 1/r2 */
                rinv11           = invsqrt(rsq11);

                /* Load parameters for j atom */
                isaj             = invsqrta[jnr];  
                isaprod          = isai*isaj;      
                qq               = iq*charge[jnr]; 
                vcoul            = qq*rinv11;      
                fscal            = vcoul*rinv11;   
                qq               = isaprod*(-qq)*scale_gb;  
                gbscale          = isaprod*gbtabscale;
                tj               = nti+2*type[jnr];
                c6               = vdwparam[tj];   
                c12              = vdwparam[tj+1]; 
                rinvsq           = rinv11*rinv11;  

                /* Tabulated Generalized-Born interaction */
                dvdaj            = dvda[jnr];      
                r                = rsq11*rinv11;   

                /* Calculate table index */
                rt               = r*gbscale;      
                n0               = rt;             
                eps              = rt-n0;          
                eps2             = eps*eps;        
                nnn              = 4*n0;           
                Y                = GBtab[nnn];     
                F                = GBtab[nnn+1];   
                Geps             = eps*GBtab[nnn+2];
                Heps2            = eps2*GBtab[nnn+3];
                Fp               = F+Geps+Heps2;   
                VV               = Y+eps*Fp;       
                FF               = Fp+Geps+2.0*Heps2;
                vgb              = qq*VV;          
                fijC             = qq*FF*gbscale;  
                dvdatmp          = -0.5*(vgb+fijC*r);
                dvdasum          = dvdasum + dvdatmp;
                dvda[jnr]        = dvdaj+dvdatmp*isaj*isaj;
                vctot            = vctot + vcoul;  
                vgbtot           = vgbtot + vgb;

                /* Lennard-Jones interaction */
                rinvsix          = rinvsq*rinvsq*rinvsq;
                Vvdw6            = c6*rinvsix;     
                Vvdw12           = c12*rinvsix*rinvsix;
                Vvdwtot          = Vvdwtot+Vvdw12-Vvdw6;
                fscal            = (12.0*Vvdw12-6.0*Vvdw6)*rinvsq-(fijC-fscal)*rinv11;

                /* Calculate temporary vectorial force */
                tx               = fscal*dx11;     
                ty               = fscal*dy11;     
                tz               = fscal*dz11;     

                /* Increment i atom force */
                fix1             = fix1 + tx;      
                fiy1             = fiy1 + ty;      
                fiz1             = fiz1 + tz;      

                /* Decrement j atom force */
                faction[j3+0]    = faction[j3+0] - tx;
                faction[j3+1]    = faction[j3+1] - ty;
                faction[j3+2]    = faction[j3+2] - tz;
				
                /* Inner loop uses 62 flops/iteration */
            }
            

            /* Add i forces to mem and shifted force list */
            faction[ii3+0]   = faction[ii3+0] + fix1;
            faction[ii3+1]   = faction[ii3+1] + fiy1;
            faction[ii3+2]   = faction[ii3+2] + fiz1;
            fshift[is3]      = fshift[is3]+fix1;
            fshift[is3+1]    = fshift[is3+1]+fiy1;
            fshift[is3+2]    = fshift[is3+2]+fiz1;

            /* Add potential energies to the group for this list */
            ggid             = gid[n];         
            Vc[ggid]         = Vc[ggid] + vctot;
            gpol[ggid]       = gpol[ggid] + vgbtot;
            Vvdw[ggid]       = Vvdw[ggid] + Vvdwtot;
            dvda[ii]         = dvda[ii] + dvdasum*isai*isai;

            /* Increment number of inner iterations */
            ninner           = ninner + nj1 - nj0;

            /* Outer loop uses 13 flops/iteration */
        }
        

        /* Increment number of outer iterations */
        nouter           = nouter + nn1 - nn0;
    }
    while (nn1<nri);
  
    /* Write outer/inner iteration count to pointers */
    *outeriter       = nouter;         
    *inneriter       = ninner;         
}
Esempio n. 5
0
/*
 * Gromacs nonbonded kernel nb_kernel121nf
 * Coulomb interaction:     Normal Coulomb
 * VdW interaction:         Buckingham
 * water optimization:      SPC/TIP3P - other atoms
 * Calculate forces:        no
 */
void nb_kernel121nf(
                    int *           p_nri,
                    int *           iinr,
                    int *           jindex,
                    int *           jjnr,
                    int *           shift,
                    real *          shiftvec,
                    real *          fshift,
                    int *           gid,
                    real *          pos,
                    real *          faction,
                    real *          charge,
                    real *          p_facel,
                    real *          p_krf,
                    real *          p_crf,
                    real *          Vc,
                    int *           type,
                    int *           p_ntype,
                    real *          vdwparam,
                    real *          Vvdw,
                    real *          p_tabscale,
                    real * VFtab,real * enerd1,real * enerd2,real * enerd3,real * enerd4,int * start,int * end,int * homenr,int * nbsum,
                    real *          invsqrta,
                    real *          dvda,
                    real *          p_gbtabscale,
                    real *          GBtab,
                    int *           p_nthreads,
                    int *           count,
                    void *          mtx,
                    int *           outeriter,
                    int *           inneriter,
                    real *          work)
{
    int           nri,ntype,nthreads;
    real          facel,krf,crf,tabscale,gbtabscale;
    int           n,ii,is3,ii3,k,nj0,nj1,jnr,j3,ggid;
    int           nn0,nn1,nouter,ninner;
    real          shX,shY,shZ;
    real          rinvsq;
    real          jq;
    real          qq,vcoul,vctot;
    int           nti;
    int           tj;
    real          rinvsix;
    real          Vvdw6,Vvdwtot;
    real          Vvdwexp,br;
    real          ix1,iy1,iz1;
    real          ix2,iy2,iz2;
    real          ix3,iy3,iz3;
    real          jx1,jy1,jz1;
    real          dx11,dy11,dz11,rsq11,rinv11;
    real          dx21,dy21,dz21,rsq21,rinv21;
    real          dx31,dy31,dz31,rsq31,rinv31;
    real          qO,qH;
    real          c6,cexp1,cexp2;

    nri              = *p_nri;         
    ntype            = *p_ntype;       
    nthreads         = *p_nthreads;    
    facel            = *p_facel;       
    krf              = *p_krf;         
    crf              = *p_crf;         
    tabscale         = *p_tabscale;    

    /* Initialize water data */
    ii               = iinr[0];        
    qO               = facel*charge[ii];
    qH               = facel*charge[ii+1];
    nti              = 3*ntype*type[ii];


    /* Reset outer and inner iteration counters */
    nouter           = 0;              
    ninner           = 0;              

    /* Loop over thread workunits */
    
    do
    {
#ifdef GMX_THREADS
        gmx_thread_mutex_lock((gmx_thread_mutex_t *)mtx);
        nn0              = *count;         
		
        /* Take successively smaller chunks (at least 10 lists) */
        nn1              = nn0+(nri-nn0)/(2*nthreads)+10;
        *count           = nn1;            
        gmx_thread_mutex_unlock((gmx_thread_mutex_t *)mtx);
        if(nn1>nri) nn1=nri;
#else
	    nn0 = 0;
		nn1 = nri;
#endif
        /* Start outer loop over neighborlists */
        
        for(n=nn0; (n<nn1); n++)
        {

            /* Load shift vector for this list */
            is3              = 3*shift[n];     
            shX              = shiftvec[is3];  
            shY              = shiftvec[is3+1];
            shZ              = shiftvec[is3+2];

            /* Load limits for loop over neighbors */
            nj0              = jindex[n];      
            nj1              = jindex[n+1];    

            /* Get outer coordinate index */
            ii               = iinr[n];        
            ii3              = 3*ii;           

            /* Load i atom data, add shift vector */
            ix1              = shX + pos[ii3+0];
            iy1              = shY + pos[ii3+1];
            iz1              = shZ + pos[ii3+2];
            ix2              = shX + pos[ii3+3];
            iy2              = shY + pos[ii3+4];
            iz2              = shZ + pos[ii3+5];
            ix3              = shX + pos[ii3+6];
            iy3              = shY + pos[ii3+7];
            iz3              = shZ + pos[ii3+8];

            /* Zero the potential energy for this list */
            vctot            = 0;              
            Vvdwtot          = 0;              

            /* Clear i atom forces */
            
            for(k=nj0; (k<nj1); k++)
            {

                /* Get j neighbor index, and coordinate index */
                jnr              = jjnr[k];        
                j3               = 3*jnr;          

                /* load j atom coordinates */
                jx1              = pos[j3+0];      
                jy1              = pos[j3+1];      
                jz1              = pos[j3+2];      

                /* Calculate distance */
                dx11             = ix1 - jx1;      
                dy11             = iy1 - jy1;      
                dz11             = iz1 - jz1;      
                rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;
                dx21             = ix2 - jx1;      
                dy21             = iy2 - jy1;      
                dz21             = iz2 - jz1;      
                rsq21            = dx21*dx21+dy21*dy21+dz21*dz21;
                dx31             = ix3 - jx1;      
                dy31             = iy3 - jy1;      
                dz31             = iz3 - jz1;      
                rsq31            = dx31*dx31+dy31*dy31+dz31*dz31;

                /* Calculate 1/r and 1/r2 */
                rinv11           = invsqrt(rsq11);
                rinv21           = invsqrt(rsq21);
                rinv31           = invsqrt(rsq31);

                /* Load parameters for j atom */
                jq               = charge[jnr+0];  
                qq               = qO*jq;          
                tj               = nti+3*type[jnr];
                c6               = vdwparam[tj];   
                cexp1            = vdwparam[tj+1]; 
                cexp2            = vdwparam[tj+2]; 
                rinvsq           = rinv11*rinv11;  

                /* Coulomb interaction */
                vcoul            = qq*rinv11;      
                vctot            = vctot+vcoul;    

                /* Buckingham interaction */
                rinvsix          = rinvsq*rinvsq*rinvsq;
                Vvdw6            = c6*rinvsix;     
                br               = cexp2*rsq11*rinv11;
                Vvdwexp          = cexp1*exp(-br); 
                Vvdwtot          = Vvdwtot+Vvdwexp-Vvdw6;

                /* Load parameters for j atom */
                qq               = qH*jq;          

                /* Coulomb interaction */
                vcoul            = qq*rinv21;      
                vctot            = vctot+vcoul;    

                /* Load parameters for j atom */

                /* Coulomb interaction */
                vcoul            = qq*rinv31;      
                vctot            = vctot+vcoul;    

                /* Inner loop uses 82 flops/iteration */
            }
            

            /* Add i forces to mem and shifted force list */

            /* Add potential energies to the group for this list */
            ggid             = gid[n];         
            Vc[ggid]         = Vc[ggid] + vctot;
            Vvdw[ggid]       = Vvdw[ggid] + Vvdwtot;

            /* Increment number of inner iterations */
            ninner           = ninner + nj1 - nj0;

            /* Outer loop uses 11 flops/iteration */
        }
        

        /* Increment number of outer iterations */
        nouter           = nouter + nn1 - nn0;
    }
    while (nn1<nri);
    

    /* Write outer/inner iteration count to pointers */
    *outeriter       = nouter;         
    *inneriter       = ninner;         
}
Esempio n. 6
0
real orires(int nfa,t_iatom forceatoms[],t_iparams ip[],
	    rvec x[],rvec f[],t_forcerec *fr,t_graph *g,
	    matrix box,real lambda,real *dvdlambda,
	    t_mdatoms *md,int ngrp,real egnb[],real egcoul[],
	    t_fcdata *fcd)
{
  atom_id      ai,aj;
  int          fa,d,i,type,ex,power,ki;
  ivec         dt;
  real         r2,invr,invr2,fc,smooth_fc,dev,devins,pfac;
  rvec         r,Sr,fij;
  real         vtot;
  t_oriresdata *od;
  bool         bTAV;

  vtot = 0;
  od = &(fcd->orires);

  if (fabs(od->fc) > GMX_REAL_MIN) {
    bTAV = (fabs(od->edt) > GMX_REAL_MIN);
    
    /* Smoothly switch on the restraining when time averaging is used */
    smooth_fc = od->fc*(1.0 - od->exp_min_t_tau);
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3) {
      type  = forceatoms[fa];
      ai    = forceatoms[fa+1];
      aj    = forceatoms[fa+2];
      rvec_sub(x[ai],x[aj],r);
      r2    = norm2(r);
      invr  = invsqrt(r2);
      invr2 = invr*invr;
      ex    = ip[type].orires.ex;
      power = ip[type].orires.pow;
      fc    = smooth_fc*ip[type].orires.kfac;
      dev   = od->otav[d] - ip[type].orires.obs;
      
      /* NOTE: there is no real potential when time averaging is applied */
      vtot += 0.5*fc*sqr(dev);
      
      if (bTAV) {
	/* Calculate the force as the sqrt of tav times instantaneous */
	devins = od->oins[d] - ip[type].orires.obs;
	if (dev*devins <= 0)
	  dev = 0;
	else {
	  dev = sqrt(dev*devins);
	  if (devins < 0)
	    dev = -dev;
	}
      }
      
      pfac  = fc*ip[type].orires.c*invr2;
      for(i=0; i<power; i++)
	pfac *= invr;
      mvmul(od->S[ex],r,Sr);
      for(i=0; i<DIM; i++)
	fij[i] = -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr,r)*r[i]);
      
      ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
      ki=IVEC2IS(dt);
      
      for(i=0; i<DIM; i++) {
	f[ai][i]               += fij[i];
	f[aj][i]               -= fij[i];
	fr->fshift[ki][i]      += fij[i];
	fr->fshift[CENTRAL][i] -= fij[i];
      }
      d++;
    }
  }
  
  return vtot;
  
  /* Approx. 80*nfa/3 flops */
}
Esempio n. 7
0
real calc_orires_dev(t_commrec *mcr,
		     int nfa,t_iatom forceatoms[],t_iparams ip[],
		     t_mdatoms *md,rvec x[],t_fcdata *fcd)
{
  int          fa,d,i,j,type,ex,nref;
  real         edt,edt1,invn,pfac,r2,invr,corrfac,weight,wsv2,sw,dev;
  tensor       *S,R,TMP;
  rvec5        *Dinsl,*Dins,*Dtav,*rhs;
  real         *mref,***T;
  rvec         *xref,*xtmp,com,r_unrot,r;
  t_oriresdata *od;
  bool         bTAV;
  static real  two_thr=2.0/3.0;

  od = &(fcd->orires);

  bTAV = (fabs(od->edt)>GMX_REAL_MIN);
  edt  = od->edt;
  edt1 = od->edt1;
  S    = od->S;
  Dinsl= od->Dinsl;
  Dins = od->Dins;
  Dtav = od->Dtav;
  T    = od->TMP;
  rhs  = od->tmp;
  nref = od->nref;
  mref = od->mref;
  xref = od->xref;
  xtmp = od->xtmp;
  
  od->exp_min_t_tau *= edt;

  if (mcr)
    invn = 1.0/mcr->nnodes;
  else
    invn = 1.0;

  j=0;
  for(i=0; i<md->nr; i++)
    if (md->cORF[i] == 0) {
      copy_rvec(x[i],xtmp[j]);
      for(d=0; d<DIM; d++)
	com[d] += mref[j]*xref[j][d];
      j++;
    }
  svmul(od->invmref,com,com);
  for(j=0; j<nref; j++)
    rvec_dec(xtmp[j],com);
  /* Calculate the rotation matrix to rotate x to the reference orientation */
  calc_fit_R(nref,mref,xref,xtmp,R);
  copy_mat(R,od->R);

  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    rvec_sub(x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
    mvmul(R,r_unrot,r);
    r2   = norm2(r);
    invr = invsqrt(r2);
    /* Calculate the prefactor for the D tensor, this includes the factor 3! */
    pfac = ip[type].orires.c*invr*invr*3;
    for(i=0; i<ip[type].orires.pow; i++)
      pfac *= invr;
    Dinsl[d][0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2);
    Dinsl[d][1] = pfac*(2*r[0]*r[1]);
    Dinsl[d][2] = pfac*(2*r[0]*r[2]);
    Dinsl[d][3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2);
    Dinsl[d][4] = pfac*(2*r[1]*r[2]);

    if (mcr)
      for(i=0; i<5; i++)
	Dins[d][i] = Dinsl[d][i]*invn;
    
    d++;
  }
  
  if (mcr)
    gmx_sum(5*od->nr,Dins[0],mcr);
  
  /* Correction factor to correct for the lack of history for short times */
  corrfac = 1.0/(1.0-od->exp_min_t_tau);
  
  /* Calculate the order tensor S for each experiment via optimization */
  for(ex=0; ex<od->nex; ex++)
    for(i=0; i<5; i++) {
      rhs[ex][i] = 0;
      for(j=0; j<=i; j++)
	T[ex][i][j] = 0;
    }
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    if (bTAV)
      for(i=0; i<5; i++)
	Dtav[d][i] = edt*Dtav[d][i] + edt1*Dins[d][i];

    type   = forceatoms[fa];
    ex     = ip[type].orires.ex;
    weight = ip[type].orires.kfac;
    /* Calculate the vector rhs and half the matrix T for the 5 equations */
    for(i=0; i<5; i++) {
      rhs[ex][i] += Dtav[d][i]*ip[type].orires.obs*weight;
      for(j=0; j<=i; j++)
	T[ex][i][j] += Dtav[d][i]*Dtav[d][j]*weight;
    }
    d++;
  }
  /* Now we have all the data we can calculate S */
  for(ex=0; ex<od->nex; ex++) {
    /* Correct corrfac and copy one half of T to the other half */
    for(i=0; i<5; i++) {
      rhs[ex][i]  *= corrfac;
      T[ex][i][i] *= sqr(corrfac);
      for(j=0; j<i; j++) {
	T[ex][i][j] *= sqr(corrfac);
	T[ex][j][i]  = T[ex][i][j];
      }
    }
    m_inv_gen(T[ex],5,T[ex]);
    /* Calculate the orientation tensor S for this experiment */
    S[ex][0][0] = 0;
    S[ex][0][1] = 0;
    S[ex][0][2] = 0;
    S[ex][1][1] = 0;
    S[ex][1][2] = 0;
    for(i=0; i<5; i++) {
      S[ex][0][0] += 1.5*T[ex][0][i]*rhs[ex][i];
      S[ex][0][1] += 1.5*T[ex][1][i]*rhs[ex][i];
      S[ex][0][2] += 1.5*T[ex][2][i]*rhs[ex][i];
      S[ex][1][1] += 1.5*T[ex][3][i]*rhs[ex][i];
      S[ex][1][2] += 1.5*T[ex][4][i]*rhs[ex][i];
    }
    S[ex][1][0] = S[ex][0][1];
    S[ex][2][0] = S[ex][0][2];
    S[ex][2][1] = S[ex][1][2];
    S[ex][2][2] = -S[ex][0][0] - S[ex][1][1];
  }
  
  wsv2 = 0;
  sw   = 0;
  
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    ex = ip[type].orires.ex;

    od->otav[d] = two_thr*
      corrfac*(S[ex][0][0]*Dtav[d][0] + S[ex][0][1]*Dtav[d][1] +
	       S[ex][0][2]*Dtav[d][2] + S[ex][1][1]*Dtav[d][3] +
	       S[ex][1][2]*Dtav[d][4]);
    if (bTAV)
      od->oins[d] = two_thr*(S[ex][0][0]*Dins[d][0] + S[ex][0][1]*Dins[d][1] +
			     S[ex][0][2]*Dins[d][2] + S[ex][1][1]*Dins[d][3] +
			     S[ex][1][2]*Dins[d][4]);
    if (mcr)
      /* When ensemble averaging is used recalculate the local orientation
       * for output to the energy file.
       */
      od->oinsl[d] = two_thr*
	(S[ex][0][0]*Dinsl[d][0] + S[ex][0][1]*Dinsl[d][1] +
	 S[ex][0][2]*Dinsl[d][2] + S[ex][1][1]*Dinsl[d][3] +
	 S[ex][1][2]*Dinsl[d][4]);
    
    dev = od->otav[d] - ip[type].orires.obs;
    
    wsv2 += ip[type].orires.kfac*sqr(dev);
    sw   += ip[type].orires.kfac;
    
    d++;
  }
  od->rmsdev = sqrt(wsv2/sw);
  
  /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
  for(ex=0; ex<od->nex; ex++) {
    tmmul(R,S[ex],TMP);
    mmul(TMP,R,S[ex]);
  }

  return od->rmsdev;
  
  /* Approx. 120*nfa/3 flops */
}
Esempio n. 8
0
ffdotpows *subharm_ffdot_plane(int numharm, int harmnum,
                               double fullrlo, double fullrhi,
                               subharminfo * shi, accelobs * obs)
{
   int ii, lobin, hibin, numdata, nice_numdata, nrs, fftlen, binoffset;
   static int numrs_full = 0, numzs_full = 0;
   float powargr, powargi;
   double drlo, drhi, harm_fract;
   ffdotpows *ffdot;
   fcomplex *data, **result;
   presto_datainf datainf;

   if (numrs_full == 0) {
      if (numharm == 1 && harmnum == 1) {
         numrs_full = ACCEL_USELEN;
         numzs_full = shi->numkern;
      } else {
         printf("You must call subharm_ffdot_plane() with numharm=1 and\n");
         printf("harnum=1 before you use other values!  Exiting.\n\n");
         exit(7);
      }
   }
   ffdot = (ffdotpows *) malloc(sizeof(ffdotpows));

   /* Calculate and get the required amplitudes */

   harm_fract = (double) harmnum / (double) numharm;
   drlo = calc_required_r(harm_fract, fullrlo);
   drhi = calc_required_r(harm_fract, fullrhi);
   ffdot->rlo = (int) floor(drlo);
   ffdot->zlo = calc_required_z(harm_fract, obs->zlo);

   /* Initialize the lookup indices */
   if (numharm > 1) {
      double rr, subr;
      for (ii = 0; ii < numrs_full; ii++) {
         rr = fullrlo + ii * ACCEL_DR;
         subr = calc_required_r(harm_fract, rr);
         shi->rinds[ii] = index_from_r(subr, ffdot->rlo);
      }
   }
   ffdot->rinds = shi->rinds;
   ffdot->numrs = (int) ((ceil(drhi) - floor(drlo))
                         * ACCEL_RDR + DBLCORRECT) + 1;
   if (numharm == 1 && harmnum == 1) {
      ffdot->numrs = ACCEL_USELEN;
   } else {
      if (ffdot->numrs % ACCEL_RDR) {
         ffdot->numrs = (ffdot->numrs / ACCEL_RDR + 1) * ACCEL_RDR;
      }
   }
   ffdot->numzs = shi->numkern;
   binoffset = shi->kern[0].kern_half_width;
   fftlen = shi->kern[0].fftlen;
   lobin = ffdot->rlo - binoffset;
   hibin = (int) ceil(drhi) + binoffset;
   numdata = hibin - lobin + 1;
   nice_numdata = next2_to_n(numdata);  // for FFTs
   data = get_fourier_amplitudes(lobin, nice_numdata, obs);
   if (!obs->mmap_file && !obs->dat_input)
       printf("This is newly malloc'd!\n");

   // Normalize the Fourier amplitudes

   if (obs->nph > 0.0) {
       //  Use freq 0 normalization if requested (i.e. photons)
       double norm = 1.0 / sqrt(obs->nph);
       for (ii = 0; ii < numdata; ii++) {
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
   } else if (obs->norm_type == 0) {
       //  old-style block median normalization
       float *powers;
       double norm;

       powers = gen_fvect(numdata);
       for (ii = 0; ii < numdata; ii++)
           powers[ii] = POWER(data[ii].r, data[ii].i);
       norm = 1.0 / sqrt(median(powers, numdata)/log(2.0));
       free(powers);
       for (ii = 0; ii < numdata; ii++) {
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
   } else {
       //  new-style running double-tophat local-power normalization
       float *powers, *loc_powers;

       powers = gen_fvect(nice_numdata);
       for (ii = 0; ii < nice_numdata; ii++) {
           powers[ii] = POWER(data[ii].r, data[ii].i);
       }
       loc_powers = corr_loc_pow(powers, nice_numdata);
       for (ii = 0; ii < numdata; ii++) {
           float norm = invsqrt(loc_powers[ii]);
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
       free(powers);
       free(loc_powers);
   }

   /* Perform the correlations */

   result = gen_cmatrix(ffdot->numzs, ffdot->numrs);
   datainf = RAW;
   for (ii = 0; ii < ffdot->numzs; ii++) {
      nrs = corr_complex(data, numdata, datainf,
                         shi->kern[ii].data, fftlen, FFT,
                         result[ii], ffdot->numrs, binoffset,
                         ACCEL_NUMBETWEEN, binoffset, CORR);
      datainf = SAME;
   }

   // Always free data
   free(data);

   /* Convert the amplitudes to normalized powers */

   ffdot->powers = gen_fmatrix(ffdot->numzs, ffdot->numrs);
   for (ii = 0; ii < (ffdot->numzs * ffdot->numrs); ii++)
      ffdot->powers[0][ii] = POWER(result[0][ii].r, result[0][ii].i);
   free(result[0]);
   free(result);
   return ffdot;
}