コード例 #1
0
ファイル: imd_misc.c プロジェクト: PengfeiJi2htec/QMTIS
void add_positions(void)
{
  int k;
  for (k=0; k<NCELLS; k++) {
    int i;
    cell* p;
    p = CELLPTR(k);
    for (i=0; i<p->n; i++) {
        AV_POS(p,i,X) += ORT(p,i,X) + SHEET(p,i,X);
        AV_POS(p,i,Y) += ORT(p,i,Y) + SHEET(p,i,Y);
#ifndef TWOD
        AV_POS(p,i,Z) += ORT(p,i,Z) + SHEET(p,i,Z);
#endif
        AV_EPOT(p,i)  += POTENG(p,i);
    }
  }

#ifdef NPT
  av_box_x.x += box_x.x;
  av_box_x.y += box_x.y;
  av_box_y.x += box_y.x;
  av_box_y.y += box_y.y;
#ifndef TWOD
  av_box_x.z += box_x.z;  
  av_box_y.z += box_y.z;
  av_box_z.x += box_z.x;
  av_box_z.y += box_z.y;  
  av_box_z.z += box_z.z;  
#endif
#endif
  avpos_cnt++;

}
コード例 #2
0
ファイル: imd_comm_force_2d.c プロジェクト: CBegau/imd
void add_forces( int j, int k, int l, int m )
{
  int i;
  cell *from, *to;

  from = PTR_2D_V(cell_array, j, k, cell_dim);
  to   = PTR_2D_V(cell_array, l, m, cell_dim);

  for (i=0; i<to->n; ++i) {
    KRAFT (to,i,X) += KRAFT (from,i,X);
    KRAFT (to,i,Y) += KRAFT (from,i,Y);
    POTENG(to,i)   += POTENG(from,i);
#ifdef STRESS_TENS
    PRESSTENS(to,i,xx) += PRESSTENS(from,i,xx);
    PRESSTENS(to,i,yy) += PRESSTENS(from,i,yy);
    PRESSTENS(to,i,xy) += PRESSTENS(from,i,xy);
#endif
#ifdef NNBR
    NBANZ(to,i) += NBANZ(from,i);
#endif
  }
}
コード例 #3
0
ファイル: imd_comm_force_2d.c プロジェクト: CBegau/imd
void unpack_forces( msgbuf *b, int j, int k )
{
  int i;
  cell *to;

  to = PTR_2D_V(cell_array, j, k, cell_dim);
  for (i=0; i<to->n; ++i) {
    KRAFT (to,i,X) += b->data[ b->n++ ];
    KRAFT (to,i,Y) += b->data[ b->n++ ];
    POTENG(to,i)   += b->data[ b->n++ ];
#ifdef STRESS_TENS
    PRESSTENS(to,i,xx) += b->data[ b->n++ ];
    PRESSTENS(to,i,yy) += b->data[ b->n++ ];
    PRESSTENS(to,i,xy) += b->data[ b->n++ ];
#endif
#ifdef NNBR
    NBANZ(to,i) += (shortint) b->data[ b->n++ ];
#endif
  }
  if (b->n_max < b->n) error("Buffer overflow in unpack_forces.");
}
コード例 #4
0
ファイル: imd_comm_force_2d.c プロジェクト: CBegau/imd
void pack_forces( msgbuf *b, int j, int k )
{
  int i;
  cell *from;
    
  from = PTR_2D_V(cell_array, j, k, cell_dim);
  for (i=0; i<from->n; ++i) {
    b->data[ b->n++ ] = KRAFT(from,i,X);
    b->data[ b->n++ ] = KRAFT(from,i,Y);
    b->data[ b->n++ ] = POTENG(from,i);
#ifdef STRESS_TENS
    b->data[ b->n++ ] = PRESSTENS(from,i,xx);
    b->data[ b->n++ ] = PRESSTENS(from,i,yy);
    b->data[ b->n++ ] = PRESSTENS(from,i,xy);
#endif
#ifdef NNBR
    b->data[ b->n++ ] = (real) NBANZ(from,i);
#endif
  }
  if (b->n_max < b->n) error("Buffer overflow in pack_forces.");
}
コード例 #5
0
ファイル: imd_forces_fcs.c プロジェクト: CBegau/imd
void clear_forces(void) {
  int k,i;
  tot_pot_energy = 0.0;
  virial = vir_xx = vir_yy = vir_xy = vir_zz = vir_yz = vir_zx = 0.0;
  for (k=0; k<nallcells; k++) {
    cell *p = cell_array + k;
    for (i=0; i<p->n; i++) {
      KRAFT(p,i,X) = 0.0;
      KRAFT(p,i,Y) = 0.0;
      KRAFT(p,i,Z) = 0.0;
#if defined (STRESS_TENS)
      PRESSTENS(p,i,xx) = 0.0;
      PRESSTENS(p,i,yy) = 0.0;
      PRESSTENS(p,i,xy) = 0.0;
      PRESSTENS(p,i,zz) = 0.0;
      PRESSTENS(p,i,yz) = 0.0;
      PRESSTENS(p,i,zx) = 0.0;
#endif
      POTENG(p,i) = 0.0;
    }
  }
}
コード例 #6
0
ファイル: imd_extpot.c プロジェクト: CBegau/imd
void calc_extpot(void)
{
  int k, i, n;
  int isinx,isiny,isinz;
  real tmpvec1[4], tmpvec2[4];

  vektor d,addforce,totaddforce;
  real   dd,cc;
  real   dn,ddn,ee;
  
  vektor force;
  real tmp_virial;
#ifdef P_AXIAL
  vektor tmp_vir_vect;
#endif
      
  real pot_zwi, pot_grad;
  int col, is_short=0;
  

  
  for (k=0; k<ep_n; k++) {
    ep_fext[k] = 0.0;
    ep_xmax[k] = 0.0;
    ep_ymax[k] = 0.0;
    ep_atomsincontact[k]=0;
    ep_xmin[k] = 1.e8;
    ep_ymin[k] = 1.e8;
  }
  
  if(ep_key == 0) {   /* default: original harmonic potential */
    for (k=0; k<NCELLS; ++k) {
      cell *p = CELLPTR(k);
      for (i=0; i<p->n; ++i) {
	for (n=0; n<ep_n; ++n) {
	  
	
	  isinx= ep_dir[n].x;                  
	  isiny= ep_dir[n].y;                  
	  isinz= ep_dir[n].z;                  
	
	  d.x = ep_pos[n].x - ORT(p,i,X); 
	  d.y = ep_pos[n].y - ORT(p,i,Y); 
	  d.z = ep_pos[n].z - ORT(p,i,Z); 
	  dn  = SPROD(d,ep_dir[n]);
	  
	  /* spherical indentor*/
	  if (n<ep_nind) {
	    if (dn > -ep_rcut) {
	      real d2 = SPROD(d,d);
	      real d1 = SQRT(d2);
	      dd = ep_rcut - d1;
	      if (dd > 0.0) {
		real f = ep_a * dd * dd / d1;   /* force on atoms and indentor */
		KRAFT(p,i,X) -= f * d.x; 
		KRAFT(p,i,Y) -= f * d.y; 
		KRAFT(p,i,Z) -= f * d.z;
		ep_fext[n]   += f * ABS(dn); /* normal force on indentor */

		ep_atomsincontact[n]++;

		/* for determination of contact area */
		if(isinz)
		  {				  
		    ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		    ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Y) );    
		    ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		    ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Y) );    
		  }
		else if(isiny)
		  {
		    ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		    ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		    ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		    ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		  }
		else
		  {
		    ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,Y) );    
		    ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		    ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,Y) );    
		    ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		  }
	      }
	    }
	  }          
	  /*  potential wall */
	  else {  
	    if (dn*dn < ep_rcut*ep_rcut) {
	      real d1 = (dn>0) ? dn : -1*dn ;
	      dd = ep_rcut - d1;
	      if (dd > 0.0) {
		ep_atomsincontact[n]++;
		real f = ep_a * dd * dd / d1;   /* force on atoms and indentor */
		KRAFT(p,i,X) += f * ep_dir[n].x;
		KRAFT(p,i,Y) += f * ep_dir[n].y;
		KRAFT(p,i,Z) += f * ep_dir[n].z;
		ep_fext[n]   += f;  /* magnitude of force on wall */
	      }
	    } 
	  }
	}
      }
    }
  }
  else if(ep_key == 1) /* Ju Li's spherical indenter, see PRB 67, 104105 */
    {
 
      totaddforce.x=0.0;
      totaddforce.y=0.0;
      totaddforce.z=0.0;
      
      for (k=0; k<NCELLS; ++k) {
	cell *p = CELLPTR(k);
	for (i=0; i<p->n; ++i) {
	  for (n=0; n<ep_n; ++n) {
	    
	
	    isinx= ep_dir[n].x;                  
	    isiny= ep_dir[n].y;                  
	    isinz= ep_dir[n].z;      
	    
	    if (n<ep_nind) {	    
	      d.x =   ORT(p,i,X)-ep_pos[n].x; 
	      d.y =   ORT(p,i,Y)-ep_pos[n].y; 
	      d.z =   ORT(p,i,Z)-ep_pos[n].z; 
	      dn  = SPROD(d,ep_dir[n]);
	      dd  = SPROD(d,d);
	      
	      if ( dd < ep_rcut*ep_rcut)
		{
		  ep_atomsincontact[n]++;
		  /* for the determination of the contact area */
		  if(isinz)
		    {				  
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Y) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Y) );    
		    }
		  else if(isiny)
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		    }
		  else
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,Y) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,Y) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		  }
		  
		  if(have_extpotfile == 1){
		    PAIR_INT3(pot_zwi, pot_grad, ext_pot, n, ep_nind, dd, is_short);
		    tot_pot_energy += pot_zwi;
		    force.x = -1.0* pot_grad * d.x; 
		    force.y = -1.0* pot_grad * d.y; 
		    force.z = -1.0* pot_grad * d.z; 
		    KRAFT(p,i,X) += force.x;
		    KRAFT(p,i,Y) += force.y;
		    KRAFT(p,i,Z) += force.z;
		      
		    totaddforce.x += force.x;
		    totaddforce.y += force.y;
		    totaddforce.z += force.z;
		    
		    ep_fext[n]   += -pot_grad * ABS(dn); /* normal force on indentor */
		    
#ifdef P_AXIAL
		    tmp_vir_vect.x -= d.x * force.x;
		    tmp_vir_vect.y -= d.y * force.y;
#ifndef TWOD
		    tmp_vir_vect.z -= d.z * force.z;
#endif
#else
		    tmp_virial     -= dd * pot_grad;
#endif

#ifdef STRESS_TENS
		    if (do_press_calc) {
		      PRESSTENS(p,i,xx) -= d.x * force.x;
		      PRESSTENS(p,i,yy) -= d.y * force.y;
		      PRESSTENS(p,i,xy) -= d.x * force.y;
#ifndef TWOD
		      PRESSTENS(p,i,zz) -= d.z * force.z;
		      PRESSTENS(p,i,yz) -= d.y * force.z;
		      PRESSTENS(p,i,zx) -= d.z * force.x;
#endif
		      }
#endif
		    }

		   
	      /* old version of extpot, kept for downwards compatibility */
		  else{
		    ddn= sqrt(dd);
		    cc = (ep_rcut - ddn)/ep_a;
		    if (cc > UPPER_EXP) cc = UPPER_EXP;
		    if (cc < LOWER_EXP) cc = LOWER_EXP;
		    ee = exp(cc - 1.0/cc);
		    
		    tot_pot_energy += ee;
		    POTENG(p,i) += ee;
		    
		    ee = ee / ep_a / ddn * (1.0 + 1.0 /(cc*cc));
                        
		    KRAFT(p,i,X) += ee * d.x; 
		    KRAFT(p,i,Y) += ee * d.y; 
		    KRAFT(p,i,Z) += ee * d.z;
		    
		    totaddforce.x += ee * d.x;
		    totaddforce.y += ee * d.y;
		    totaddforce.z += ee * d.z; 
		    
		    ep_fext[n]   += ee * ABS(dn); /* normal force on indentor */
		  }
		}
	    } 
	  }
	}
      }
      
