double mindist(IntList *set1, IntList *set2)
{
  double mindist, pt[3];
  int i, j, in_set;

  mindist = SQR(box_l[0] + box_l[1] + box_l[2]);

  updatePartCfg(WITHOUT_BONDS);
  for (j=0; j<n_part-1; j++) {
    pt[0] = partCfg[j].r.p[0];
    pt[1] = partCfg[j].r.p[1];
    pt[2] = partCfg[j].r.p[2];
    /* check which sets particle j belongs to
       bit 0: set1, bit1: set2
    */
    in_set = 0;
    if (!set1 || intlist_contains(set1, partCfg[j].p.type))
      in_set = 1;
    if (!set2 || intlist_contains(set2, partCfg[j].p.type))
      in_set |= 2;
    if (in_set == 0)
      continue;

    for (i=j+1; i<n_part; i++)
      /* accept a pair if particle j is in set1 and particle i in set2 or vice versa. */
      if (((in_set & 1) && (!set2 || intlist_contains(set2, partCfg[i].p.type))) ||
          ((in_set & 2) && (!set1 || intlist_contains(set1, partCfg[i].p.type))))
        mindist = dmin(mindist, min_distance2(pt, partCfg[i].r.p));
  }
  mindist = sqrt(mindist);

  return mindist;
}
void calc_part_distribution(int *p1_types, int n_p1, int *p2_types, int n_p2, 
			    double r_min, double r_max, int r_bins, int log_flag, 
			    double *low, double *dist)
{
  int i,j,t1,t2,ind,cnt=0;
  double inv_bin_width=0.0;
  double min_dist,min_dist2=0.0,start_dist2,act_dist2;

  start_dist2 = SQR(box_l[0] + box_l[1] + box_l[2]);
  /* bin preparation */
  *low = 0.0;
  for(i=0;i<r_bins;i++) dist[i] = 0.0;
  if(log_flag == 1) inv_bin_width = (double)r_bins/(log(r_max)-log(r_min));
  else              inv_bin_width = (double)r_bins / (r_max-r_min);

  /* particle loop: p1_types*/
  for(i=0; i<n_part; i++) {
    for(t1=0; t1<n_p1; t1++) {
      if(partCfg[i].p.type == p1_types[t1]) {
	min_dist2 = start_dist2;
	/* particle loop: p2_types*/
	for(j=0; j<n_part; j++) {
	  if(j != i) {
	    for(t2=0; t2<n_p2; t2++) {
	      if(partCfg[j].p.type == p2_types[t2]) {
		act_dist2 =  min_distance2(partCfg[i].r.p, partCfg[j].r.p);
		if(act_dist2 < min_dist2) { min_dist2 = act_dist2; }
	      }
	    }
	  }
	}
	min_dist = sqrt(min_dist2);
	if(min_dist <= r_max) {
	  if(min_dist >= r_min) {
	    /* calculate bin index */
	    if(log_flag == 1) ind = (int) ((log(min_dist) - log(r_min))*inv_bin_width);
	    else              ind = (int) ((min_dist - r_min)*inv_bin_width);
	    if(ind >= 0 && ind < r_bins) {
	      dist[ind] += 1.0;
	    }
	  }
	  else {
	    *low += 1.0;
	  }
	}
	cnt++;    
      }
    }
  }
  
  /* normalization */
  *low /= (double)cnt;
  for(i=0;i<r_bins;i++) dist[i] /= (double)cnt;
}
Exemple #3
0
 /**
  * updates the histogram
  */
 void updateHistogram() {
     double max_distance2 = 2. * (L/2.) * (L/2.);
     double distance2;
     int historyIndex;
     #pragma omp parallel for
     for(int i=0; i<Nx*Ny; i++) {
         for(int j=0; j<i; j++) {
             // get the minimal distance
             distance2 = min_distance2(discs[i], discs[j]);
             // increment the histogram value that this corresponds to
             historyIndex = (distance2/max_distance2) * (M-1);
             assert(historyIndex < M && historyIndex >= 0);
             histogram[historyIndex]++;
         }
     }
 }
