Esempio n. 1
0
void adress_update_weights(){
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      if (ifParticleIsVirtual(&p[i])) {
         p[i].p.adress_weight=adress_wf_vector((&p[i])->r.p);
	 //printf("LOCAL %f %f\n", p[i].r.p[0], p[i].p.adress_weight);
      }
    }
  }
  for (c = 0; c < local_cells.n; c++) {
    cell = ghost_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
      if (ifParticleIsVirtual(&p[i])) {
         p[i].p.adress_weight=adress_wf_vector((&p[i])->r.p);
	 //printf("GHOST %f %f\n", p[i].r.p[0], p[i].p.adress_weight);
      }
    }
  }
}
Esempio n. 2
0
void put_mol_force_on_parts(Particle *p_com){
   int i,j,mol_id;
   Particle *p;
   double force[3],M;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
  mol_id=p_com->p.mol_id;
   for (i=0;i<3;i++){
      force[i]=p_com->f.f[i];
      p_com->f.f[i]=0.0;
   }
#ifdef MASS
   M=0;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
          ostringstream msg;
          msg <<"Particle does not exist in put_mol_force_on_parts! id= " << topology[mol_id].part.e[i] << "\n";
          runtimeError(msg);
         return;
      }
      #endif
       if (ifParticleIsVirtual(p)) continue;
      M+=PMASS(*p);
   }
#else
   M=topology[mol_id].part.n-1;
#endif
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
          ostringstream msg;
          msg <<"Particle does not exist in put_mol_force_on_parts! id= " << topology[mol_id].part.e[i] << "\n";
          runtimeError(msg);
         return;
      }
      #endif
      if (!ifParticleIsVirtual(p)) {
         for (j=0;j<3;j++){
            p->f.f[j]+=PMASS(*p)*force[j]/M;
         }
#ifdef VIRTUAL_SITES_DEBUG
         count++;
#endif
      }
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
       ostringstream msg;
       msg <<"There is more than one COM input_mol_force_on_parts! mol_id= " << mol_id << "\n";
       runtimeError(msg);
      return;
   }
#endif
}
void put_mol_force_on_parts(Particle *p_com){
   int i,j,mol_id;
   Particle *p;
   double force[3],M;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
  mol_id=p_com->p.mol_id;
   for (i=0;i<3;i++){
      force[i]=p_com->f.f[i];
      p_com->f.f[i]=0.0;
   }
#ifdef MASS
   M=0;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
         char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
         ERROR_SPRINTF(errtxt,"Particle does not exist in put_mol_force_on_parts! id=%i\n",topology[mol_id].part.e[i]);
         return;
      }
      #endif
       if (ifParticleIsVirtual(p)) continue;
      M+=PMASS(*p);
   }
#else
   M=topology[mol_id].part.n-1;
#endif
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
         char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
         ERROR_SPRINTF(errtxt,"Particle does not exist in put_mol_force_on_parts! id=%i\n",topology[mol_id].part.e[i]);
         return;
      }
      #endif
      if (!ifParticleIsVirtual(p)) {
         for (j=0;j<3;j++){
            p->f.f[j]+=PMASS(*p)*force[j]/M;
         }
#ifdef VIRTUAL_SITES_DEBUG
         count++;
#endif
      }
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
      char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt,"There is more than one COM input_mol_force_on_parts! mol_id=%i\n",mol_id);
      return;
   }
#endif
}
/** Calculate kinetic energies for one particle.
    @param p1 particle for which to calculate energies
*/
inline void add_kinetic_energy(Particle *p1)
{
#ifdef VIRTUAL_SITES
  if (ifParticleIsVirtual(p1)) return;
#endif

  /* kinetic energy */
  energy.data.e[0] += (SQR(p1->m.v[0]) + SQR(p1->m.v[1]) + SQR(p1->m.v[2]))*PMASS(*p1);

#ifdef ROTATION
#ifdef ROTATION_PER_PARTICLE
if (p1->p.rotation)
#endif
{
#ifdef ROTATIONAL_INERTIA
  /* the rotational part is added to the total kinetic energy;
     Here we use the rotational inertia  */

  energy.data.e[0] += (SQR(p1->m.omega[0])*p1->p.rinertia[0] +
               SQR(p1->m.omega[1])*p1->p.rinertia[1] +
               SQR(p1->m.omega[2])*p1->p.rinertia[2])*time_step*time_step;
#else
  /* the rotational part is added to the total kinetic energy;
     at the moment, we assume unit inertia tensor I=(1,1,1)  */
  energy.data.e[0] += (SQR(p1->m.omega[0]) + SQR(p1->m.omega[1]) + SQR(p1->m.omega[2]))*time_step*time_step;
#endif
}
#endif
}
// Calculates center of mass of a particle
int calc_mol_pos_cfg(Particle *p_com,double r_com[3]){
   int i,j,mol_id;
   double M=0;
   Particle *p;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
   for (i=0;i<3;i++){
      r_com[i]=0.0;
   }
   mol_id=p_com->p.mol_id;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=&partCfg[topology[mol_id].part.e[i]];
      if (ifParticleIsVirtual(p)) continue;
      for (j=0;j<3;j++){
            r_com[j] += PMASS(*p)*p->r.p[j];
      }
      M+=PMASS(*p);
#ifdef VIRTUAL_SITES_DEBUG
      count++;
#endif
   }
   for (j=0;j<3;j++){
      r_com[j] /= M;
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
      fprintf(stderr,"There is more than one COM in calc_mol_pos_cfg! mol_id=%i\n",mol_id);
      return 0;
   }