#ifdef MPI
      tmpvec1[0] =  totaddforce.x ;
      tmpvec1[1] =  totaddforce.y ;
      tmpvec1[2] =  totaddforce.z ;
      //    printf("before totaddforcereduce allreduce\n");fflush(stdout);
      MPI_Allreduce( tmpvec1, tmpvec2, 4, REAL, MPI_SUM, cpugrid);
      // printf("after totaddforce allreduce\n");fflush(stdout);
      totaddforce.x = tmpvec2[0];
      totaddforce.y = tmpvec2[1];
      totaddforce.z = tmpvec2[2];      
#endif
      /* no need for a wall as the total additional impuls is substracted */
      
      totaddforce.x *= 1.0/nactive_vect[0];
      totaddforce.y *= 1.0/nactive_vect[1];
      totaddforce.z *= 1.0/nactive_vect[2];
      
      
      for (k=0; k<NCELLS; ++k) {
	cell *p = CELLPTR(k);
	for (i=0; i<p->n; ++i) {
	  KRAFT(p,i,X) -= totaddforce.x;
	  KRAFT(p,i,Y) -= totaddforce.y;
	  KRAFT(p,i,Z) -= totaddforce.z;
	}
      }
    }
  

  else if(ep_key == 2) 
    /* Ju Li's spherical indenter made flat, see PRB 67, 104105
       with subtraction of total additional impulse
       works only with indentation directions parallel to box vectors*/ 
    {
      //      vektor d,addforce,totaddforce;
      //real   dd,cc;
      //real   dn,ddn,ee;
      
      totaddforce.x=0.0;
      totaddforce.y=0.0;
      totaddforce.z=0.0;
      
      
      for (k=0; k<NCELLS; ++k) {
	cell *p = CELLPTR(k);
	for (i=0; i<p->n; ++i) {
	  for (n=0; n<ep_n; ++n) {

	    isinx= ep_dir[n].x;                  
	    isiny= ep_dir[n].y;                  
	    isinz= ep_dir[n].z;      
	    
	    //  vektor d;
	    // real   dn;
	    d.x =  (ep_dir[n].x==0)  ? 0 : (ORT(p,i,X)-ep_pos[n].x); 
	    d.y =  (ep_dir[n].y==0)  ? 0 : (ORT(p,i,Y)-ep_pos[n].y); 
	    d.z =  (ep_dir[n].z==0)  ? 0 : (ORT(p,i,Z)-ep_pos[n].z); 
	    dn  = SPROD(d,ep_dir[n]);
	    dd  = SPROD(d,d);
		
	    if ( dd < ep_rcut*ep_rcut)
	      {
		/* for the determination of the contact area */
		ep_atomsincontact[n]++;
		if(isinz)
		    {				  
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Y) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Y) );    
		    }
		  else if(isiny)
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		    }
		  else
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,Y) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,Y) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		    }


		  
		if(have_extpotfile == 1){
		  PAIR_INT3(pot_zwi, pot_grad, ext_pot, n, ep_nind, dd, is_short);
		  tot_pot_energy += pot_zwi;
		  force.x = -1.0* pot_grad * d.x; 
		  force.y = -1.0* pot_grad * d.y; 
		  force.z = -1.0* pot_grad * d.z; 
		  KRAFT(p,i,X) += force.x;
		  KRAFT(p,i,Y) += force.y;
		  KRAFT(p,i,Z) += force.z;
		  
		  totaddforce.x += force.x;
		  totaddforce.y += force.y;
		  totaddforce.z += force.z;
		  
		  ep_fext[n]   += -pot_grad * ABS(dn); /* normal force on indentor */
		  
#ifdef P_AXIAL
		  tmp_vir_vect.x -= d.x * force.x;
		  tmp_vir_vect.y -= d.y * force.y;
#ifndef TWOD
		  tmp_vir_vect.z -= d.z * force.z;
#endif
#else
		  tmp_virial     -= dd * pot_grad;
#endif
		  
#ifdef STRESS_TENS
		  if (do_press_calc) {
		    PRESSTENS(p,i,xx) -= d.x * force.x;
		    PRESSTENS(p,i,yy) -= d.y * force.y;
		    PRESSTENS(p,i,xy) -= d.x * force.y;
#ifndef TWOD
		    PRESSTENS(p,i,zz) -= d.z * force.z;
		    PRESSTENS(p,i,yz) -= d.y * force.z;
		    PRESSTENS(p,i,zx) -= d.z * force.x;
#endif
		  }
#endif
		}
		
		   
		/* old version of extpot, kept for downwards compatibility */
		else{
		  ddn= sqrt(dd);
		  cc = (ep_rcut - ddn)/ep_a;
		  if (cc > UPPER_EXP) cc = UPPER_EXP;
		  if (cc < LOWER_EXP) cc = LOWER_EXP;
		  ee = exp(cc - 1.0/cc);
		    
		  tot_pot_energy += ee;
		  POTENG(p,i) += ee;
		  
		  ee = ee / ep_a / ddn * (1.0 + 1.0 /(cc*cc));
		  
		  KRAFT(p,i,X) += ee * d.x; 
		  KRAFT(p,i,Y) += ee * d.y; 
		  KRAFT(p,i,Z) += ee * d.z;
		  
		  totaddforce.x += ee * d.x;
		  totaddforce.y += ee * d.y;
		  totaddforce.z += ee * d.z; 
                    
		  ep_fext[n]   += ee * ABS(dn); /* normal force on indentor */
                    
		}
	      }
	  } 
	      
	}
      }
      
      