int aggregation(double dist_criteria2, int min_contact, int s_mol_id, int f_mol_id, int *head_list, int *link_list, int *agg_id_list, int *agg_num, int *agg_size, int *agg_max, int *agg_min, int *agg_avg, int *agg_std, int charge)
{
  int c, np, n, i;
  Particle *p1, *p2, **pairs;
  double dist2;
  int target1;
  int p1molid, p2molid;
  int *contact_num, ind;

  if (min_contact > 1) {
    contact_num = (int *) malloc(n_molecules*n_molecules *sizeof(int));
    for (i = 0; i < n_molecules *n_molecules; i++) contact_num[i]=0;
  } else {
    contact_num = (int *) 0; /* Just to keep the compiler happy */
  }

  on_observable_calc();
  build_verlet_lists();

  for (i = s_mol_id; i <= f_mol_id; i++) {
    head_list[i]=i;
    link_list[i]=-1;
    agg_id_list[i]=i;
    agg_size[i]=0;
  }
  
  /* Loop local cells */
  for (c = 0; c < local_cells.n; c++) {
    /* Loop cell neighbors */
    for (n = 0; n < dd.cell_inter[c].n_neighbors; n++) {
      pairs = dd.cell_inter[c].nList[n].vList.pair;
      np    = dd.cell_inter[c].nList[n].vList.n;
      /* verlet list loop */
      for(i=0; i<2*np; i+=2) {
	p1 = pairs[i];                    /* pointer to particle 1 */
	p2 = pairs[i+1];                  /* pointer to particle 2 */
	p1molid = p1->p.mol_id;
	p2molid = p2->p.mol_id;
	if (((p1molid <= f_mol_id) && (p1molid >= s_mol_id)) && ((p2molid <= f_mol_id) && (p2molid >= s_mol_id))) {
	  if (agg_id_list[p1molid] != agg_id_list[p2molid]) {
	    dist2 = min_distance2(p1->r.p, p2->r.p);

#ifdef ELECTROSTATICS
	    if (charge && (p1->p.q * p2->p.q >= 0)) {continue;}
#endif
	    if (dist2 < dist_criteria2) {
	      if ( p1molid > p2molid ) { ind=p1molid*n_molecules + p2molid;} 
	      else { ind=p2molid*n_molecules +p1molid;}
	      if (min_contact > 1) {
		contact_num[ind] ++;
		if (contact_num[ind] >= min_contact) {
		    merge_aggregate_lists( head_list, agg_id_list, p1molid, p2molid, link_list);				    
		}
	      } else {
		  merge_aggregate_lists( head_list, agg_id_list, p1molid, p2molid, link_list);				    
	      }
	    }
	  }
	}
      }
    }
  }
  
  /* count number of aggregates 
     find aggregate size
     find max and find min size, and std */
  for (i = s_mol_id ; i <= f_mol_id ; i++) {
    if (head_list[i] != -2) {
      (*agg_num)++;
      agg_size[*agg_num -1]++;
      target1= head_list[i];
      while( link_list[target1] != -1) {
	target1= link_list[target1];
	agg_size[*agg_num -1]++;
      }
    }
  }
  
  for (i = 0 ; i < *agg_num; i++) {
    *agg_avg += agg_size[i];
    *agg_std += agg_size[i] * agg_size[i];
    if (*agg_min > agg_size[i]) { *agg_min = agg_size[i]; }
    if (*agg_max < agg_size[i]) { *agg_max = agg_size[i]; }
  }
  
  return 0;
}
Exemple #5
0
/** returns the minimal distance between two positions in the perhaps periodic
    simulation box.
 *  \param pos1  Position one.
 *  \param pos2  Position two.
 */
inline double min_distance(double pos1[3], double pos2[3]) {
  return sqrt(min_distance2(pos1, pos2));
}