#endif
   return 1;
}
Esempio n. 6
0
/** initialize the forces for a ghost particle */
MDINLINE void init_ghost_force(Particle *part)
{
#ifdef ADRESS
  if (ifParticleIsVirtual(part)) {
    part->p.adress_weight=adress_wf_vector(part->r.p);
  }
#endif
  
  part->f.f[0] = 0;
  part->f.f[1] = 0;
  part->f.f[2] = 0;

#ifdef ROTATION
  {
    double scale;
    /* set torque to zero */
    part->f.torque[0] = 0;
    part->f.torque[1] = 0;
    part->f.torque[2] = 0;

    /* and rescale quaternion, so it is exactly of unit length */	
    scale = sqrt( SQR(part->r.quat[0]) + SQR(part->r.quat[1]) +
		  SQR(part->r.quat[2]) + SQR(part->r.quat[3]));
    part->r.quat[0]/= scale;
    part->r.quat[1]/= scale;
    part->r.quat[2]/= scale;
    part->r.quat[3]/= scale;
  }
#endif
}
Esempio n. 7
0
/* momentum update step of ghmc */
void simple_momentum_update()
{
	
	int i, j, c, np;
  Particle *part;
	double sigmat, sigmar;
	

	sigmat = sqrt(temperature); sigmar = sqrt(temperature);
	for (c = 0; c < local_cells.n; c++) {
    np   = local_cells.cell[c]->n;
    part = local_cells.cell[c]->part;
    for (i = 0; i < np; i++) {
			#ifdef VIRTUAL_SITES
				if (ifParticleIsVirtual(&part[i])) continue;
			#endif
			
			#ifdef MASS
				sigmat = sqrt(temperature / PMASS(part[i]));
			#endif
      for (j = 0; j < 3; j++) {
				part[i].m.v[j] = sigmat*gaussian_random()*time_step;
				#ifdef ROTATION
					#ifdef ROTATIONAL_INERTIA
						sigmar = sqrt(temperature / part[i].p.rinertia[j]);
					#endif
					part[i].m.omega[j] = sigmar*gaussian_random();
				#endif	
			}
    }
	}
	
	//fprintf(stderr,"%d: temp after simple update: %f\n",this_node,calc_local_temp());
	
}
Particle *get_mol_com_particle(Particle *calling_p){
   int mol_id;
   int i;
   Particle *p;

   mol_id=calling_p->p.mol_id;

   if (mol_id < 0) {
     char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
     ERROR_SPRINTF(errtxt,"Particle does not have a mol id! pnr=%i\n",
		   calling_p->p.identity);
     return NULL;
   }
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];

      if (p==NULL){
         char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
         ERROR_SPRINTF(errtxt,"Particle does not exist in put_mol_force_on_parts! id=%i\n",topology[mol_id].part.e[i]);
         return NULL;
      }

      if (ifParticleIsVirtual(p)) {
          return p;
       }
   }

   char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
   ERROR_SPRINTF(errtxt,"No com found in get_mol_com_particleParticle does not exist in put_mol_force_on_parts! pnr=%i\n",calling_p->p.identity);
   return NULL;

   return calling_p;
}
Esempio n. 9
0
Particle *get_mol_com_particle(Particle *calling_p) {
    int mol_id;
    int i;
    Particle *p;

    mol_id=calling_p->p.mol_id;
    for (i=0; i<topology[mol_id].part.n; i++) {
        p=local_particles[topology[mol_id].part.e[i]];
#ifdef VIRTUAL_SITES_DEBUG
        if (p==NULL) {
            char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
            ERROR_SPRINTF(errtxt,"Particle does not exist in put_mol_force_on_parts! id=%i\n",topology[mol_id].part.e[i]);
            return NULL;
        }
#endif
        if (ifParticleIsVirtual(p)) {
            return p;
        }
    }
#ifdef VIRTUAL_SITES_DEBUG
    char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
    ERROR_SPRINTF(errtxt,"No com found in get_mol_com_particleParticle does not exist in put_mol_force_on_parts! pnr=%i\n",calling_p->p.identity);
    return NULL;
#endif
    return calling_p;
}
Esempio n. 10
0
Particle *get_mol_com_particle(Particle *calling_p){
   int mol_id;
   int i;
   Particle *p;

   mol_id=calling_p->p.mol_id;

   if (mol_id < 0) {
     ostringstream msg;
     msg <<"Particle does not have a mol id! pnr= " << calling_p->p.identity << "\n";
     runtimeError(msg);
     return NULL;
   }
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];

      if (p==NULL){
          ostringstream msg;
          msg <<"Particle does not exist in put_mol_force_on_parts! id= " << topology[mol_id].part.e[i] << "\n";
          runtimeError(msg);
         return NULL;
      }

      if (ifParticleIsVirtual(p)) {
          return p;
       }
   }

   ostringstream msg;
   msg <<"No com found in get_mol_com_particleParticle does not exist in put_mol_force_on_parts! pnr= " << calling_p->p.identity << "\n";
   runtimeError(msg);
   return NULL;

   return calling_p;
}
Esempio n. 11
0
/* momentum update step of ghmc with temperature scaling */
void tscale_momentum_update()
{
  
  int i, j, c, np;
  Particle *part;
  
  //fprintf(stderr,"%d: temp before update: %f\n",this_node,calc_local_temp());

  save_last_state();
  
  simple_momentum_update();

  //fprintf(stderr,"%d: temp after simple update: %f\n",this_node,calc_local_temp());
  
  double tempt, tempr;
  calc_kinetic(&tempt, &tempr);
  tempt /= (1.5*n_total_particles);
  tempr /= (1.5*n_total_particles);
  
  double scalet = sqrt(temperature / tempt);
  #ifdef ROTATION    
    double scaler = sqrt(temperature / tempr);
  #endif  
            
  for (c = 0; c < local_cells.n; c++) {
    np   = local_cells.cell[c]->n;
    part = local_cells.cell[c]->part;
    for (i = 0; i < np; i++) {
      for (j = 0; j < 3; j++) {
        part[i].m.v[j] *= scalet;
        #ifdef ROTATION
          part[i].m.omega[j] *= scaler;
        #endif  
      }
    }
  }
  
  //fprintf(stderr,"%d: temp after scale: %f\n",this_node,calc_local_temp());
  
	for (c = 0; c < local_cells.n; c++) {
    np   = local_cells.cell[c]->n;
    part = local_cells.cell[c]->part;
    for (i = 0; i < np; i++) {
			#ifdef VIRTUAL_SITES
				if (ifParticleIsVirtual(&part[i])) continue;
			#endif
			
      for (j = 0; j < 3; j++) {
				part[i].m.v[j] = cosp*(part[i].l.m_ls.v[j])+sinp*(part[i].m.v[j]);
				#ifdef ROTATION
					part[i].m.omega[j] = cosp*(part[i].l.m_ls.omega[j])+sinp*(part[i].m.omega[j]);
				#endif	
			}
    }
	}
	
	//fprintf(stderr,"%d : temp after partial update: %f\n",this_node,calc_local_temp());
	
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
void rescale_forces_propagate_vel()
{
  Cell *cell;
  Particle *p;
  int i, j, np, c;
  double scale;

#ifdef NPT
  if(integ_switch == INTEG_METHOD_NPT_ISO){
    nptiso.p_vel[0] = nptiso.p_vel[1] = nptiso.p_vel[2] = 0.0;}
#endif

  scale = 0.5 * time_step * time_step;
  INTEG_TRACE(fprintf(stderr,"%d: rescale_forces_propagate_vel:\n",this_node));

  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++) {
      check_particle_force(&p[i]);
      /* Rescale forces: f_rescaled = 0.5*dt*dt * f_calculated * (1/mass) */
      p[i].f.f[0] *= scale/PMASS(p[i]);
      p[i].f.f[1] *= scale/PMASS(p[i]);
      p[i].f.f[2] *= scale/PMASS(p[i]);

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n",this_node,p[i].f.f[0],p[i].f.f[1],p[i].f.f[2],p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
#ifdef VIRTUAL_SITES
       // Virtual sites are not propagated during integration
       if (ifParticleIsVirtual(&p[i])) continue; 
#endif
      for(j = 0; j < 3 ; j++) {
#ifdef EXTERNAL_FORCES
	if (!(p[i].l.ext_flag & COORD_FIXED(j))) {
#endif
#ifdef NPT
	  if(integ_switch == INTEG_METHOD_NPT_ISO && ( nptiso.geometry & nptiso.nptgeom_dir[j] )) {
	    nptiso.p_vel[j] += SQR(p[i].m.v[j])*PMASS(p[i]);
	    p[i].m.v[j] += p[i].f.f[j] + friction_therm0_nptiso(p[i].m.v[j])/PMASS(p[i]);
	  }
	  else
#endif
	    /* Propagate velocity: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */
	    { p[i].m.v[j] += p[i].f.f[j]; }
#ifdef EXTERNAL_FORCES
	}
#endif
      }

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_2 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
    }
  }