#ifdef MPI
      tmpvec1[0] =  totaddforce.x ;
      tmpvec1[1] =  totaddforce.y ;
      tmpvec1[2] =  totaddforce.z ;
      //    printf("before totaddforcereduce allreduce\n");fflush(stdout);
      MPI_Allreduce( tmpvec1, tmpvec2, 4, REAL, MPI_SUM, cpugrid);
      // printf("after totaddforce allreduce\n");fflush(stdout);
      totaddforce.x = tmpvec2[0];
      totaddforce.y = tmpvec2[1];
      totaddforce.z = tmpvec2[2];      
#endif
      /* no need for a wall as the total additional impuls is substracted */
      
      totaddforce.x *= 1.0/nactive_vect[0];
      totaddforce.y *= 1.0/nactive_vect[1];
      totaddforce.z *= 1.0/nactive_vect[2];
      
      
      for (k=0; k<NCELLS; ++k) {
	cell *p = CELLPTR(k);
	for (i=0; i<p->n; ++i) {
	  KRAFT(p,i,X) -= totaddforce.x;
	  KRAFT(p,i,Y) -= totaddforce.y;
	  KRAFT(p,i,Z) -= totaddforce.z;
	}
      }
    }

  else if(ep_key == 3) 
    /* Ju Li's spherical indenter made flat, see PRB 67, 104105
       without subtraction of the total additional impulse
       works only with indentation directions parallel to box vectors*/ 
    {
      //    vektor d,addforce,totaddforce;
      //      real   dd,cc;
      //      real   dn,ddn,ee;
      
      totaddforce.x=0.0;
      totaddforce.y=0.0;
      totaddforce.z=0.0;
      
      
      for (k=0; k<NCELLS; ++k) {
	cell *p = CELLPTR(k);
	for (i=0; i<p->n; ++i) {
	  for (n=0; n<ep_n; ++n) {
	    
	 
	    isinx= ep_dir[n].x;                  
	    isiny= ep_dir[n].y;                  
	    isinz= ep_dir[n].z;      
	    
	    vektor d;
	    real   dn;
	    d.x =  (ep_dir[n].x==0)  ? 0 : (ORT(p,i,X)-ep_pos[n].x) ; 
	    d.y =   (ep_dir[n].y==0)  ? 0 : (ORT(p,i,Y)-ep_pos[n].y); 
	    d.z =   (ep_dir[n].z==0)  ? 0 : (ORT(p,i,Z)-ep_pos[n].z); 
	    dn  = SPROD(d,ep_dir[n]);
	    dd  = SPROD(d,d);
		
	    if ( dd < ep_rcut*ep_rcut)
	      {
		/* for the determination of the contact area */
		ep_atomsincontact[n]++;
		if(isinz)
		    {				  
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Y) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Y) );    
		    }
		  else if(isiny)
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,X) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,X) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		    }
		  else
		    {
		      ep_xmax[n] = MAX(ep_xmax[n], ORT(p,i,Y) );    
		      ep_ymax[n] = MAX(ep_ymax[n], ORT(p,i,Z) );    
		      ep_xmin[n] = MIN(ep_xmin[n], ORT(p,i,Y) );    
		      ep_ymin[n] = MIN(ep_ymin[n], ORT(p,i,Z) );    
		    }

		  
		if(have_extpotfile == 1){
		  PAIR_INT3(pot_zwi, pot_grad, ext_pot, n, ep_nind, dd, is_short);
		  tot_pot_energy += pot_zwi;
		  force.x = - pot_grad * d.x; 
		  force.y = - pot_grad * d.y; 
		  force.z = - pot_grad * d.z; 
		  KRAFT(p,i,X) += force.x;
		  KRAFT(p,i,Y) += force.y;
		  KRAFT(p,i,Z) += force.z;
		  
		  totaddforce.x += force.x;
		  totaddforce.y += force.y;
		  totaddforce.z += force.z;
		  
		  ep_fext[n]   += -pot_grad * ABS(dn); /* normal force on indentor */
		  
#ifdef P_AXIAL
		  tmp_vir_vect.x -= d.x * force.x;
		  tmp_vir_vect.y -= d.y * force.y;
#ifndef TWOD
		  tmp_vir_vect.z -= d.z * force.z;
#endif
#else
		  tmp_virial     -= dd * pot_grad;
#endif
		  
#ifdef STRESS_TENS
		  if (do_press_calc) {
		    PRESSTENS(p,i,xx) -= d.x * force.x;
		    PRESSTENS(p,i,yy) -= d.y * force.y;
		    PRESSTENS(p,i,xy) -= d.x * force.y;
#ifndef TWOD
		    PRESSTENS(p,i,zz) -= d.z * force.z;
		    PRESSTENS(p,i,yz) -= d.y * force.z;
		    PRESSTENS(p,i,zx) -= d.z * force.x;
#endif
		  }
#endif
		}
		
		   
		/* old version of extpot, kept for downwards compatibility */
		else{
		ddn= sqrt(dd);
		cc = (ep_rcut - ddn)/ep_a;
		if (cc > UPPER_EXP) cc = UPPER_EXP;
		if (cc < LOWER_EXP) cc = LOWER_EXP;
		ee = exp(cc - 1.0/cc);
		    
		tot_pot_energy += ee;
		POTENG(p,i) += ee;
		    
		ee = ee / ep_a / ddn * (1.0 + 1.0 /(cc*cc));
		
		KRAFT(p,i,X) += ee * d.x; 
		KRAFT(p,i,Y) += ee * d.y; 
		KRAFT(p,i,Z) += ee * d.z;
		ep_fext[n]   += ee * ABS(dn); /* normal force on indentor */
		}
	      }	    
	  } 
	}
      }     
    }
  
  else
    {
      error("Error: external potential ep_key not defined.\n");
    }
