Ejemplo n.º 1
0
Archivo: imd_qc.c Proyecto: CBegau/imd
void adjust()
{
  int k;

  for (k=0; k<ncells; ++k) {

    cell *p;
    int  i,typ;
    real x,y,z;

    p = cell_array + CELLS(k);

    for (i=0; i<p->n; ++i) {
	
	x = ORT(p,i,X)-0.1;
	y = ORT(p,i,Y)-0.1;
	z = ORT(p,i,Z)-0.1;
	typ = VSORTE(p,i);
	
	/* fix the type of the first atom */
	if (FABS(x+2.*gmin.x) < 0.0001 && FABS(y+2.*gmin.y) < 0.0001 && 
	    FABS(z+2.*gmin.z) < 0.0001) 
        {
           typ=0;
           SORTE (p,i) = typ;
           VSORTE(p,i) = typ;
        }
        num_sort[typ]++;
    }
  }
}
Ejemplo n.º 2
0
void init_extpot(void)
{
  long tmpvec1[3], tmpvec2[3];
  int i,k,sort;
  nactive_vect[0]=0;
  nactive_vect[1]=0;
  nactive_vect[2]=0;
  if (0==myid)
    {
      printf( "EXTPOT: choosen potential ep_key = %d\n", ep_key);
      printf( "EXTPOT: number of indenters = %d\n", ep_n);
      printf( "EXTPOT: number of walls = %d\n", ep_n-ep_nind);
      printf( "EXTPOT: external potential constant = %f\n",ep_a );
      printf( "EXTPOT: cutoff radius = %f\n", ep_rcut );
      for (i=0; i<ep_n; i++)
        {
	  printf("EXTPOT: ep_pos #%d   %.10g %.10g %.10g \n",
		 i, ep_pos[i].x, ep_pos[i].y, ep_pos[i].z);
	  printf("EXTPOT: ep_vel #%d   %.10g %.10g %.10g \n",
		 i, ep_vel[i].x, ep_vel[i].y, ep_vel[i].z);
	  printf("EXTPOT: ep_dir #%d   %.10g %.10g %.10g \n",
		 i, ep_dir[i].x, ep_dir[i].y, ep_dir[i].z);
        }
    }
  /* needed if the indenter impulse should be balanced */
  /* might not work with 2D, epitax, clone, superatom  */
  if(ep_key==1 || ep_key==2  ){
    for (k=0; k<NCELLS; ++k) {
      cell *p = CELLPTR(k);
      for (i=0; i<p->n; ++i) {
	sort = VSORTE(p,i);
	nactive_vect[0] += (restrictions + sort)->x;
	nactive_vect[1] += (restrictions + sort)->y;
	nactive_vect[2] += (restrictions + sort)->z;
      }
    }
#ifdef MPI
    tmpvec1[0] =  nactive_vect[0] ;
    tmpvec1[1] =  nactive_vect[1] ;
    tmpvec1[2] =  nactive_vect[2] ;
    MPI_Allreduce( tmpvec1, tmpvec2, 3, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
    nactive_vect[0] = tmpvec2[0];
    nactive_vect[1] = tmpvec2[1];
    nactive_vect[2] = tmpvec2[2];
#endif
    if (0==myid)
      {
	if (nactive_vect[0] == 0 ||  nactive_vect[1] == 0 || nactive_vect[2] == 0)
	  error ("ep_key=1 requires atoms free to move in all directions\n");
	printf("EXTPOT: active degrees of freedom: x %ld y %ld z %ld\n",nactive_vect[0],nactive_vect[1],nactive_vect[2]);
      }
#ifdef RELAX
    printf( "EXTPOT: max number of relaxation steps = %d\n", ep_max_int);
    printf( "EXTPOT: ekin_threshold = %f\n", glok_ekin_threshold);
    printf( "EXTPOT: fnorm_threshold = %f\n", fnorm_threshold);
#endif
        
      
  }
}
Ejemplo n.º 3
0
void maxwell(real temp)
{ 
   int         k;
   vektor      tot_impuls;
   int         nactive_x, nactive_y, nactive_z;
   static long dummy = 0;
   int slice;
#ifdef DAMP
   real tmp1,tmp2,tmp3,f,maxax,maxax2;
#endif
#ifdef LASER
   real depth;
#endif

#ifdef UNIAX
   real xisq;
   real xi0;
   real xi1;
   real xi2;
   real dot;
   real norm;
   real osq;
#endif
   real   TEMP;
   real   scale, xx, tmp;
   int    num, nhalf, typ;

   TEMP = temp;
   tot_impuls.x = 0.0;   nactive_x = 0;
   tot_impuls.y = 0.0;   nactive_y = 0;
#ifndef TWOD
   tot_impuls.z = 0.0;   nactive_z = 0;
#endif

   /* set temperature */
   for (k=0; k<NCELLS; ++k) {

      int i;
      cell *p;
      vektor *rest;

      p = CELLPTR(k);

      for (i=0; i<p->n; ++i) {
#ifdef LASER
	 depth =   laser_dir.x * ORT(p,i,X)
		 + laser_dir.y * ORT(p,i,Y)
#ifndef TWOD
		 + laser_dir.z * ORT(p,i,Z)
#endif
	 ;
	 depth -= laser_offset;
         if (depth < 0) {
	   depth=0; /* we don't want to exceed laser_delta_temp */
         }
	 
	 TEMP =  laser_delta_temp * exp(-laser_mu * depth);
         TEMP += temperature; /* add base temperature of sample */

#endif /* LASER */

#ifdef DAMP
            /* Calculate stadium function f */
         maxax = MAX(MAX(stadium.x,stadium.y),stadium.z);
         maxax2 = MAX(MAX(stadium2.x,stadium2.y),stadium2.z);

         tmp1 = (stadium2.x == 0) ? 0 : SQR((ORT(p,i,X)-center.x)/(2.0*stadium2.x));
         tmp2 = (stadium2.y == 0) ? 0 : SQR((ORT(p,i,Y)-center.y)/(2.0*stadium2.y));
         tmp3 = (stadium2.z == 0) ? 0 : SQR((ORT(p,i,Z)-center.z)/(2.0*stadium2.z));

         f    = (tmp1+tmp2+tmp3-SQR(maxax/(2.0*maxax2)))/\
             (.25- SQR(maxax/(2.0*maxax2)));

         if (f<= 0.0)
             f = 0.0;
         else if (f>1.0)
             f = 1.0;

      /* we smooth the stadium function: to get a real bath tub !
        fully damped atoms have temp=0, temperature gradient determined
          by bath tub */
         if (f !=0)
             TEMP = damptemp * (1.0 - 0.5 * (1 + sin(-M_PI/2.0 + M_PI*f)));
         else TEMP= temp;

#endif

#ifdef FTG
	  /* calc slice and set TEMP  */
	 tmp = ORT(p,i,X) / box_x.x;
	 slice = (int) nslices * tmp;
	 if (slice<0)        slice = 0;
	 if (slice>=nslices) slice = nslices -1;;
	 
	 TEMP=  Tleft + (Tright-Tleft)*(slice-nslices_Left+1) /
	   (real) (nslices-nslices_Left-nslices_Right+1);
    
	 if (slice>=nslices-nslices_Right) TEMP = Tright;
	 if (slice<nslices_Left)           TEMP=  Tleft;
#endif
         
	 tmp  = sqrt(TEMP * MASSE(p,i));
         rest = restrictions + VSORTE(p,i);
#ifndef RIGID
         IMPULS(p,i,X) = imd_gaussian(tmp) * rest->x;
         IMPULS(p,i,Y) = imd_gaussian(tmp) * rest->y;
#ifndef TWOD
         IMPULS(p,i,Z) = imd_gaussian(tmp) * rest->z;
#endif
#else
	 /* superatoms get velocity zero */
	 if (superatom[VSORTE(p,i)]>-1) {
	   IMPULS(p,i,X) = 0.0;
	   IMPULS(p,i,Y) = 0.0;
#ifndef TWOD
	   IMPULS(p,i,Z) = 0.0;
#endif
	 }
#endif
         nactive_x += (int) rest->x;
         nactive_y += (int) rest->y;
#ifndef TWOD
         nactive_z += (int) rest->z;
#endif
         tot_impuls.x += IMPULS(p,i,X);
         tot_impuls.y += IMPULS(p,i,Y);
#ifndef TWOD
         tot_impuls.z += IMPULS(p,i,Z);
#endif

#ifdef UNIAX

         /* angular velocities for uniaxial molecules */

         /* choose a random vector in space */

         do {
           xi1 = 2.0 * drand48() - 1.0 ;
           xi2 = 2.0 * drand48() - 1.0 ;
           xisq = xi1 * xi1 + xi2 * xi2 ;
         } while ( xisq >= 1.0 );

         xi0 = sqrt( 1.0 - xisq ) ;

         DREH_IMPULS(p,i,X) = 2.0 * xi1 * xi0 ;
         DREH_IMPULS(p,i,Y) = 2.0 * xi2 * xi0 ;
         DREH_IMPULS(p,i,Z) = 1.0 - 2.0 * xisq ;

        /* constrain the vector to be perpendicular to the molecule */

        dot = SPRODN(DREH_IMPULS,p,i,ACHSE,p,i);

        DREH_IMPULS(p,i,X) -= dot * ACHSE(p,i,X) ; 
        DREH_IMPULS(p,i,Y) -= dot * ACHSE(p,i,Y) ; 
        DREH_IMPULS(p,i,Z) -= dot * ACHSE(p,i,Z) ; 

        /* renormalize vector */	   

        osq = SPRODN(DREH_IMPULS,p,i,DREH_IMPULS,p,i);
        norm = SQRT( osq );

        DREH_IMPULS(p,i,X) /= norm ;
        DREH_IMPULS(p,i,Y) /= norm ;
        DREH_IMPULS(p,i,Z) /= norm ;

        /* choose the magnitude of the angular momentum */

        osq = - 2.0 * uniax_inert * TEMP * log( drand48() ) ;
        norm = sqrt( osq );

        DREH_IMPULS(p,i,X) *= norm ;
        DREH_IMPULS(p,i,Y) *= norm ;
        DREH_IMPULS(p,i,Z) *= norm ;

#endif /* UNIAX */

#ifdef SHOCK
	/* plate against bulk */
	 if (shock_mode == 1) {
	   if ( ORT(p,i,X) < shock_strip ) 
	       IMPULS(p,i,X) += shock_speed * MASSE(p,i);
	 }
	 /* two halves against one another */
	 if (shock_mode == 2) {
	   if ( ORT(p,i,X) < box_x.x*0.5 ) 
	     IMPULS(p,i,X) += shock_speed * MASSE(p,i);
	   else
	     IMPULS(p,i,X) -= shock_speed * MASSE(p,i);
	 }
	 /* bulk against wall */
	 if (shock_mode == 3) IMPULS(p,i,X) += shock_speed * MASSE(p,i);
#endif
      }
   }

#ifdef CLONE

   /* compute the total momentum afresh */
   tot_impuls.x = 0.0;
   tot_impuls.y = 0.0;
#ifndef TWOD
   tot_impuls.z = 0.0;
#endif

   /* set velocities of clones equal */
   for (k=0; k<NCELLS; k++) {

      int i, j;
      cell *p;
      p = CELLPTR(k);

      for (i=0; i<p->n; i+=nclones) {

        tot_impuls.x += nclones * IMPULS(p,i,X);
        tot_impuls.y += nclones * IMPULS(p,i,Y);
#ifndef TWOD
        tot_impuls.z += nclones * IMPULS(p,i,Z);
#endif
	for (j=1; j<nclones; j++) {
          IMPULS(p,i+j,X) = IMPULS(p,i,X);
          IMPULS(p,i+j,Y) = IMPULS(p,i,Y);
#ifndef TWOD
          IMPULS(p,i+j,Z) = IMPULS(p,i,Z);
#endif
        }
      }
   }

#endif /* CLONE */

   tot_impuls.x = nactive_x == 0 ? 0.0 : tot_impuls.x / nactive_x;
   tot_impuls.y = nactive_y == 0 ? 0.0 : tot_impuls.y / nactive_y;
#ifndef TWOD
   tot_impuls.z = nactive_z == 0 ? 0.0 : tot_impuls.z / nactive_z;
#endif

   /* correct center of mass momentum */
   for (k=0; k<NCELLS; ++k) {
      int i;
      cell *p;
      vektor *rest;
      p = CELLPTR(k);
      for (i=0; i<p->n; ++i) {
         rest = restrictions + VSORTE(p,i);
         IMPULS(p,i,X) -= tot_impuls.x * rest->x;
         IMPULS(p,i,Y) -= tot_impuls.y * rest->y;
#ifndef TWOD
         IMPULS(p,i,Z) -= tot_impuls.z * rest->z;
#endif
      }
   }

} 
Ejemplo n.º 4
0
void fix_cells(void)
{
  int i,j,k,l,clone,to_cpu, ii;
  minicell *p, *q;
  ivektor coord, lcoord;
  msgbuf *buf;

#ifdef MPI
  empty_mpi_buffers();
#endif

  /* apply periodic boundary conditions */
  do_boundaries();

  /* for each cell in bulk */
  for (i=cellmin.x; i < cellmax.x; ++i)
    for (j=cellmin.y; j < cellmax.y; ++j)
      for (k=cellmin.z; k < cellmax.z; ++k) {

	p = PTR_3D_V(cell_array, i, j, k, cell_dim);
#ifdef LOADBALANCE
	/* Only check content in real cells */
	if (p->lb_cell_type != LB_REAL_CELL) continue;
#endif
	/* loop over atoms in cell */
	l=0;
	while( l<p->n ) {

          coord  = cell_coord( ORT(p,l,X), ORT(p,l,Y), ORT(p,l,Z) );
	  lcoord = local_cell_coord( coord );

#ifdef LOADBALANCE
  	/* Wrap around pbcs if necessary to get the correct index using the loadbalance scheme*/
   if (cpu_dim.x >= 2 && pbc_dirs.x == 1) {
		if (lcoord.x >= global_cell_dim.x) lcoord.x -= global_cell_dim.x;
		if (lcoord.x < 0) lcoord.x += global_cell_dim.x;
	}
	if (cpu_dim.y >= 2 && pbc_dirs.y == 1) {
		if (lcoord.y >= global_cell_dim.y) lcoord.y -= global_cell_dim.y;
		if (lcoord.y < 0) lcoord.y += global_cell_dim.y;
	}
	if (cpu_dim.z >= 2 && pbc_dirs.z == 1) {
		if (lcoord.z >= global_cell_dim.z) lcoord.z -= global_cell_dim.z;
		if (lcoord.z < 0) lcoord.z += global_cell_dim.z;
	}
#endif

 	  /* see if atom is in wrong cell */
	  if ((lcoord.x == i) && (lcoord.y == j) && (lcoord.z == k)) {
            l++;
          } 
          else {

#ifdef LOADBALANCE
        	  if (lcoord.x< 0 || lcoord.x >= cell_dim.x ||
        			  lcoord.y < 0 || lcoord.y >= cell_dim.y ||
        			  lcoord.z < 0 || lcoord.z >= cell_dim.z ||
        			  (PTR_VV(cell_array,lcoord,cell_dim))->lb_cell_type == LB_EMPTY_CELL) {
        		  error("LB: Illegal cell accessed, Atom jumped multiple CPUs");
        	  }
        	  to_cpu = (PTR_VV(cell_array,lcoord,cell_dim))->lb_cpu_affinity;
#else
            to_cpu = cpu_coord(coord);
#endif
            buf    = NULL;

            /* atom is on my cpu */
	    if (to_cpu==myid) {
               q = PTR_VV(cell_array,lcoord,cell_dim);
               MOVE_ATOM(q, p, l);
#ifdef CLONE
               if (l < p->n-nclones)
                 for (clone=1; clone<nclones; clone++) 
                   MOVE_ATOM(q, p, l+clone);
               else /* we are dealing with the last in the stack */
                 for (clone=1; clone<nclones; clone++) 
                   MOVE_ATOM(q, p, l); 
#endif
            }
#ifdef MPI
#ifdef LOADBALANCE
	    else {
			buf = &lb_send_buf[(PTR_VV(cell_array,lcoord,cell_dim))->lb_neighbor_index];
	    }
#else
            /* west */
            else if ((cpu_dim.x>1) && 
               ((to_cpu==nbwest) || (to_cpu==nbnw)  || (to_cpu==nbws) ||
                (to_cpu==nbuw  ) || (to_cpu==nbunw) || (to_cpu==nbuws)||
                (to_cpu==nbdw  ) || (to_cpu==nbdwn) || (to_cpu==nbdsw))) {
              buf = &send_buf_west;
            }
            
            /* east */
            else if ((cpu_dim.x>1) &&
                ((to_cpu==nbeast) || (to_cpu==nbse)  || (to_cpu==nben) ||
                 (to_cpu==nbue  ) || (to_cpu==nbuse) || (to_cpu==nbuen)||
                 (to_cpu==nbde  ) || (to_cpu==nbdes) || (to_cpu==nbdne))) {
              buf = &send_buf_east;
            }
                   
            /* south  */
            else if ((cpu_dim.y>1) &&
                ((to_cpu==nbsouth) || (to_cpu==nbus)  || (to_cpu==nbds))) {
              buf = &send_buf_south;
            }
                   
            /* north  */
            else if ((cpu_dim.y>1) &&
                ((to_cpu==nbnorth) || (to_cpu==nbun)  || (to_cpu==nbdn))) {
              buf = &send_buf_north;
            }
            
            /* down  */
            else if ((cpu_dim.z>1) && (to_cpu==nbdown)) {
              buf = &send_buf_down;
            }
            
            /* up  */
            else if ((cpu_dim.z>1) && (to_cpu==nbup)) {
              buf = &send_buf_up;
            }
            
            else {
#ifdef SHOCK
              /* remove atom from simulation */
              buf = &dump_buf;
              dump_buf.n = 0;
              natoms  -= nclones;
              nactive -= nclones * DIM;
              num_sort [ SORTE(p,l)] -= nclones;
              num_vsort[VSORTE(p,l)] -= nclones;
              warning("Atom jumped multiple CPUs");
#else
              error("Atom jumped multiple CPUs");
#endif
	    }
#endif /* not LOADBALANCE*/

            if (buf != NULL) {
              copy_one_atom( buf, to_cpu, p, l, 1);
#ifdef CLONE
              if (l < p->n-nclones)
                for (clone=1; clone<nclones; clone++)
                  copy_one_atom( buf, to_cpu, p, l+clone, 1);
              else /* we are dealing with the last in the stack */
                for (clone=1; clone<nclones; clone++)
                  copy_one_atom( buf, to_cpu, p, l, 1);
#endif
            }
#endif /* MPI */
	  }
	}
      }
Ejemplo n.º 5
0
Archivo: imd_qc.c Proyecto: CBegau/imd
void sortin (int ifeld[])
{
  int typ,sign,icell,i,hv,it,to_cpu;
  ivektor cellc;
  real x,y,z,dx,dy,dz,dist;
  cell *p, *q;
  
  x=tx[0]*ifeld[0]+tx[1]*ifeld[1]+tx[2]*ifeld[2]+
    tx[3]*ifeld[3]+tx[4]*ifeld[4]+tx[5]*ifeld[5]+0.1-2.*gmin.x;
  y=ty[0]*ifeld[0]+ty[1]*ifeld[1]+ty[2]*ifeld[2]+
    ty[3]*ifeld[3]+ty[4]*ifeld[4]+ty[5]*ifeld[5]+0.1-2.*gmin.y;
  z=tz[0]*ifeld[0]+tz[1]*ifeld[1]+tz[2]*ifeld[2]+
    tz[3]*ifeld[3]+tz[4]*ifeld[4]+tz[5]*ifeld[5]+0.1-2.*gmin.z;

  if (x < perp[0] && y < perp[1] && z < perp[2] && 
      x > perm[0] && y > perm[1] && z > perm[2]) 
    {   
      cellc = cell_coord(x, y, z);
#ifdef BUFCELLS
      cellc = local_cell_coord(cellc);
#endif
      p = PTR_3D_VV(cell_array,cellc,cell_dim);
      
      hv=1;

      for (i = 0 ; i < p->n; i++) {
	 dx = x - ORT(p,i,X);
	 dy = y - ORT(p,i,Y);
	 dz = z - ORT(p,i,Z);
	 dist = dx*dx+dy*dy+dz*dz;
	
	 if (dist < 0.01) {
	     hv=0;
	     break;
	 }
      }

      if (hv == 1) {

	      natoms++;
              nactive +=3;

	      input->n = 1;
	      ORT(input,0,X)  = x;
	      ORT(input,0,Y)  = y;
	      ORT(input,0,Z)  = z;
	      NUMMER(input,0) = natoms;
	      typ=ifeld[6]-1;

	      if (FABS(x+2.*gmin.x) < 0.0001 && FABS(y+2.*gmin.y) < 0.0001 && 
		  FABS(z+2.*gmin.z) < 0.0001) typ=0;

	      if (typ == 1) typ=0; 
	      if (typ == 2) typ=1;

	      SORTE (input,0) = typ;
	      VSORTE(input,0) = typ;
              MASSE(input,0)  = masses[typ];
              INSERT_ATOM(p, input, 0);
      }
    }
}