#ifdef NPT
  finalize_p_inst_npt();
#endif
}
void update_mol_vel_particle(Particle *p){
   int j;
   double v_com[3];
   if (ifParticleIsVirtual(p)) {
      calc_mol_vel(p,v_com);
      for (j=0;j<3;j++){
         p->m.v[j] = v_com[j];
      }
   }
}
void update_mol_pos_particle(Particle *p){
   int j;
   double r_com[3];
   if (ifParticleIsVirtual(p)) {
      calc_mol_pos(p,r_com);
      for (j=0;j<3;j++){
         p->r.p[j] = r_com[j];
      }
   }
}
Esempio n. 16
0
/** propagate angular velocities and quaternions \todo implement for
       fixed_coord_flag */
void propagate_omega_quat()
{
  Particle *p;
  Cell *cell;
  int c,i,j, np;
  double lambda, dt2, dt4, dtdt, dtdt2;

  dt2 = time_step*0.5;
  dt4 = time_step*0.25;
  dtdt = time_step*time_step;
  dtdt2 = dtdt*0.5;

  INTEG_TRACE(fprintf(stderr,"%d: propagate_omega_quat:\n",this_node));

  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++) {
	  double Qd[4], Qdd[4], S[3], Wd[3];
	  
	  #ifdef VIRTUAL_SITES
	   // Virtual sites are not propagated in the integration step
	   if (ifParticleIsVirtual(&p[i]))
	    continue;
	  #endif

	  define_Qdd(&p[i], Qd, Qdd, S, Wd);
	  
	  lambda = 1 - S[0]*dtdt2 - sqrt(1 - dtdt*(S[0] + time_step*(S[1] + dt4*(S[2]-S[0]*S[0]))));

	  for(j=0; j < 3; j++){
	    p[i].m.omega[j]+= dt2*Wd[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]));

	  p[i].r.quat[0]+= time_step*(Qd[0] + dt2*Qdd[0]) - lambda*p[i].r.quat[0];
	  p[i].r.quat[1]+= time_step*(Qd[1] + dt2*Qdd[1]) - lambda*p[i].r.quat[1];
	  p[i].r.quat[2]+= time_step*(Qd[2] + dt2*Qdd[2]) - lambda*p[i].r.quat[2];
	  p[i].r.quat[3]+= time_step*(Qd[3] + dt2*Qdd[3]) - lambda*p[i].r.quat[3];
	  // Update the director
	  convert_quat_to_quatu(p[i].r.quat, p[i].r.quatu);