#ifdef P_AXIAL
vir_xx += tmp_vir_vect.x;
vir_yy += tmp_vir_vect.y;
virial += tmp_vir_vect.x;
virial += tmp_vir_vect.y;
#ifndef TWOD
vir_zz += tmp_vir_vect.z;
virial += tmp_vir_vect.z;
#endif
#else
virial += tmp_virial;
#endif 
}
コード例 #7
0
ファイル: imd_main_mpi_3d.c プロジェクト: CBegau/imd
void calc_forces(int steps)
{
  int n, k;
  real tmpvec1[8], tmpvec2[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

  /* fill the buffer cells */
  if ((steps == steps_min) || (0 == steps % BUFSTEP)) setup_buffers();
  send_cells(copy_cell,pack_cell,unpack_cell);

  /* clear global accumulation variables */
  tot_pot_energy = 0.0;
  virial = 0.0;
  vir_xx = 0.0;
  vir_yy = 0.0;
  vir_zz = 0.0;
  vir_yz = 0.0;
  vir_zx = 0.0;
  vir_xy = 0.0;
  nfc++;

  /* clear per atom accumulation variables */
#ifdef _OPENMP
#pragma omp parallel for
#endif
  for (k=0; k<nallcells; ++k) {
    int  i;
    cell *p;
    p = cell_array + k;
    for (i=0; i<p->n; ++i) {
      KRAFT(p,i,X) = 0.0;
      KRAFT(p,i,Y) = 0.0;
      KRAFT(p,i,Z) = 0.0;
#ifdef UNIAX
      DREH_MOMENT(p,i,X) = 0.0;
      DREH_MOMENT(p,i,Y) = 0.0;
      DREH_MOMENT(p,i,Z) = 0.0;
#endif
#if defined(STRESS_TENS)
      PRESSTENS(p,i,xx) = 0.0;
      PRESSTENS(p,i,yy) = 0.0;
      PRESSTENS(p,i,zz) = 0.0;
      PRESSTENS(p,i,yz) = 0.0;
      PRESSTENS(p,i,zx) = 0.0;
      PRESSTENS(p,i,xy) = 0.0;
#endif      
#ifndef MONOLJ
      POTENG(p,i) = 0.0;
#endif
#ifdef NNBR
      NBANZ(p,i) = 0;
#endif
#ifdef CNA
      if (cna)
	MARK(p,i) = 0;
#endif
#ifdef COVALENT
      NEIGH(p,i)->n = 0;
#endif
#ifdef EAM2
      EAM_RHO(p,i) = 0.0; /* zero host electron density at atom site */
#ifdef EEAM
      EAM_P(p,i) = 0.0; /* zero host electron density at atom site */
#endif
#endif
    }
  }

#ifdef RIGID
  /* clear total forces */
  if ( nsuperatoms>0 ) 
    for(k=0; k<nsuperatoms; k++) {
      superforce[k].x = 0.0;
      superforce[k].y = 0.0;
      superforce[k].z = 0.0;
    }
#endif

  /* What follows is the standard one-cpu force 
     loop acting on our local data cells */

  /* compute forces for all pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:tot_pot_energy,virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
    for (k=0; k<npairs[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n] + k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      do_forces(cell_array + P->np, cell_array + P->nq, pbc,
                &tot_pot_energy, &virial, &vir_xx, &vir_yy, &vir_zz,
                                          &vir_yz, &vir_zx, &vir_xy);
    }
  }

#ifdef COVALENT
  /* complete neighbor tables for remaining pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime)
#endif
    for (k=npairs[n]; k<npairs2[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n] + k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      do_neightab(cell_array + P->np, cell_array + P->nq, pbc);
    }
  }

#ifndef CNA
  /* second force loop for covalent systems */
/* does not work correctly - different threads may write to same variables 
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:tot_pot_energy,virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
*/
  for (k=0; k<ncells; ++k) {
    do_forces2(cell_array + CELLS(k),
               &tot_pot_energy, &virial, &vir_xx, &vir_yy, &vir_zz,
                                         &vir_yz, &vir_zx, &vir_xy);
  }
#endif
#endif /* COVALENT */

#ifndef AR
  /* If we don't use actio=reactio accross the cpus, we have do do
     the force loop also on the other half of the neighbours for the 
     cells on the surface of the CPU */

  /* compute forces for remaining pairs of cells */
  for (n=0; n<nlists; ++n) {
/* does not work correctly - different threads may write to same variables 
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime)
#endif
*/
    for (k=npairs[n]; k<npairs2[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n] + k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      /* potential energy and virial are already complete;          */
      /* to avoid double counting, we update only the dummy tmpvec2 */
      do_forces(cell_array + P->np, cell_array + P->nq, pbc,
                tmpvec2, tmpvec2+1, tmpvec2+2, tmpvec2+3, tmpvec2+4,
                                    tmpvec2+5, tmpvec2+6, tmpvec2+7);
    }
  }
#endif  /* not AR */

#ifdef EAM2

#ifdef AR
  /* collect host electron density */
  send_forces(add_rho,pack_rho,unpack_add_rho);
#endif
  /* compute embedding energy and its derivative */
  do_embedding_energy();
  /* distribute derivative of embedding energy */
  send_cells(copy_dF,pack_dF,unpack_dF);

  /* second EAM2 loop over all cells pairs */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
    for (k=0; k<npairs[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n]+k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      do_forces_eam2(cell_array + P->np, cell_array + P->nq, pbc,
        &virial, &vir_xx, &vir_yy, &vir_zz, &vir_yz, &vir_zx, &vir_xy);
    }
  }

#ifndef AR
  /* If we don't use actio=reactio accross the cpus, we have do do
     the force loop also on the other half of the neighbours for the 
     cells on the surface of the CPU */

  /* compute forces for remaining pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime)
#endif
    for (k=npairs[n]; k<npairs2[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n]+k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      /* potential energy and virial are already complete;          */
      /* to avoid double counting, we update only the dummy tmpvec2 */
      do_forces_eam2(cell_array + P->np, cell_array + P->nq, pbc,
                     tmpvec2, tmpvec2+1, tmpvec2+2, tmpvec2+3, tmpvec2+4,
                                         tmpvec2+5, tmpvec2+6, tmpvec2+7);
    }
  }
