示例#1
0
/**Incorporates mass of each particle*/
double calc_mol_gyr_radius2(Molecule mol)
{
  int i, id;
  double rg=0.0, M=0.0, com[3], diff_vec[3];

  calc_mol_center_of_mass(mol, com);

  for(i=0; i<mol.part.n; i++) {
    id = mol.part.e[i];
    vecsub(partCfg[id].r.p, com, diff_vec);
    rg += sqrlen(diff_vec);
    M += PMASS(partCfg[id]);
  }

  return (rg/M);
}
示例#2
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;

}
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;
}
void angularmomentum(int type, double *com)
{
  int i, j;
  double tmp[3];
  double pre_factor;
  com[0]=com[1]=com[2]=0.;

  updatePartCfg(WITHOUT_BONDS);
  for (j=0; j<n_part; j++) 
  {
    if (type == partCfg[j].p.type) 
    {
      vector_product(partCfg[j].r.p,partCfg[j].m.v,tmp);
      pre_factor=PMASS(partCfg[j]);
      for (i=0; i<3; i++) {
        com[i] += tmp[i]*pre_factor;
      }
    }
  }
  return;
}
示例#5
0
/* This is only done for the trapped molecules to save time */
void calc_local_mol_info (IntList *local_trapped_mols)
{
  int mi, i,j, mol;
  Particle *p;
  int np, c;
  Cell *cell;
  int lm;
  int fixed;

  /* First reset all molecule masses,forces,centers of mass*/
  for ( mi = 0 ; mi < n_molecules ; mi++ ) {
    topology[mi].mass = 0;
    for ( i = 0 ; i < 3 ; i++) {
      topology[mi].f[i] = 0.0;
      topology[mi].com[i] = 0.0;
      topology[mi].v[i] = 0.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++) {
      mol = p[i].p.mol_id;
      if ( mol >= n_molecules ) {
	char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
	ERROR_SPRINTF(errtxt, "{ 094 can't calculate molforces no such molecule as %d }",mol);
	return;
      }

      /* Check to see if this molecule is fixed */
      fixed =0;
      for(j = 0; j < 3; j++) {
#ifdef EXTERNAL_FORCES
	if (topology[mol].trap_flag & COORD_FIXED(j)) fixed = 1;
	if (topology[mol].noforce_flag & COORD_FIXED(j)) fixed = 1;
#endif
      }  
      if (fixed) {
	topology[mol].mass += PMASS(p[i]);
	/* Unfold the particle */
	unfold_position(p[i].r.p,p[i].l.i);
	for ( j = 0 ; j < 3 ; j++ ) {
	  topology[mol].f[j] += p[i].f.f[j];
	  topology[mol].com[j] += p[i].r.p[j]*PMASS(p[i]); 
	  topology[mol].v[j] += p[i].m.v[j]*PMASS(p[i]); 
	}
	/* Fold the particle back */
	fold_position(p[i].r.p,p[i].l.i);

      }
    }
  }

  /* Final normalisation of centers of mass and velocity*/
  for ( lm = 0 ; lm < local_trapped_mols->n; lm++ ) {
    mi = local_trapped_mols->e[lm];
    for ( i = 0 ; i < 3 ; i++) {
      topology[mi].com[i] = topology[mi].com[i]/(double)(topology[mi].mass);
      topology[mi].v[i] = topology[mi].v[i]/(double)(topology[mi].mass);
    }
  }

}
void analyze_rdfchain(double r_min, double r_max, int r_bins, double **_f1, double **_f2, double **_f3) {
  int i, j, ind, c_i, c_j, mon;
  double bin_width, inv_bin_width, factor, r_in, r_out, bin_volume, dist, chain_mass,
    *cm=NULL, *min_d=NULL, *f1=NULL, *f2=NULL, *f3=NULL;
  
  *_f1 = f1 = (double*)Utils::realloc(f1,r_bins*sizeof(double));
  *_f2 = f2 = (double*)Utils::realloc(f2,r_bins*sizeof(double));
  *_f3 = f3 = (double*)Utils::realloc(f3,r_bins*sizeof(double));
  cm = (double*)Utils::realloc(cm,(chain_n_chains*3)*sizeof(double));
  min_d = (double*)Utils::realloc(min_d,(chain_n_chains*chain_n_chains)*sizeof(double));
  for(i=0; i<r_bins; i++) {
    f1[i] = f2[i] = f3[i] = 0.0;
  }
  bin_width     = (r_max-r_min) / (double)r_bins;
  inv_bin_width = 1.0 / bin_width;
  for(c_i=0; c_i<chain_n_chains; c_i++) {
    cm[3*c_i] = cm[3*c_i+1] = cm[3*c_i+2] = 0.0;
    for(c_j=(c_i+1); c_j<chain_n_chains; c_j++) {
      min_d[c_i*chain_n_chains+c_j] = box_l[0] + box_l[1] + box_l[2];
    }
  }    
  for(c_i=0; c_i<chain_n_chains; c_i++) {
    for(i=0; i<chain_length; i++) {
      mon = chain_start + c_i*chain_length + i;
      cm[3*c_i]+= partCfg[mon].r.p[0]*PMASS(partCfg[mon]);
      cm[3*c_i+1]+= partCfg[mon].r.p[1]*PMASS(partCfg[mon]);
      cm[3*c_i+2]+= partCfg[mon].r.p[2]*PMASS(partCfg[mon]);	  
      for(c_j=(c_i+1); c_j<chain_n_chains; c_j++) {
        for(j=0; j<chain_length; j++) {
          dist = min_distance(partCfg[mon].r.p, partCfg[chain_start + c_j*chain_length+j].r.p);		
          if ((dist > r_min) && (dist < r_max)) {
            ind = (int) ( (dist - r_min)*inv_bin_width ); 
            f1[ind]+= 1.0; 
          }        
          if (dist<min_d[c_i*chain_n_chains+c_j]) min_d[c_i*chain_n_chains+c_j] = dist;
        }
      }
    }       
  }
  chain_mass = 0;
  for(i=0; i<chain_length; i++) chain_mass+= PMASS(partCfg[i]);
  for(c_i=0; c_i<chain_n_chains; c_i++) {  
    cm[3*c_i]/= chain_mass;
    cm[3*c_i+1]/= chain_mass;
    cm[3*c_i+2]/= chain_mass;
    for(c_j=(c_i+1); c_j<chain_n_chains; c_j++) {
      dist = min_d[c_i*chain_n_chains+c_j];
      if ((dist > r_min) && (dist < r_max)) {
        ind = (int) ( (dist - r_min)*inv_bin_width );
        f3[ind]+= 1.0; 
      }  
    }
  }    
  for(c_i=0; c_i<chain_n_chains; c_i++) {  
    for(c_j=(c_i+1); c_j<chain_n_chains; c_j++) {
      dist = min_distance(&cm[3*c_i],&cm[3*c_j]);
      if ((dist > r_min) && (dist < r_max)) {
        ind = (int) ( (dist - r_min)*inv_bin_width );
        f2[ind]+= 1.0; 
      }  
    }
  }
  /* normalization */
  factor = box_l[0]*box_l[1]*box_l[2] *1.5/PI/(chain_n_chains*(chain_n_chains-1));
  for(i=0; i<r_bins; i++) {
    r_in       = i*bin_width + r_min; 
    r_out      = r_in + bin_width;
    bin_volume = r_out*r_out*r_out - r_in*r_in*r_in;
    f1[i] *= factor / (bin_volume * chain_length*chain_length);
    f2[i] *= factor / bin_volume;
    f3[i] *= factor / bin_volume;
  }  
}
示例#7
0
文件: dpd.hpp 项目: tojb/espresso
/** Calculate Random Force and Friction Force acting between particle
    p1 and p2 and add them to their forces. */