#ifdef DIPOLES
	  // When dipoles are enabled, update dipole moment
	  convert_quatu_to_dip(p[i].r.quatu, p[i].p.dipm, p[i].r.dip);
#endif
	

      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]));
    }
  }
}
Particle *get_mol_com_particle_from_molid_cfg(int mol_id){
   int i;
   Particle *p;
   for (i=0;i<topology[mol_id].part.n;i++){
       p=&partCfg[topology[mol_id].part.e[i]];
       if (ifParticleIsVirtual(p)){
          return p;
       }
   }
#ifdef VIRTUAL_SITES_DEBUG
   fprintf(stderr,"No com found in get_mol_com_particle_from_molid_cfg ! mol_id=%i\n",mol_id);
#endif
   return NULL;
}
Esempio n. 18
0
void update_mol_pos()
{
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
       if (ifParticleIsVirtual(&p[i]))
        update_mol_pos_particle(&p[i]);
    }
    //only for real particles
  }
}
// Distribute forces that have accumulated on virtual particles to the 
// associated real particles
void distribute_mol_force()
{
  // Iterate over all the particles in the local cells
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      // We only care about virtual particles
      if (ifParticleIsVirtual(&p[i])) {
       update_mol_pos_particle(&p[i]);

       // First obtain the real particle responsible for this virtual particle:
       Particle *p_real = vs_relative_get_real_particle(&p[i]);

       // Get distance vector pointing from real to virtual particle, respecting periodic boundary i
       // conditions
       double d[3];
       get_mi_vector(d,p[i].r.p,p_real->r.p);

       // The rules for transfering forces are:
       // F_realParticle +=F_virtualParticle
       // T_realParticle +=f_realParticle \times (r_virtualParticle-r_realParticle)
       
       // Calculate torque to be added on real particle
       double tmp[3];
       vector_product(d,p[i].f.f,tmp);

       // Add forces and torques
       int j;
//       printf("Particle %d gets torque from %f %f %f of particle %d\n",p_real->p.identity, p[i].f.f[0], p[i].f.f[1],p[i].f.f[2], p[i].p.identity);
       for (j=0;j<3;j++) {
         p_real->f.torque[j]+=tmp[j];
//	 printf("%f ",tmp[j]);
	 p_real->f.f[j]+=p[i].f.f[j];
	 // Clear forces on virtual particle
	 p[i].f.f[j]=0;

       }
      }
    }
  }
}
Esempio n. 20
0
void update_mol_vel()
{
#ifndef VIRTUAL_SITES_NO_VELOCITY
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
       if (ifParticleIsVirtual(&p[i]))
        update_mol_vel_particle(&p[i]);
    }
  }