#endif /* not AR */

#endif /* EAM2 */

  /* sum up results of different CPUs */
  tmpvec1[0] = tot_pot_energy;
  tmpvec1[1] = virial;
  tmpvec1[2] = vir_xx;
  tmpvec1[3] = vir_yy;
  tmpvec1[4] = vir_zz;
  tmpvec1[5] = vir_yz;
  tmpvec1[6] = vir_zx;
  tmpvec1[7] = vir_xy;

  MPI_Allreduce( tmpvec1, tmpvec2, 8, REAL, MPI_SUM, cpugrid); 

  tot_pot_energy = tmpvec2[0];
  virial         = tmpvec2[1];
  vir_xx         = tmpvec2[2];
  vir_yy         = tmpvec2[3];
  vir_zz         = tmpvec2[4];
  vir_yz         = tmpvec2[5];
  vir_zx         = tmpvec2[6];
  vir_xy         = tmpvec2[7];

#ifdef AR
  send_forces(add_forces,pack_forces,unpack_forces);
#endif

}
コード例 #8
0
ファイル: mdmain.C プロジェクト: elau/graphite_pep
EXTERN_ENV
#include <stdio.h>
#include "carbon_user.h"

#include "parameters.h"
#include "mdvar.h"
#include "water.h"
#include "wwpot.h"
#include "cnst.h"
#include "mddata.h"
#include "fileio.h"
#include "split.h"
#include "global.h"

/************************************************************************/

/* routine that implements the time-steps. Called by main routine and calls others */
double MDMAIN(long NSTEP, long NPRINT, long NSAVE, long NORD1, long ProcID)
{
    double XTT;
    long i;
    double POTA,POTR,POTRF;
    double XVIR,AVGT,TEN;
    double TTMV = 0.0, TKIN = 0.0, TVIR = 0.0;

    /*.......ESTIMATE ACCELERATION FROM F/M */
    INTRAF(&gl->VIR,ProcID);

    BARRIER(gl->start, NumProcs);

    INTERF(ACC,&gl->VIR,ProcID);

    BARRIER(gl->start, NumProcs);

    /* MOLECULAR DYNAMICS LOOP OVER ALL TIME-STEPS */

    for (i=1;i <= NSTEP; i++) {
        TTMV=TTMV+1.00;

        /* reset simulator stats at beginning of second time-step */

        /* POSSIBLE ENHANCEMENT:  Here's where one start measurements to avoid
           cold-start effects.  Recommended to do this at the beginning of the
           second timestep; i.e. if (i == 2).
           */
        if (i == 2)
        {
           // Reset Models
           CarbonEnableModels();
        }
        

        /* initialize various shared sums */
        if (ProcID == 0) {
            long dir;
            if (i >= 2) {
                CLOCK(gl->trackstart);
            }
            gl->VIR = 0.0;
            gl->POTA = 0.0;
            gl->POTR = 0.0;
            gl->POTRF = 0.0;
            for (dir = XDIR; dir <= ZDIR; dir++)
                gl->SUM[dir] = 0.0;
        }

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intrastart);
        }

        BARRIER(gl->start, NumProcs);
        PREDIC(TLC,NORD1,ProcID);
        INTRAF(&gl->VIR,ProcID);
        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intraend);
            gl->intratime += gl->intraend - gl->intrastart;
        }


        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->interstart);
        }

        INTERF(FORCES,&gl->VIR,ProcID);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->interend);
            gl->intertime += gl->interend - gl->interstart;
        }

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intrastart);
        }

        CORREC(PCC,NORD1,ProcID);

        BNDRY(ProcID);

        KINETI(gl->SUM,HMAS,OMAS,ProcID);

        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intraend);
            gl->intratime += gl->intraend - gl->intrastart;
        }

        TKIN=TKIN+gl->SUM[0]+gl->SUM[1]+gl->SUM[2];
        TVIR=TVIR-gl->VIR;

        /*  check if potential energy is to be computed, and if
            printing and/or saving is to be done, this time step.
            Note that potential energy is computed once every NPRINT
            time-steps */

        if (((i % NPRINT) == 0) || ( (NSAVE > 0) && ((i % NSAVE) == 0))){

            if ((ProcID == 0) && (i >= 2)) {
                CLOCK(gl->interstart);
            }

            /*  call potential energy computing routine */
            POTENG(&gl->POTA,&gl->POTR,&gl->POTRF,ProcID);
            BARRIER(gl->start, NumProcs);

            if ((ProcID == 0) && (i >= 2)) {
                CLOCK(gl->interend);
                gl->intertime += gl->interend - gl->interstart;
            }

            POTA=gl->POTA*FPOT;
            POTR=gl->POTR*FPOT;
            POTRF=gl->POTRF*FPOT;

            /* compute some values to print */
            XVIR=TVIR*FPOT*0.50/TTMV;
            AVGT=TKIN*FKIN*TEMP*2.00/(3.00*TTMV);
            TEN=(gl->SUM[0]+gl->SUM[1]+gl->SUM[2])*FKIN;
            XTT=POTA+POTR+POTRF+TEN;

            if ((i % NPRINT) == 0 && ProcID == 0) {
                fprintf(six,"     %5ld %14.5lf %12.5lf %12.5lf  \
                %12.5lf\n %16.3lf %16.5lf %16.5lf\n",
                        i,TEN,POTA,POTR,POTRF,XTT,AVGT,XVIR);
            }
        }

        /* wait for everyone to finish time-step */
        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->trackend);
            gl->tracktime += gl->trackend - gl->trackstart;
        }
    } /* for i */
