コード例 #1
0
void local_rotate_system(double phi, double theta, double alpha)
{
  // Culculate center of mass
  double com[3] = {0,0,0};
  int N=0; // Num of particles

  int c, np, i;
  Particle *part;
  Cell *cell;

  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    part = cell->part;
    np = cell->n;
        
    for(i = 0; i < np; i++) {
      for (int j=0;j<3;j++){
        com[j]+=part[i].r.p[j];
      }
      N++;
    }
  }
  for (int j=0;j<3;j++) com[j]/=N;

  
  // Rotation axis in carthesian coordinates
  double axis[3];
  axis[0]=sin(theta)*cos(phi);
  axis[1]=sin(theta)*sin(phi);
  axis[2]=cos(theta);

  // Rotate particle coordinates
  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    part = cell->part;
    np = cell->n;
        
    for(i = 0; i < np; i++) {
      // Move the center of mass of the system to the origin
      for (int j=0;j<3;j++){
        part[i].r.p[j]-=com[j];
      }
      // Rotate
      double res[3];
      vec_rotate(axis,alpha,part[i].r.p,res);
      // Write back result and shift back the center of mass
      for (int j=0;j<3;j++){
        part[i].r.p[j]=com[j]+res[j];
      }
      #ifdef ROTATION
        rotate_particle(part+i,axis,alpha);
      #endif
    }
  }


  resort_particles =1;
  announce_resort_particles();

}
コード例 #2
0
ファイル: minimize_energy.cpp プロジェクト: Gexar/espresso
bool steepest_descent_step(void) {
  Cell *cell;
  Particle *p;
  int c, i, j, np;
  double f_max = -std::numeric_limits<double>::max();
  double f;
  /* Verlet list criterion */
  const double skin2 = SQR(0.5*skin);
  double f_max_global;
  double dx[3], dx2;
  const double max_dx2 = SQR(params->max_displacement);

  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
      f = 0.0;
      dx2 = 0.0;
#ifdef VIRTUAL_SITES
      if (ifParticleIsVirtual(&p[i])) continue;
#endif
      for(j=0; j < 3; j++){
#ifdef EXTERNAL_FORCES
        if (!(p[i].p.ext_flag & COORD_FIXED(j)))
#endif
          {
            f += SQR(p[i].f.f[j]);	    	    
	    dx[j] = params->gamma * p[i].f.f[j];	    
	    dx2 += SQR(dx[j]);
	    MINIMIZE_ENERGY_TRACE(printf("part %d dim %d dx %e gamma*f %e\n", i, j, dx[j], params->gamma * p[i].f.f[j]));
	  }
#ifdef EXTERNAL_FORCES
	else {
	  dx[j] = 0.0;	  
	}
#endif
      }

      if(dx2 <= max_dx2) {
	p[i].r.p[0] += dx[0];
	p[i].r.p[1] += dx[1];
	p[i].r.p[2] += dx[2];
      } else {
	const double c = params->max_displacement/std::sqrt(dx2);
	p[i].r.p[0] += c*dx[0];
	p[i].r.p[1] += c*dx[1];
	p[i].r.p[2] += c*dx[2];
      }
      if(distance2(p[i].r.p,p[i].l.p_old) > skin2 ) resort_particles = 1;
      f_max = std::max(f_max, f);
    }
  }
  MINIMIZE_ENERGY_TRACE(printf("f_max %e resort_particles %d\n", f_max, resort_particles));
  announce_resort_particles();
  MPI_Allreduce(&f_max, &f_max_global, 1, MPI_DOUBLE, MPI_MAX, comm_cart);
  return (sqrt(f_max_global) < params->f_max);
}
コード例 #3
0
ファイル: cells.cpp プロジェクト: Ammar-85/espresso
void check_resort_particles()
{
  int i, c, np;
  Cell *cell;
  Particle *p;
  double skin2 = SQR(skin/2.0);

  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
      /* Verlet criterion check */
      if(distance2(p[i].r.p, p[i].l.p_old) > skin2) resort_particles = 1;
    }
  }
  announce_resort_particles();
}
コード例 #4
0
ファイル: integrate_sd.cpp プロジェクト: Haider-BA/espresso
void propagate_pos_sd()
{
  /* Verlet list criterion */
  double skin2 = SQR(0.5 * skin);

  INTEG_TRACE(fprintf(stderr,"%d: propagate_pos:\n",this_node));
  Cell *cell;
  Particle *p;
  int c, i, np;
  //get total number of particles
  int N=sd_get_particle_num();
  // gather all the data for mobility calculation
  real * pos=NULL;
  pos=(real *)Utils::malloc(DIM*N*sizeof(double));
  assert(pos!=NULL);
  real * force=NULL;
  force=(real *)Utils::malloc(DIM*N*sizeof(double));
  assert(force!=NULL);
  real * velocity=NULL;
  velocity=(real *)Utils::malloc(DIM*N*sizeof(real));
  assert(velocity!=NULL);
#ifdef EXTERNAL_FORCES
  const int COORD_ALL=COORD_FIXED(0)&COORD_FIXED(1)&COORD_FIXED(2);
#endif
  int j=0; // total particle counter
  for (c = 0; c < local_cells.n; c++){
    cell = local_cells.cell[c];
    p    = cell->part;
    np   = cell->n;
    for (i = 0; i < np; i++) { // only count nonVirtual Particles
#ifdef EXTERNAL_FORCES
      if (p[i].p.ext_flag & COORD_ALL)
	{
	  fprintf (stderr, "Warning: Fixing particle in StokesDynamics this way with EXTERNAL_FORCES is not possible (and will be ignored). Please try to bind them e.g. harmonicaly.\n");
	}
#endif
#ifdef  VIRTUAL_SITES
      if (!ifParticleIsVirtual(&p[i]))
#endif
      {
#ifdef SD_USE_FLOAT
	for (int d=0;d<3;d++){
	  pos[3*j+d]        = p[i].r.p[d];
	  pos[3*j+d]        -=rint(pos[3*j+d]/box_l[d])*box_l[d];
	  force[3*j+d]      = p[i].f.f[d];
	}
#else
        memmove(&pos[3*j], p[i].r.p, 3*sizeof(double));
        memmove(&force[3*j], p[i].f.f, 3*sizeof(double));
	for (int d=0;d<3;d++){
	  pos[3*j+d]        -=rint(pos[3*j+d]/box_l[d])*box_l[d];
	}
#endif
	j++;
      }
    }
  }
  if (!(thermo_switch & THERMO_SD) && thermo_switch & THERMO_BD){
    propagate_pos_bd(N,pos,force, velocity);
  } else {
    // cuda part
#ifdef CUDA
    //void propagate_pos_sd_cuda(double * box_l_h, int N,double * pos_h, double * force_h, double * velo_h){
#ifdef SD_USE_FLOAT
    real box_size[3];
    for (int d=0;d<3;d++){
      box_size[d]=box_l[d];
    }
#else
    real * box_size = box_l;
#endif
    if (!(thermo_switch & THERMO_SD)){
      temperature*=-1;
    }
  propagate_pos_sd_cuda(box_size,N,pos,force, velocity);
  if (!(thermo_switch & THERMO_SD)){
    temperature*=-1;
  }
#else
  fprintf(stderr, "Warning - CUDA is currently required for SD\n");
  fprintf(stderr, "So i am just sitting here and copying stupidly stuff :'(\n");
#endif
}
  

#ifdef NEMD
  /* change momentum of each particle in top and bottom slab */
  fprintf (stderr, "Warning: NEMD is in SD not supported.\n");
#endif
  j=0;
  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p    = cell->part;
    np   = cell->n;
    for (i = 0; i < np; i++) {
#ifdef VIRTUAL_SITES
      if (ifParticleIsVirtual(&p[i])) continue;
#endif
      // write back of position and velocity data
#ifdef SD_USE_FLOAT
      for (int d=0;d<3;d++){
	p[i].r.p[d] = pos[3*j+d]+box_l[d]*rint(p[i].r.p[d]/box_l[d]);
	p[i].m.v[d] = velocity[3*j+d];
	//p[i].f.f[d] *= (0.5*time_step*time_step)/(*part).p.mass;
      }
#else
      for (int d=0;d<3;d++){
	p[i].r.p[d] = pos[3*j+d]+box_l[d]*rint(p[i].r.p[d]/box_l[d]);
      }
      memmove(p[i].m.v, &velocity[DIM*j], 3*sizeof(double));
#endif
      // somehow this does not effect anything, although it is called ...
      for (int d=0;d<3;d++){
	p[i].f.f[d] *= (0.5*time_step*time_step)/(*p).p.mass;
      }
      for (int d=0;d<DIM;d++){
        assert(!isnan(pos[DIM*i+d]));
      }
      j++;
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_1 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PPOS p = (%.3f,%.3f,%.3f)\n",this_node,p[i].r.p[0],p[i].r.p[1],p[i].r.p[2]));
   

#ifdef ROTATION
      propagate_omega_quat_particle(&p[i]);
#endif

      /* Verlet criterion check */
      if(distance2(p[i].r.p,p[i].l.p_old) > skin2 ) resort_particles = 1;
    }
  }
  free(pos);
  free(force);
  free(velocity);
  announce_resort_particles();
}
コード例 #5
0
bool steepest_descent_step(void) {
  Cell *cell;
  Particle *p;
  int c, i, j, np;
  
  // Maximal force encountered on node
  double f_max = -std::numeric_limits<double>::max();
  // and globally
  double f_max_global;
  
  // Square of force,torque on particle
  double f,t;
  
  // Positional increments
  double dp, dp2, dp2_max = -std::numeric_limits<double>::max();
    
  // Iteration over all local particles
  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
      f = 0.0;
      t = 0.0;
      dp2 = 0.0;
#ifdef EXTERNAL_FORCES
        // Skip, if coordinate is fixed
        if (!(p[i].p.ext_flag & COORD_FIXED(j)))
#endif
      // For all Cartesian coordinates
      for(j=0; j < 3; j++){
#ifdef VIRTUAL_SITES
      // Skip positional increments of virtual particles
      if (!ifParticleIsVirtual(&p[i])) 
#endif
        {
            // Square of force on particle
	    f += SQR(p[i].f.f[j]);	    	    
	    
	    // Positional increment
	    dp = params->gamma * p[i].f.f[j];
	    if(fabs(dp) > params->max_displacement)
	      // Crop to maximum allowed by user
	      dp = sgn<double>(dp)*params->max_displacement;
	    dp2 += SQR(dp);
            
	    // Move particle
	    p[i].r.p[j] += dp;
	    MINIMIZE_ENERGY_TRACE(printf("part %d dim %d dp %e gamma*f %e\n", i, j, dp, params->gamma * p[i].f.f[j]));
          }
	}
#ifdef ROTATION
	// Rotational increment
	double dq[3]; // Vector parallel to torque

        for (int j=0;j<3;j++){
          dq[j]=0;
          // Square of torque
	  t += SQR(p[i].f.torque[j]);	    	    
	    
	  // Rotational increment
	  dq[j] = params->gamma * p[i].f.torque[j];
	    
      }
      // Normalize rotation axis and compute amount of rotation
      double l=normr(dq);
      if (l>0.0)
      {
        for (j=0;j<3;j++)
          dq[j]/=l;
  
        if(fabs(l) > params->max_displacement)
          // Crop to maximum allowed by user
  	l=sgn(l)*params->max_displacement;
        
        
//        printf("dq: %g %g %g, l=%g\n",dq[0],dq[1],dq[2],l);
        // Rotate the particle around axis dq by amount l
        rotate_particle(&(p[i]),dq,l);
      }
#endif

      // Note maximum force/torque encountered
      f_max = std::max(f_max, f);
      f_max = std::max(f_max, t);
      dp2_max = std::max(dp2_max, dp2);
      resort_particles = 1;
    }
  }
  MINIMIZE_ENERGY_TRACE(printf("f_max %e resort_particles %d\n", f_max, resort_particles));
  announce_resort_particles();
  
  // Synchronize maximum force/torque encountered
  MPI_Allreduce(&f_max, &f_max_global, 1, MPI_DOUBLE, MPI_MAX, comm_cart);
  
  // Return true, if the maximum force/torque encountered is below the user limit.
  return (sqrt(f_max_global) < params->f_max);
}