#endif
}
Esempio n. 21
0
/* but p_com is a real particle */
void calc_mol_pos(Particle *p_com,double r_com[3]){
   int i,j,mol_id;
   double M=0;
   double vec12[3];
   Particle *p;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
   for (i=0;i<3;i++){
      r_com[i]=0.0;
   }
   mol_id=p_com->p.mol_id;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
          ostringstream msg;
          msg <<"Particle does not exist in calc_mol_pos! id= " << topology[mol_id].part.e[i] << "\n";
          runtimeError(msg);
         return;
      }
      #endif
      if (ifParticleIsVirtual(p)) continue;
      get_mi_vector(vec12,p->r.p, p_com->r.p);
      for (j=0;j<3;j++){
          r_com[j] += PMASS(*p)*vec12[j];
      }
      M+=PMASS(*p);
#ifdef VIRTUAL_SITES_DEBUG
      count++;
#endif
   }
   for (j=0;j<3;j++){
      r_com[j] /= M;
      r_com[j] += p_com->r.p[j];
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
       ostringstream msg;
       msg <<"There is more than one COM in calc_mol_pos! mol_id= " << mol_id << "\n";
       runtimeError(msg);
      return;
   }
#endif
}
void distribute_mol_force()
{
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      if (ifParticleIsVirtual(&p[i])) {
         if (sqrlen(p[i].f.f)!=0){
            put_mol_force_on_parts(&p[i]);
         }
      }
    }
  }
}
// Rigid body conribution to scalar pressure and stress tensor
void vs_relative_pressure_and_stress_tensor(double* pressure, double* stress_tensor)
{
  // Division by 3 volume is somewhere else. (pressure.cpp after all presure calculations)


  // Iterate over all the particles in the local cells
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      // We only care about virtual particles
      if (!ifParticleIsVirtual(&p[i]))
        continue;

      update_mol_pos_particle(&p[i]);

      // First obtain the real particle responsible for this virtual particle:
      Particle *p_real = vs_relative_get_real_particle(&p[i]);

      // Get distance vector pointing from real to virtual particle, respecting periodic boundary i
      // conditions
      double d[3];
      get_mi_vector(d,p_real->r.p,p[i].r.p);

      // Stress tensor conribution
      for (int k =0; k<3;k++)
       for (int l =0;l<3;l++)
        stress_tensor[k*3+l] +=p[i].f.f[k] *d[l];
      
      // Pressure = 1/3 trace of stress tensor
      // but the 1/3 is applied somewhere else.
      *pressure +=(p[i].f.f[0] *d[0] +p[i].f.f[1] *d[1] +p[i].f.f[2] *d[2]);

    }
  }
 *pressure/=0.5*time_step*time_step;
 for (i=0;i<9;i++)
  stress_tensor[i]/=0.5*time_step*time_step;

}
Esempio n. 24
0
void calc_kinetic(double *ek_trans , double *ek_rot)
{
	
	int i, c, np;
  Particle *part;
	double et = 0.0, er = 0.0;
		
	for (c = 0; c < local_cells.n; c++) {
    np   = local_cells.cell[c]->n;
		
    part = local_cells.cell[c]->part;
    for (i = 0; i < np; i++) {
			#ifdef VIRTUAL_SITES
				if (ifParticleIsVirtual(&part[i])) continue;
			#endif
			
			/* kinetic energy */
			et += (SQR(part[i].m.v[0]) + SQR(part[i].m.v[1]) + SQR(part[i].m.v[2]))*PMASS(part[i]);

			/* rotational energy */
			#ifdef ROTATION
			#ifdef ROTATIONAL_INERTIA
				er += SQR(part[i].m.omega[0])*part[i].p.rinertia[0] +
								SQR(part[i].m.omega[1])*part[i].p.rinertia[1] +
								SQR(part[i].m.omega[2])*part[i].p.rinertia[2];
			#else
				er += SQR(part[i].m.omega[0]) + SQR(part[i].m.omega[1]) + SQR(part[i].m.omega[2]);
			#endif
			#endif	
    }
	}
	
  MPI_Allreduce(MPI_IN_PLACE, &et, 1, MPI_DOUBLE, MPI_SUM, comm_cart);
  MPI_Allreduce(MPI_IN_PLACE, &er, 1, MPI_DOUBLE, MPI_SUM, comm_cart);
	
	et /= (2.0*time_step*time_step);
	#ifdef ROTATION
		er /= 2.0;
	#endif
		
	*ek_trans=et;
	*ek_rot=er;

}
/* but p_com is a real particle */
void calc_mol_pos(Particle *p_com,double r_com[3]){
   int i,j,mol_id;
   double M=0;
   double vec12[3];
   Particle *p;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
   for (i=0;i<3;i++){
      r_com[i]=0.0;
   }
   mol_id=p_com->p.mol_id;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
         char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
         ERROR_SPRINTF(errtxt,"Particle does not exist in calc_mol_pos! id=%i\n",topology[mol_id].part.e[i]);
         return;
      }
      #endif
      if (ifParticleIsVirtual(p)) continue;
      get_mi_vector(vec12,p->r.p, p_com->r.p);
      for (j=0;j<3;j++){
          r_com[j] += PMASS(*p)*vec12[j];
      }
      M+=PMASS(*p);