コード例 #9
0
ファイル: mdmain.C プロジェクト: CoryXie/Graphite
EXTERN_ENV

#include <stdio.h>

#include "parameters.h"
#include "mdvar.h"
#include "water.h"
#include "wwpot.h"
#include "cnst.h"
#include "mddata.h"
#include "fileio.h"
#include "split.h"
#include "global.h"

/************************************************************************/

double MDMAIN(long NSTEP, long NPRINT, long NSAVE, long NORD1, long ProcID)
{
    double TVIR = 0.0;
    double TTMV = 0.0;
    double TKIN = 0.0;
    double XTT;
    long i,j,k;
    double POTA,POTR,POTRF;
    double XVIR,AVGT,TEN;
    struct list_of_boxes *new_box, *curr_box;

    for (i=start_end[ProcID]->box[XDIR][FIRST]; i<=start_end[ProcID]->box[XDIR][LAST]; i++) {
        for (j=start_end[ProcID]->box[YDIR][FIRST]; j<=start_end[ProcID]->box[YDIR][LAST]; j++) {
            for (k=start_end[ProcID]->box[ZDIR][FIRST]; k<=start_end[ProcID]->box[ZDIR][LAST]; k++) {
                new_box = (box_list *) G_MALLOC(sizeof(box_list));
                new_box->coord[XDIR] = i;
                new_box->coord[YDIR] = j;
                new_box->coord[ZDIR] = k;
                new_box->next_box = NULL;
                curr_box = my_boxes[ProcID];
                if (curr_box == NULL)
                    my_boxes[ProcID] = new_box;
                else {
                    while (curr_box->next_box != NULL)
                        curr_box = curr_box->next_box;
                    curr_box->next_box = new_box;
                } /* else */
            }
        }
    }

    /* calculate initial value for acceleration */

    INTRAF(&gl->VIR,ProcID);

    BARRIER(gl->start,NumProcs);

    INTERF(ACC,&gl->VIR,ProcID);

    BARRIER(gl->start, NumProcs);

    /* MOLECULAR DYNAMICS LOOP */

    for (i=1;i <= NSTEP; i++) {
        TTMV=TTMV+1.00;

        /* POSSIBLE ENHANCEMENT:  Here's where one start measurements to avoid
           cold-start effects.  Recommended to do this at the beginning of the
           second timestep; i.e. if (i == 2).
           */

        /* initialize various shared sums */
        if (ProcID == 0) {
            long dir;
            if (i >= 2) {
                CLOCK(gl->trackstart);
            }
            gl->VIR = 0.0;
            gl->POTA = 0.0;
            gl->POTR = 0.0;
            gl->POTRF = 0.0;
            for (dir = XDIR; dir <= ZDIR; dir++)
                gl->SUM[dir] = 0.0;
        }

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intrastart);
        }

        BARRIER(gl->start, NumProcs);

        PREDIC(TLC,NORD1,ProcID);
        INTRAF(&gl->VIR,ProcID);

        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intraend);
            gl->intratime += gl->intraend - gl->intrastart;
        }

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->interstart);
        }

        INTERF(FORCES,&gl->VIR,ProcID);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->interend);
            gl->intertime += gl->interend - gl->interstart;
        }

        CORREC(PCC,NORD1,ProcID);

        BNDRY(ProcID);

        KINETI(gl->SUM,HMAS,OMAS,ProcID);

        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->intraend);
            gl->intratime += gl->intraend - gl->interend;
        }

        TKIN=TKIN+gl->SUM[0]+gl->SUM[1]+gl->SUM[2];
        TVIR=TVIR-gl->VIR;

        /* CHECK if  PRINTING AND/OR SAVING IS TO BE DONE */

        if ( ((i % NPRINT) == 0) || ((NSAVE > 0) && ((i % NSAVE) == 0))) {

            /* if so, call poteng to compute potential energy.  Note
               that we are attributing all the time in poteng to intermolecular
               computation although some of it is intramolecular (see poteng.C) */

            if ((ProcID == 0) && (i >= 2)) {
                CLOCK(gl->interstart);
            }

            POTENG(&gl->POTA,&gl->POTR,&gl->POTRF,ProcID);

            BARRIER(gl->start, NumProcs);

            if ((ProcID == 0) && (i >= 2)) {
                CLOCK(gl->interend);
                gl->intertime += gl->interend - gl->interstart;
            }

            POTA=gl->POTA*FPOT;
            POTR=gl->POTR*FPOT;
            POTRF=gl->POTRF*FPOT;
            XVIR=TVIR*FPOT*0.50/TTMV;
            AVGT=TKIN*FKIN*TEMP*2.00/(3.00*TTMV);
            TEN=(gl->SUM[0]+gl->SUM[1]+gl->SUM[2])*FKIN;
            XTT=POTA+POTR+POTRF+TEN;

            /* if it is time to print output as well ... */
            if ((i % NPRINT) == 0 && ProcID == 0) {
                LOCK(gl->IOLock);
                fprintf(six,"     %5ld %14.5lf %12.5lf %12.5lf %12.5lf \n"
                        ,i,TEN,POTA,POTR,POTRF);
                fprintf(six," %16.3lf %16.5lf %16.5lf\n",XTT,AVGT,XVIR);
                fflush(six);
                UNLOCK(gl->IOLock);
            }

        }

        BARRIER(gl->start, NumProcs);

        if ((ProcID == 0) && (i >= 2)) {
            CLOCK(gl->trackend);
            gl->tracktime += gl->trackend - gl->trackstart;
        }

    } /* for i */
   
    return(XTT);

} /* mdmain.c */
コード例 #10
0
ファイル: imd_main_mpi_2d.c プロジェクト: CBegau/imd
void calc_forces(int steps)
{
  int  n, k;
  real tmpvec1[5], tmpvec2[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

  /* fill the buffer cells */
  if ((steps == steps_min) || (0 == steps % BUFSTEP)) setup_buffers();
  send_cells(copy_cell,pack_cell,unpack_cell);

  /* clear global accumulation variables */
  tot_pot_energy = 0.0;
  virial = 0.0;
  vir_xx = 0.0;
  vir_yy = 0.0;
  vir_xy = 0.0;
  nfc++;

  /* clear per atom accumulation variables */
#ifdef _OPENMP
#pragma omp parallel for
#endif
  for (k=0; k<nallcells; ++k) {
    int i;
    cell *p;
    p = cell_array + k;
    for (i=0; i<p->n; ++i) {
      KRAFT(p,i,X) = 0.0;
      KRAFT(p,i,Y) = 0.0;
      POTENG(p,i)  = 0.0;
#ifdef NNBR
      NBANZ(p,i) = 0;
#endif
#if defined(STRESS_TENS)
      PRESSTENS(p,i,xx) = 0.0;
      PRESSTENS(p,i,yy) = 0.0;
      PRESSTENS(p,i,xy) = 0.0;
#endif      
    }
  }

#ifdef RIGID
  /* clear total forces */
  if ( nsuperatoms>0 ) 
    for(k=0; k<nsuperatoms; k++) {
      superforce[k].x = 0.0;
      superforce[k].y = 0.0;
    }
#endif

  /* What follows is the standard one-cpu force 
     loop acting on our local data cells */

  /* compute forces for all pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:tot_pot_energy,virial,vir_xx,vir_yy,vir_xy)
#endif
    for (k=0; k<npairs[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n] + k;
      pbc.x = P->ipbc[0] * box_x.x + P->ipbc[1] * box_y.x;
      pbc.y = P->ipbc[0] * box_x.y + P->ipbc[1] * box_y.y;
      do_forces(cell_array + P->np, cell_array + P->nq, pbc,
                &tot_pot_energy, &virial, &vir_xx, &vir_yy, &vir_zz,
                                          &vir_yz, &vir_zx, &vir_xy);
    }
  }

#ifndef AR

  /* If we don't use actio=reactio accross the cpus, we have do do
     the force loop also on the other half of the neighbours for the 
     cells on the surface of the CPU */

  /* compute forces for remaining pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime)
#endif
    for (k=npairs[n]; k<npairs2[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n] + k;
      pbc.x = P->ipbc[0] * box_x.x + P->ipbc[1] * box_y.x;
      pbc.y = P->ipbc[0] * box_x.y + P->ipbc[1] * box_y.y;
      /* potential energy and virial are already complete;          */
      /* to avoid double counting, we update only the dummy tmpvec2 */
      do_forces(cell_array + P->np, cell_array + P->nq, pbc,
                tmpvec2, tmpvec2+1, tmpvec2+2, tmpvec2+3, tmpvec2+4,
                                    tmpvec2+5, tmpvec2+6, tmpvec2+7);
    }
  }