inline void add_dpd_thermo_pair_force(Particle *p1, Particle *p2, double d[3], double dist, double dist2)
{
  extern double dpd_gamma,dpd_pref1, dpd_pref2,dpd_r_cut,dpd_r_cut_inv;
  extern int dpd_wf;
#ifdef TRANS_DPD
  extern double dpd_tgamma, dpd_pref3, dpd_pref4,dpd_tr_cut,dpd_tr_cut_inv;
  extern int dpd_twf;
#endif
  int j;
  // velocity difference between p1 and p2
  double vel12_dot_d12=0.0;
  // inverse distance
  double dist_inv;
  // weighting functions for friction and random force
  double omega,omega2;// omega = w_R/dist
  double friction, noise;
  //Projection martix
#ifdef TRANS_DPD
  int i;
  double P_times_dist_sqr[3][3]={{dist2,0,0},{0,dist2,0},{0,0,dist2}},noise_vec[3];
  double f_D[3],f_R[3];
#endif
  double tmp;
#ifdef DPD_MASS
  double massf;
#endif

#ifdef LEES_EDWARDS
  if( le_chatterjee_test_pair(p1, p2) == 0 ) return;
#endif
  
#ifdef EXTERNAL_FORCES
  // if any of the two particles is fixed in some direction then
  // do not add any dissipative or stochastic dpd force part
  // because dissipation-fluctuation theorem is violated
  if (dpd_ignore_fixed_particles)
    if ( (p1->l.ext_flag | p2->l.ext_flag) & COORDS_FIX_MASK) return;
#endif

#ifdef VIRTUAL_SITES
    if (ifParticleIsVirtual(p1) || ifParticleIsVirtual(p2)) return;
#endif	  

#ifdef DPD_MASS_RED
  massf=2*PMASS(*p1)*PMASS(*p2)/(PMASS(*p1)+PMASS(*p2));
#endif

#ifdef DPD_MASS_LIN
  massf=0.5*(PMASS(*p1)+PMASS(*p2));
#endif


  dist_inv = 1.0/dist;

  if((dist < dpd_r_cut)&&(dpd_gamma > 0.0)) {
    if ( dpd_wf == 1 ) //w_R=1
    {
       omega    = dist_inv;
    }
    else //w_R=(1-r/r_c)
    {
    	omega    = dist_inv- dpd_r_cut_inv;
    }
#ifdef DPD_MASS
    omega*=sqrt(massf);
#endif
    omega2   = SQR(omega);
    //DPD part
    // friction force prefactor
    for(j=0; j<3; j++)  vel12_dot_d12 += (p1->m.v[j] - p2->m.v[j]) * d[j];
    friction = dpd_pref1 * omega2 * vel12_dot_d12;
    // random force prefactor
    noise    = dpd_pref2 * omega      * (d_random()-0.5);
    for(j=0; j<3; j++) {
       p1->f.f[j] += ( tmp = (noise - friction)*d[j] );
       p2->f.f[j] -= tmp;
    }
  }
#ifdef TRANS_DPD
    //DPD2 part
  if ((dist < dpd_tr_cut)&&(dpd_tgamma > 0.0)){
      if ( dpd_twf == 1 )
      {
        omega    = dist_inv;
      }
      else 
      {
        omega    = dist_inv- dpd_tr_cut_inv;
      }
#ifdef DPD_MASS
      omega*=sqrt(massf);
#endif
      omega2   = SQR(omega);
      for (i=0;i<3;i++){
        //noise vector
        noise_vec[i]=d_random()-0.5;
        // Projection Matrix
        for (j=0;j<3;j++){
          P_times_dist_sqr[i][j]-=d[i]*d[j];
        }
      }
      for (i=0;i<3;i++){
        //Damping force
        f_D[i]=0;
        //Random force
        f_R[i]=0;
        for (j=0;j<3;j++){
          f_D[i]+=P_times_dist_sqr[i][j]*(p1->m.v[j] - p2->m.v[j]);
          f_R[i]+=P_times_dist_sqr[i][j]*noise_vec[j];
        }
        //NOTE: velocity are scaled with time_step
        f_D[i]*=dpd_pref3*omega2;
        //NOTE: noise force scales with 1/sqrt(time_step
        f_R[i]*=dpd_pref4*omega*dist_inv;
      }
      for(j=0; j<3; j++) {
        tmp=f_R[j]-f_D[j];
        p1->f.f[j] += tmp;
        p2->f.f[j] -= tmp;
      }
  }
#endif
}
inline void add_inter_dpd_pair_force(Particle *p1, Particle *p2, IA_parameters *ia_params,
				double d[3], double dist, double dist2)
{
  int j;
  // velocity difference between p1 and p2
  double vel12_dot_d12=0.0;
  // inverse distance
  double dist_inv;
  // weighting functions for friction and random force
  double omega,omega2;// omega = w_R/dist
  double friction, noise;
  //Projection martix
  int i;
  double P_times_dist_sqr[3][3]={{0,0,0},{0,0,0},{0,0,0}},noise_vec[3];
  double f_D[3],f_R[3];
  double tmp;
#ifdef DPD_MASS
  double massf;
#endif

#ifdef EXTERNAL_FORCES
  // if any of the two particles is fixed in some direction then
  // do not add any dissipative or stochastic dpd force part
  // because dissipation-fluctuation theorem is violated
  if (dpd_ignore_fixed_particles)
    if ( (p1->l.ext_flag | p2->l.ext_flag) & COORDS_FIX_MASK) return;
#endif

#ifdef DPD_MASS_RED
  massf=2*PMASS(*p1)*PMASS(*p2)/(PMASS(*p1)+PMASS(*p2));
#endif

#ifdef DPD_MASS_LIN
  massf=0.5*(PMASS(*p1)+PMASS(*p2));
#endif

  P_times_dist_sqr[0][0]=dist2;
  P_times_dist_sqr[1][1]=dist2;
  P_times_dist_sqr[2][2]=dist2;
  dist_inv = 1.0/dist;
  if((dist < ia_params->dpd_r_cut)&&(ia_params->dpd_gamma > 0.0)) {
    if ( dpd_wf == 1 )
    {
       omega    = dist_inv;
    }
    else 
    {
    	omega    = dist_inv - 1.0/ia_params->dpd_r_cut;
    }
#ifdef DPD_MASS
    omega*=sqrt(massf);
#endif
    omega2   = SQR(omega);
    //DPD part
       // friction force prefactor
    for(j=0; j<3; j++)  vel12_dot_d12 += (p1->m.v[j] - p2->m.v[j]) * d[j];
    friction = ia_params->dpd_pref1 * omega2 * vel12_dot_d12;
    // random force prefactor
    noise    = ia_params->dpd_pref2 * omega      * (d_random()-0.5);
    for(j=0; j<3; j++) {
       p1->f.f[j] += ( tmp = (noise - friction)*d[j] );
       p2->f.f[j] -= tmp;
    }
  }
  //DPD2 part
  if ((dist < ia_params->dpd_tr_cut)&&(ia_params->dpd_tgamma > 0.0)){
      if ( ia_params->dpd_twf == 1 )
      {
        omega    = dist_inv;
      }
      else 
      {
        omega    = dist_inv- 1.0/ia_params->dpd_tr_cut;
      }
#ifdef DPD_MASS
      omega*=sqrt(massf);
#endif
      omega2   = SQR(omega);
      for (i=0;i<3;i++){
        //noise vector
        noise_vec[i]=d_random()-0.5;
        // Projection Matrix
        for (j=0;j<3;j++){
          P_times_dist_sqr[i][j]-=d[i]*d[j];
        }
      }
      for (i=0;i<3;i++){
        //Damping force
        f_D[i]=0;
        //Random force
        f_R[i]=0;
        for (j=0;j<3;j++){
          f_D[i]+=P_times_dist_sqr[i][j]*(p1->m.v[j] - p2->m.v[j]);
          f_R[i]+=P_times_dist_sqr[i][j]*noise_vec[j];
        }
        //NOTE: velocity are scaled with time_step
        f_D[i]*=ia_params->dpd_pref3*omega2;
        //NOTE: noise force scales with 1/sqrt(time_step
        f_R[i]*=ia_params->dpd_pref4*omega*dist_inv;
      }
      for(j=0; j<3; j++) {
        tmp=f_R[j]-f_D[j];
        p1->f.f[j] += tmp;
        p2->f.f[j] -= tmp;
      }
  }
}