#ifdef VIRTUAL_SITES_DEBUG
      count++;
#endif
   }
   for (j=0;j<3;j++){
      r_com[j] /= M;
      r_com[j] += p_com->r.p[j];
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
      char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt,"There is more than one COM in calc_mol_pos! mol_id=%i\n",mol_id);
      return;
   }
#endif
}
void calc_dipole_of_molecule(int mol_id,double dipole[4]){
   int j,k;
   Particle *p,*p_first=NULL;
   double vec12[3];
   dipole[0]=dipole[1]=dipole[2]=dipole[3]=0.0;
   for (j=0;j<topology[mol_id].part.n;j++){
      p=&partCfg[topology[mol_id].part.e[j]];
      if (ifParticleIsVirtual(p)) continue;
      if (p_first==NULL){
         p_first=p;
      }
      else
      {
         get_mi_vector(vec12,p->r.p, p_first->r.p);
         for (k=0;k<3;k++){
            dipole[k] += p->p.q*vec12[k];
         }
      }
      dipole[3]+=p->p.q;
   }
}
double calc_energy_kinetic_mol(int type){
   double E_kin=0;
   int i;
   Particle *p_com;
   for (i=0;i<n_molecules;i++){
      if (topology[i].type == type){
         p_com=get_mol_com_particle_from_molid_cfg(i);
#ifdef VIRTUAL_SITES_DEBUG
         if (p_com==NULL){
            return -(i);
         }
         if (!ifParticleIsVirtual(p_com)){
            return -(i);
         }
#endif
         E_kin+=PMASS(*p_com)*sqrlen(p_com->m.v);
      }
   }
   E_kin*=0.5/time_step/time_step;
   return E_kin;
}
int tclcommand_analyze_parse_and_print_check_mol(Tcl_Interp *interp,int argc, char **argv){
   int j,count=0;
   double dist;
   char buffer[TCL_DOUBLE_SPACE];
   Particle p;
   updatePartCfg(WITHOUT_BONDS);
   for(j=0; j<n_total_particles; j++){
      if (!ifParticleIsVirtual(&partCfg[j])) continue;
      get_particle_data(j,&p);
      //dist=min_distance(partCfg[j].r.p,p.r.p);
      unfold_position(p.r.p,p.l.i);
      dist=distance(partCfg[j].r.p,p.r.p);
      if (dist > 0.01){
         if (count==0) Tcl_AppendResult(interp,"BEGIN Particle Missmatch: \n", (char *)NULL);
         sprintf(buffer,"%i",j);
         Tcl_AppendResult(interp,"Particle ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,partCfg[j].r.p[0] , buffer);
         Tcl_AppendResult(interp," partCfg x ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,partCfg[j].r.p[1] , buffer);
         Tcl_AppendResult(interp," y ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,partCfg[j].r.p[2] , buffer);
         Tcl_AppendResult(interp," z ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,p.r.p[0] , buffer);
         Tcl_AppendResult(interp," my_partCfg x ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,p.r.p[1] , buffer);
         Tcl_AppendResult(interp," y ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp,p.r.p[2] , buffer);
         Tcl_AppendResult(interp," z ",buffer, (char *)NULL);
         Tcl_PrintDouble(interp, dist, buffer);
         Tcl_AppendResult(interp," dist ",buffer,"\n", (char *)NULL);
         count++;
      }
   }
   if (count!=0){
      Tcl_AppendResult(interp,"END Particle Missmatch\n", (char *)NULL);
      return(TCL_ERROR);
   }
   return(TCL_OK);
}
Esempio n. 29
0
void propagate_press_box_pos_and_rescale_npt()
{
#ifdef NPT
  if(integ_switch == INTEG_METHOD_NPT_ISO) {
    Cell *cell;
    Particle *p;
    int i, j, np, c;
    double scal[3]={0.,0.,0.}, L_new=0.0;

    /* finalize derivation of p_inst */
    finalize_p_inst_npt();

    /* adjust \ref nptiso_struct::nptiso.volume; prepare pos- and vel-rescaling */
    if (this_node == 0) {
      nptiso.volume += nptiso.inv_piston*nptiso.p_diff*0.5*time_step;
      scal[2] = SQR(box_l[nptiso.non_const_dim])/pow(nptiso.volume,2.0/nptiso.dimension);
      nptiso.volume += nptiso.inv_piston*nptiso.p_diff*0.5*time_step;
      if (nptiso.volume < 0.0) {
	char *errtxt = runtime_error(128 + 3*TCL_DOUBLE_SPACE);
        ERROR_SPRINTF(errtxt, "{015 your choice of piston=%g, dt=%g, p_diff=%g just caused the volume to become negative, decrease dt} ",
                nptiso.piston,time_step,nptiso.p_diff);
	nptiso.volume = box_l[0]*box_l[1]*box_l[2];
	scal[2] = 1;
      }

      L_new = pow(nptiso.volume,1.0/nptiso.dimension);
      //      printf(stdout,"Lnew, %f: volume, %f: dim, %f: press, %f \n", L_new, nptiso.volume, nptiso.dimension,nptiso.p_inst );
      //    fflush(stdout);

      scal[1] = L_new/box_l[nptiso.non_const_dim];
      scal[0] = 1/scal[1];
    }
    MPI_Bcast(scal,  3, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    /* propagate positions while rescaling positions and velocities */
    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
	for(j=0; j < 3; j++){
#ifdef EXTERNAL_FORCES
	  if (!(p[i].l.ext_flag & COORD_FIXED(j))) {
#endif	    
	    if(nptiso.geometry & nptiso.nptgeom_dir[j]) {
	      p[i].r.p[j]      = scal[1]*(p[i].r.p[j] + scal[2]*p[i].m.v[j]);
	      p[i].l.p_old[j] *= scal[1];
	      p[i].m.v[j]     *= scal[0];
	    } else {
	      p[i].r.p[j] += p[i].m.v[j];
	    }

#ifdef EXTERNAL_FORCES
	  }
#endif
	}
	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 ADDITIONAL_CHECKS
	force_and_velocity_check(&p[i]); 
#endif
      }
    }

    resort_particles = 1; 

    /* Apply new volume to the box-length, communicate it, and account for necessary adjustments to the cell geometry */
    if (this_node == 0) {
      for ( i = 0 ; i < 3 ; i++ ){ 
	if ( nptiso.geometry & nptiso.nptgeom_dir[i] ) {
	  box_l[i] = L_new;
	} else if ( nptiso.cubic_box ) {
	  box_l[i] = L_new;
	}
      }
    }
    MPI_Bcast(box_l, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    on_NpT_boxl_change();
  }
Esempio n. 30
0
/** initialize the forces for a real particle */
MDINLINE void init_local_particle_force(Particle *part)
{
#ifdef ADRESS
  double new_weight;
  if (ifParticleIsVirtual(part)) {
    new_weight = adress_wf_vector(part->r.p);
#ifdef ADRESS_INIT
    double old_weight = part->p.adress_weight;
    
    if(new_weight>0 && old_weight==0){
      double rand_cm_pos[3], rand_cm_vel[3], rand_weight, new_pos, old_pos;
      int it, dim, this_mol_id=part->p.mol_id, rand_mol_id, rand_type;
      int n_ats_this_mol=topology[this_mol_id].part.n, n_ats_rand_mol;
      
      //look for a random explicit particle
      rand_type=-1;
      rand_weight=-1;
      rand_mol_id=-1;
      n_ats_rand_mol=-1;
      
      while(rand_type != part->p.type || rand_weight != 1 || n_ats_rand_mol != n_ats_this_mol){
	rand_mol_id = i_random(n_molecules);
	rand_type   = local_particles[(topology[rand_mol_id].part.e[0])]->p.type;
	rand_weight = local_particles[(topology[rand_mol_id].part.e[0])]->p.adress_weight;
	n_ats_rand_mol = topology[rand_mol_id].part.n;
	
	if(!ifParticleIsVirtual(local_particles[(topology[rand_mol_id].part.e[0])]))
	  fprintf(stderr,"No virtual site found on molecule %d, with %d total molecules.\n",rand_mol_id, n_molecules);
      }
      
      //store CM position and velocity
      for(dim=0;dim<3;dim++){
	rand_cm_pos[dim]=local_particles[(topology[rand_mol_id].part.e[0])]->r.p[dim];
	rand_cm_vel[dim]=local_particles[(topology[rand_mol_id].part.e[0])]->m.v[dim];
      }
      
      //assign new positions and velocities to the atoms
      for(it=0;it<n_ats_this_mol;it++){
	if (!ifParticleIsVirtual(local_particles[topology[rand_mol_id].part.e[it]])) {
	  for(dim=0;dim<3;dim++){
	    old_pos = local_particles[topology[this_mol_id].part.e[it]]->r.p[dim];
	    new_pos = local_particles[topology[rand_mol_id].part.e[it]]->r.p[dim]-rand_cm_pos[dim]+part->r.p[dim];
	    //MAKE SURE THEY ARE IN THE SAME BOX
	    while(new_pos-old_pos>box_l[dim]*0.5)
	      new_pos=new_pos-box_l[dim];
	    while(new_pos-old_pos<-box_l[dim]*0.5)
	      new_pos=new_pos+box_l[dim];
	    
	    local_particles[(topology[this_mol_id].part.e[it])]->r.p[dim] = new_pos;
	    local_particles[(topology[this_mol_id].part.e[it])]->m.v[dim] = local_particles[(topology[rand_mol_id].part.e[it])]->m.v[dim]-rand_cm_vel[dim]+part->m.v[dim];
	  }   
	}
      }
    }
#endif
    part->p.adress_weight=new_weight;
  }
#endif
  if ( thermo_switch & THERMO_LANGEVIN )
    friction_thermo_langevin(part);
  else {
    part->f.f[0] = 0;
    part->f.f[1] = 0;
    part->f.f[2] = 0;
  }

#ifdef EXTERNAL_FORCES   
  if(part->l.ext_flag & PARTICLE_EXT_FORCE) {
    part->f.f[0] += part->l.ext_force[0];
    part->f.f[1] += part->l.ext_force[1];
    part->f.f[2] += part->l.ext_force[2];
  }
#endif
  
#ifdef ROTATION
  {
    double scale;
    /* set torque to zero */
    part->f.torque[0] = 0;
    part->f.torque[1] = 0;
    part->f.torque[2] = 0;
    
    /* and rescale quaternion, so it is exactly of unit length */	
    scale = sqrt( SQR(part->r.quat[0]) + SQR(part->r.quat[1]) +
		  SQR(part->r.quat[2]) + SQR(part->r.quat[3]));
    part->r.quat[0]/= scale;
    part->r.quat[1]/= scale;
    part->r.quat[2]/= scale;
    part->r.quat[3]/= scale;
  }
#endif

#ifdef ADRESS
  /* #ifdef THERMODYNAMIC_FORCE */
  if(ifParticleIsVirtual(part))
    if(part->p.adress_weight > 0 && part->p.adress_weight < 1)
      add_thermodynamic_force(part);
  /* #endif */  
#endif
}