#endif /* AR */

  /* sum up results of different CPUs */
  tmpvec1[0] = tot_pot_energy;
  tmpvec1[1] = virial;
  tmpvec1[2] = vir_xx;
  tmpvec1[3] = vir_yy;
  tmpvec1[4] = vir_xy;

  MPI_Allreduce( tmpvec1, tmpvec2, 5, REAL, MPI_SUM, cpugrid); 

  tot_pot_energy = tmpvec2[0];
  virial         = tmpvec2[1];
  vir_xx         = tmpvec2[2];
  vir_yy         = tmpvec2[3];
  vir_xy         = tmpvec2[4];

#ifdef AR
  send_forces(add_forces,pack_forces,unpack_forces);
#endif

}
コード例 #11
0
ファイル: imd_forces_fcs.c プロジェクト: CBegau/imd
void unpack_fcs(void) {

  fcs_float vir[9] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
  FCSResult result;
  real pot1, pot2, e, c, sum=0.0, fac=0.5;
  int n, m, k, i;

  /* extract output and distribute it to cell array */
  n=0; m=0; pot1=0.0;
  for (k=0; k<NCELLS; ++k) {
    cell *p = CELLPTR(k);
    for (i=0; i<p->n; ++i) { 
      c = CHARGE(p,i) * coul_eng;
      KRAFT(p,i,X) += field[n++] * c; 
      KRAFT(p,i,Y) += field[n++] * c; 
      KRAFT(p,i,Z) += field[n++] * c;
      e = pot[m++] * c * fac;
      POTENG(p,i)  += e;
      pot1         += e;
    }
  }

  /* unpack virial */
  result = fcs_get_virial(handle, vir);
  ASSERT_FCS(result);
#ifdef P_AXIAL
  vir_xx += vir[0];
  vir_yy += vir[4];
  vir_zz += vir[8];
#else
  virial += vir[0] + vir[4] + vir[8];
#endif
#ifdef STRESS_TENS
  if (do_press_calc) {
    /* distribute virial tensor evenly on all atoms */
    sym_tensor pp;
    pp.xx = vir[0] / natoms;
    pp.yy = vir[4] / natoms;
    pp.zz = vir[8] / natoms;
    pp.yz = (vir[5]+vir[7]) / (2*natoms);
    pp.zx = (vir[2]+vir[6]) / (2*natoms);
    pp.xy = (vir[1]+vir[3]) / (2*natoms);
    for (k=0; k<NCELLS; ++k) {
      cell *p = CELLPTR(k);
      for (i=0; i<p->n; ++i) { 
        PRESSTENS(p,i,xx) += pp.xx;
        PRESSTENS(p,i,yy) += pp.yy;
        PRESSTENS(p,i,zz) += pp.zz;
        PRESSTENS(p,i,yz) += pp.yz;
        PRESSTENS(p,i,zx) += pp.zx;
        PRESSTENS(p,i,xy) += pp.xy;
      }
    }
  }
#endif

  /* sum up potential energy */
#ifdef MPI
  MPI_Allreduce( &pot1, &pot2, 1, MPI_DOUBLE, MPI_SUM, cpugrid);
  tot_pot_energy += pot2;
#else
  tot_pot_energy += pot1;
#endif
}
コード例 #12
0
ファイル: imd_forces_uniax.c プロジェクト: CBegau/imd
void do_forces(cell *p, cell *q, vektor pbc, real *Epot, real *Virial, 
               real *Vir_xx, real *Vir_yy, real *Vir_zz,
               real *Vir_yz, real *Vir_zx, real *Vir_xy)
{
  int i, j ;
  int jstart ;

  real tmp_virial ;
  vektor tmp_vir_vect ; 
  vektor tmp_r12 ;

  vektor r12 ;
  vektor e1 ;
  vektor e2 ;
  real rsqr ;

  real pot12 ;
  vektor force12 ;
  vektor torque12 ;
  vektor torque21 ;

  /* actual pair virial and virial components */
  
  tmp_virial     = 0.0;
  tmp_vir_vect.x = 0.0;
  tmp_vir_vect.y = 0.0;
  tmp_vir_vect.z = 0.0;
    
  /* For each atom in first cell */
  for (i = 0;i < p->n; ++i) {
    /* For each atom in neighbouring cell */
    /* Some compilers don't find the expressions that are invariant 
       to the inner loop. I'll have to define my own temp variables. */

    tmp_r12.x = ORT(p,i,X) - pbc.x;
    tmp_r12.y = ORT(p,i,Y) - pbc.y;
    tmp_r12.z = ORT(p,i,Z) - pbc.z;

    e1.x = ACHSE(p,i,X);
    e1.y = ACHSE(p,i,Y);
    e1.z = ACHSE(p,i,Z);

#ifdef TWOD
    jstart = (((p==q) && (pbc.x==0) && (pbc.y==0))               ? i+1 : 0);
#else
    jstart = (((p==q) && (pbc.x==0) && (pbc.y==0) && (pbc.z==0)) ? i+1 : 0);
#endif
    
    for (j = jstart; j < q->n; ++j) {
      
      /* Calculate distance */

      r12.x = tmp_r12.x - ORT(q,j,X);
      r12.y = tmp_r12.y - ORT(q,j,Y);
      r12.z = tmp_r12.z - ORT(q,j,Z);

      rsqr = SPROD(r12,r12);

      e2.x = ACHSE(q,j,X);
      e2.y = ACHSE(q,j,Y);
      e2.z = ACHSE(q,j,Z);

#ifndef NODBG_DIST
      if (0==rsqr) 
	{ 
	  char msgbuf[256];
	  sprintf(msgbuf,"Distance is zero: i=%d, j=%d\n",i,j);
	  error(msgbuf);
	}
#else
      if (0==rsqr) error("Distance is zero.");
#endif

      if (rsqr <= uniax_r2_cut) {

	/* calculate interactions, if distance smaller than cutoff radius */ 

	gay_berne( r12, e1, e2, rsqr, uniax_sig, uniax_eps, &pot12,
		   &force12, &torque12, &torque21) ;
	
        /* accumulate forces */

	KRAFT(p,i,X) += force12.x;
	KRAFT(p,i,Y) += force12.y;
	KRAFT(p,i,Z) += force12.z;

	KRAFT(q,j,X) -= force12.x;
	KRAFT(q,j,Y) -= force12.y;
	KRAFT(q,j,Z) -= force12.z;

        /* accumulate torques */

	DREH_MOMENT(p,i,X) += torque12.x;
	DREH_MOMENT(p,i,Y) += torque12.y;
	DREH_MOMENT(p,i,Z) += torque12.z;

	DREH_MOMENT(q,j,X) += torque21.x;
	DREH_MOMENT(q,j,Y) += torque21.y;
	DREH_MOMENT(q,j,Z) += torque21.z;

        *Epot       += pot12;
        pot12       *= 0.5;   /* avoid double counting */
	POTENG(p,i) += pot12;
	POTENG(q,j) += pot12;

        tmp_vir_vect.x += r12.x * force12.x ;
        tmp_vir_vect.y += r12.y * force12.y ;
        tmp_vir_vect.z += r12.z * force12.z ;
	tmp_virial += r12.x * force12.x
	  + r12.y * force12.y + r12.z * force12.z ;

      }; /* if */

    }; /* for j */

  }; /* for i */

  *Vir_xx += tmp_vir_vect.x;
  *Vir_yy += tmp_vir_vect.y;
  *Vir_zz += tmp_vir_vect.z;
  *Virial += tmp_virial ;

} /* do_forces_uniax */
コード例 #13
0
ファイル: imd_main_risc_3d.c プロジェクト: CBegau/imd
void calc_forces(int steps)
{
  int n, k;

  /* clear global accumulation variables */
  tot_pot_energy = 0.0;
  virial = 0.0;
  vir_xx = 0.0;
  vir_yy = 0.0;
  vir_zz = 0.0;
  vir_yz = 0.0;
  vir_zx = 0.0;
  vir_xy = 0.0;
  nfc++;

  /* clear per atom accumulation variables */
#ifdef _OPENMP
#pragma omp parallel for
#endif
  for (k=0; k<ncells; ++k) {
    int  i;
    cell *p;
    p = cell_array + k;
    for (i=0; i<p->n; ++i) {
      KRAFT(p,i,X) = 0.0;
      KRAFT(p,i,Y) = 0.0;
      KRAFT(p,i,Z) = 0.0;
#ifdef UNIAX
      DREH_MOMENT(p,i,X) = 0.0;
      DREH_MOMENT(p,i,Y) = 0.0;
      DREH_MOMENT(p,i,Z) = 0.0;
#endif
#if defined(STRESS_TENS)
      PRESSTENS(p,i,xx) = 0.0;
      PRESSTENS(p,i,yy) = 0.0;
      PRESSTENS(p,i,zz) = 0.0;
      PRESSTENS(p,i,yz) = 0.0;
      PRESSTENS(p,i,zx) = 0.0;
      PRESSTENS(p,i,xy) = 0.0;
#endif     
#ifndef MONOLJ
      POTENG(p,i) = 0.0;
#endif
#ifdef CNA
      if (cna)
	MARK(p,i) = 0;
#endif
#ifdef NNBR
      NBANZ(p,i) = 0;
#endif
#ifdef COVALENT
      NEIGH(p,i)->n = 0;
#endif
#ifdef EAM2
      EAM_RHO(p,i) = 0.0; /* zero host electron density at atom site */
#ifdef EEAM
      EAM_P(p,i) = 0.0; /* zero host electron density at atom site */
#endif
#endif
    }
  }
#ifdef RIGID
  /* clear total forces */
  if ( nsuperatoms>0 ) 
    for(k=0; k<nsuperatoms; k++) {
      superforce[k].x = 0.0;
      superforce[k].y = 0.0;
      superforce[k].z = 0.0;
    }
#endif

#ifdef EWALD
  if (steps==0) {
    ewald_time.total = 0.0;
    imd_start_timer( &ewald_time );
  }
#endif

  /* compute forces for all pairs of cells */
  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:tot_pot_energy,virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
    for (k=0; k<npairs[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n]+k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      do_forces(cell_array + P->np, cell_array + P->nq, pbc,
                &tot_pot_energy, &virial, &vir_xx, &vir_yy, &vir_zz,
                                          &vir_yz, &vir_zx, &vir_xy);
    }
  }

#ifdef EWALD
  if (steps==0) {
    imd_stop_timer( &ewald_time );
  }
#endif

#ifdef EAM2
  /* compute embedding energy and its derivative */
  do_embedding_energy();

  for (n=0; n<nlists; ++n) {
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
    for (k=0; k<npairs[n]; ++k) {
      vektor pbc;
      pair *P;
      P = pairs[n]+k;
      pbc.x = P->ipbc[0]*box_x.x + P->ipbc[1]*box_y.x + P->ipbc[2]*box_z.x;
      pbc.y = P->ipbc[0]*box_x.y + P->ipbc[1]*box_y.y + P->ipbc[2]*box_z.y;
      pbc.z = P->ipbc[0]*box_x.z + P->ipbc[1]*box_y.z + P->ipbc[2]*box_z.z;
      do_forces_eam2(cell_array + P->np, cell_array + P->nq, pbc,
        &virial, &vir_xx, &vir_yy, &vir_zz, &vir_yz, &vir_zx, &vir_xy);
    }
  }
#endif

#if defined(COVALENT) && !defined(CNA)
/* does not work correctly - different threads may write to same variables 
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) \
  reduction(+:tot_pot_energy,virial,vir_xx,vir_yy,vir_zz,vir_yz,vir_zx,vir_xy)
#endif
*/
  for (k=0; k<ncells; ++k) {
    do_forces2(cell_array+k, &tot_pot_energy, &virial, 
               &vir_xx, &vir_yy, &vir_zz, &vir_yz, &vir_zx, &vir_xy);
  }
#endif

#ifdef EWALD 
  do_forces_ewald(steps);
#endif 

}