예제 #1
0
void  momentofinertiamatrix(int type, double *MofImatrix)
{
  int i,j,count;
  double p1[3],com[3],massi;

  count=0;
  updatePartCfg(WITHOUT_BONDS);
  for(i=0;i<9;i++) MofImatrix[i]=0.;
  centermass(type, com);
  for (j=0; j<n_part; j++) {
    if (type == partCfg[j].p.type) {
      count ++;
      for (i=0; i<3; i++) {
      	p1[i] = partCfg[j].r.p[i] - com[i];
      }
      massi= PMASS(partCfg[j]);
      MofImatrix[0] += massi * (p1[1] * p1[1] + p1[2] * p1[2]) ; 
      MofImatrix[4] += massi * (p1[0] * p1[0] + p1[2] * p1[2]);
      MofImatrix[8] += massi * (p1[0] * p1[0] + p1[1] * p1[1]);
      MofImatrix[1] -= massi * (p1[0] * p1[1]);
      MofImatrix[2] -= massi * (p1[0] * p1[2]); 
      MofImatrix[5] -= massi * (p1[1] * p1[2]);
    }
  }
  /* use symmetry */
  MofImatrix[3] = MofImatrix[1]; 
  MofImatrix[6] = MofImatrix[2]; 
  MofImatrix[7] = MofImatrix[5];
  return;
}
예제 #2
0
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;
}
예제 #3
0
void nbhood(double pt[3], double r, IntList *il, int planedims[3] )
{
  double d[3];
  int i,j;
  double r2;

  r2 = r*r;

  init_intlist(il);
 
  updatePartCfg(WITHOUT_BONDS);

  for (i = 0; i<n_part; i++) {
    if ( (planedims[0] + planedims[1] + planedims[2]) == 3 ) {
      get_mi_vector(d, pt, partCfg[i].r.p);
    } else {
      /* Calculate the in plane distance */
      for ( j= 0 ; j < 3 ; j++ ) {
	d[j] = planedims[j]*(partCfg[i].r.p[j]-pt[j]);
      }
    }

    if (sqrlen(d) < r2) {
      realloc_intlist(il, il->n + 1);
      il->e[il->n] = partCfg[i].p.identity;
      il->n++;
    }
  }
}
예제 #4
0
int updatePartCfg(int bonds_flag)
{
  int j;

  if(partCfg)
    return 1;

  partCfg = (Particle*)malloc(n_part*sizeof(Particle));
  if (bonds_flag != WITH_BONDS)
    mpi_get_particles(partCfg, NULL);
  else
    mpi_get_particles(partCfg,&partCfg_bl);

  for(j=0; j<n_part; j++)
    unfold_position(partCfg[j].r.p,partCfg[j].l.i);
  partCfgSorted = 0;
#ifdef VIRTUAL_SITES

  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} ");
    return 0;
  }
  if (!updatePartCfg(bonds_flag)) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not update positions of virtual sites in partcfg } ");
    return 0;
  }
#endif
return 1;
}
예제 #5
0
/* Get a complete list of the orientations of every lipid assuming a
   bilayer structure.  Requires grid*/
int get_lipid_orients(IntList* l_orient) {
  int i,gi,gj, atom;
  double zreflocal,zref;  
  double dir[3];
  double refdir[3] = {0,0,1};
  double grid_size[2];

  double* height_grid;

  if ( xdir + ydir + zdir == -3 || mode_grid_3d[xdir] <= 0 || mode_grid_3d[ydir] <= 0 ) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{036 cannot calculate lipid orientations with uninitialized grid} ");
    return ES_ERROR;
  }

  /* Allocate memory for height grid arrays and initialize these arrays */
  height_grid = (double*) malloc((mode_grid_3d[xdir])*sizeof(double)*mode_grid_3d[ydir]);


  /* Calculate physical size of grid mesh */
  grid_size[xdir] = box_l[xdir]/(double)mode_grid_3d[xdir];
  grid_size[ydir] = box_l[ydir]/(double)mode_grid_3d[ydir];


  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  //Make sure particles are sorted
  if (!sortPartCfg()) {
    fprintf(stderr,"%d,could not sort partCfg \n",this_node);
    return -1;
  }
  
  if ( !calc_fluctuations(height_grid, 1) ) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{034 calculation of height grid failed } ");
    return -1;
  }

  zref = calc_zref( zdir );

  for ( i = 0 ; i < n_molecules ; i++) {
    atom = topology[i].part.e[0];
    gi = floor( partCfg[atom].r.p[xdir]/grid_size[xdir] );
    gj = floor( partCfg[atom].r.p[ydir]/grid_size[ydir] );
    zreflocal = height_grid[gj+gi*mode_grid_3d[xdir]] + zref;
    l_orient->e[i] = lipid_orientation(atom,partCfg,zreflocal,dir,refdir);
  }

  free(height_grid);

  return 1;
}
예제 #6
0
int tclcommand_analyze_parse_cwvac(Tcl_Interp *interp, int argc, char **argv)
{
  /* 'analyze { cwvac } <maxtau> <interval> [<chain_start> <n_chains> <chain_length>]' */
  /***********************************************************************************************************/
  char buffer[4*TCL_DOUBLE_SPACE+7];
  int i, maxtau, interval;
  double *avac, *evac;
  if (argc < 2) {
    Tcl_AppendResult(interp, "Wrong # of args! Usage: analyze gkmobility <maxtau> <interval> [<chain_start> <n_chains> <chain_length>]",
		     (char *)NULL);
    return (TCL_ERROR);
  } else {
    if (!ARG0_IS_I(maxtau))
      return (TCL_ERROR);
    if (!ARG1_IS_I(interval))
      return (TCL_ERROR);
    argc-=2; argv+=2;
  }
  if (tclcommand_analyze_set_parse_chain_topology_check(interp, argc, argv) == TCL_ERROR) return TCL_ERROR;
  
  if ((chain_n_chains == 0) || (chain_length == 0)) {
    Tcl_AppendResult(interp, "The chain topology has not been set",(char *)NULL); return TCL_ERROR;
  }
  
  if (maxtau <=0) {
    Tcl_AppendResult(interp, "Nothing to be done - choose <maxtau> greater zero!",(char *)NULL); return TCL_ERROR;
  }

  if (interval <= 0) {
    Tcl_AppendResult(interp, "<interval> has to be positive", (char *)NULL);
    return TCL_ERROR;
  }
  updatePartCfg(WITHOUT_BONDS);
  analyze_cwvac(maxtau, interval, &avac, &evac);
  // create return string
  sprintf(buffer, "{ ");
  Tcl_AppendResult(interp, buffer, (char *)NULL);
  for(i=0;i<=maxtau;i++) {
    sprintf(buffer,"%e ",avac[i]);
    Tcl_AppendResult(interp, buffer, (char *)NULL);
  }
  sprintf(buffer, "} { ");
  Tcl_AppendResult(interp, buffer, (char *)NULL);
  for(i=0;i<=maxtau;i++) {
    sprintf(buffer,"%e ",evac[i]);
    Tcl_AppendResult(interp, buffer, (char *)NULL);
  }
  sprintf(buffer, "}");
  Tcl_AppendResult(interp, buffer, (char *)NULL);
  free(avac); free(evac);
  return (TCL_OK);
}
예제 #7
0
int tclcommand_analyze_parse_rdfchain(Tcl_Interp *interp, int argc, char **argv)
{
  /* 'analyze { rdfchain } <r_min> <r_max> <r_bins> [<chain_start> <n_chains> <chain_length>]' */
  /***********************************************************************************************************/
  char buffer[4*TCL_DOUBLE_SPACE+7];
  int i, r_bins;
  double r_min, r_max, *f1, *f2, *f3;
  double bin_width, r;
  if (argc < 3) {
    Tcl_AppendResult(interp, "Wrong # of args! Usage: analyze rdfchain <r_min> <r_max> <r_bins> [<chain_start> <n_chains> <chain_length>]",
		     (char *)NULL);
    return (TCL_ERROR);
  } else {
    if (!ARG0_IS_D(r_min))
      return (TCL_ERROR);
    if (!ARG1_IS_D(r_max))
      return (TCL_ERROR);
    if (!ARG_IS_I(2, r_bins))
      return (TCL_ERROR);
    argc-=3; argv+=3;
  }
  if (tclcommand_analyze_set_parse_chain_topology_check(interp, argc, argv) == TCL_ERROR) return TCL_ERROR;
  
  if ((chain_n_chains == 0) || (chain_length == 0)) {
    Tcl_AppendResult(interp, "The chain topology has not been set",(char *)NULL); return TCL_ERROR;
  }
  
  if (r_bins <=0) {
    Tcl_AppendResult(interp, "Nothing to be done - choose <r_bins> greater zero!",(char *)NULL); return TCL_ERROR;
  }

  if (r_min <= 0.) {
    Tcl_AppendResult(interp, "<r_min> has to be positive", (char *)NULL);
    return TCL_ERROR;
  }
  if (r_max <= r_min) {
    Tcl_AppendResult(interp, "<r_max> has to be larger than <r_min>", (char *)NULL);
    return TCL_ERROR;
  }
  updatePartCfg(WITHOUT_BONDS);
  analyze_rdfchain(r_min, r_max, r_bins, &f1, &f2, &f3);

  bin_width = (r_max - r_min) / (double)r_bins;
  r = r_min + bin_width/2.0;
  for(i=0; i<r_bins; i++) {
    sprintf(buffer,"{%f %f %f %f} ",r,f1[i],f2[i],f3[i]);
    Tcl_AppendResult(interp, buffer, (char *)NULL);
     r+= bin_width;
  }  
  free(f1); free(f2); free(f3);
  return (TCL_OK);
}
예제 #8
0
int tclcommand_analyze_parse_and_print_pressure_mol(Tcl_Interp *interp,int argc, char **argv)
{
    char buffer[TCL_DOUBLE_SPACE];
    int type1, type2;
    double psum;
#ifdef ELECTROSTATICS
#ifndef INTER_RF
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "parse_and_print_pressure_mol is only possible with INTER_RF ", (char *)NULL);
    return (TCL_ERROR);
#endif
#endif
    updatePartCfg(WITHOUT_BONDS);
    if (!sortPartCfg()) {
        char *errtxt = runtime_error(128);
        ERROR_SPRINTF(errtxt, "{059 parse_and_print_pressure_mol: could not sort particle config, particle ids not consecutive?} ");
        return TCL_ERROR;
    }
    if (argc < 2) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL);
        return (TCL_ERROR);
    }

    if (!ARG0_IS_I(type1)) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL);
        return (TCL_ERROR);
    }
    if (!ARG1_IS_I(type2)) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL);
        return (TCL_ERROR);
    }
    argc-=2;
    argv+=2;

    if (n_molecules==0) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "No molecules defined !", (char *)NULL);
        return (TCL_ERROR);
    }
    psum=calc_pressure_mol(type1,type2);
    //sprintf(buffer,"%i",type1);
    //Tcl_AppendResult(interp,"{ analyze pressure_mol ",buffer," ",(char *)NULL);
    //sprintf(buffer,"%i",type2);
    //Tcl_AppendResult(interp,buffer," ",(char *)NULL);
    sprintf(buffer,"%e",psum);
    Tcl_AppendResult(interp, buffer,(char *)NULL);
    return TCL_OK;
}
예제 #9
0
std::vector<double> centerofmass(int type)
{
    std::vector<double> com (3);
    double mass = 0.0;
    
    updatePartCfg(WITHOUT_BONDS);
    for (int i=0; i<n_part; i++) {
        if ((partCfg[i].p.type == type) || (type == -1)) {
            for (int j=0; j<3; j++) {
                com[j] += partCfg[i].r.p[j]*(partCfg[i]).p.mass;
            }
            mass += (partCfg[i]).p.mass;
        }
    }
    for (int j=0; j<3; j++) com[j] /= mass;
    return com;
}
예제 #10
0
double distto(double p[3], int pid)
{
  int i;
  double d[3];
  double mindist;

  updatePartCfg(WITHOUT_BONDS);

  /* larger than possible */
  mindist=SQR(box_l[0] + box_l[1] + box_l[2]);
  for (i=0; i<n_part; i++) {
    if (pid != partCfg[i].p.identity) {
      get_mi_vector(d, p, partCfg[i].r.p);
      mindist = dmin(mindist, sqrlen(d));
    }
  }
  return sqrt(mindist);
}
예제 #11
0
int tclcommand_analyze_parse_and_print_energy_kinetic_mol(Tcl_Interp *interp,int argc, char **argv)
{
    char buffer[TCL_DOUBLE_SPACE];
    int type;
    double Ekin;
    updatePartCfg(WITHOUT_BONDS);
    if (!sortPartCfg()) {
        char *errtxt = runtime_error(128);
        ERROR_SPRINTF(errtxt, "{059 parse_and_print_energy_kinetic_mol: could not sort particle config, particle ids not consecutive?} ");
        return TCL_ERROR;
    }
    if (argc < 1) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "usage: analyze energy_kinetic <type>", (char *)NULL);
        return (TCL_ERROR);
    }

    if (!ARG0_IS_I(type)) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "usage: analyze energy_kinetic <type>", (char *)NULL);
        return (TCL_ERROR);
    }
    argc-=1;
    argv+=1;

    if (n_molecules==0) {
        Tcl_ResetResult(interp);
        Tcl_AppendResult(interp, "No molecules defined !", (char *)NULL);
        return (TCL_ERROR);
    }
    Ekin=calc_energy_kinetic_mol(type);
    if (Ekin < 0.0) {
        Tcl_ResetResult(interp);
        sprintf(buffer,"%i",-(int)Ekin);
        Tcl_AppendResult(interp,"Could not fetch com in calc_energy_kinetic_mol! From mol_id",buffer, (char *)NULL);
        return (TCL_ERROR);
    }
    //sprintf(buffer,"%i",type);
    //Tcl_AppendResult(interp,"{ analyze pressure_mol ",buffer," ",(char *)NULL);
    sprintf(buffer,"%e",Ekin);
    Tcl_AppendResult(interp, buffer,(char *)NULL);
    return TCL_OK;
}
예제 #12
0
void centermass(int type, double *com)
{
  int i, j;
  double M = 0.0;
  com[0]=com[1]=com[2]=0.;
   	
  updatePartCfg(WITHOUT_BONDS);
  for (j=0; j<n_part; j++) {
    if ((partCfg[j].p.type == type) || (type == -1)) {
      for (i=0; i<3; i++) {
      	com[i] += partCfg[j].r.p[i]*PMASS(partCfg[j]);
      }
      M += PMASS(partCfg[j]);
    }
  }
  
  for (i=0; i<3; i++) {
    com[i] /= M;
  }
  return;
}
예제 #13
0
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;
}
예제 #14
0
int update_particle_array(int type) {
	updatePartCfg(WITHOUT_BONDS);
	if (!partCfg) 
		return ES_ERROR;

	int t_c = 0;
	for (int i=0; i<n_part; i++) {
		if (partCfg[i].p.type == type ) {
			type_array[Index.type[type]].id_list[t_c++] = partCfg[i].p.identity;
		}	
		if ( t_c > (double) type_array[Index.type[type]].cur_size/2.0 ) {
			if ( reallocate_type_array(type) == ES_ERROR ) 
				return ES_ERROR;
		}
	}
	type_array[Index.type[type]].max_entry = t_c;
	for ( int i = t_c; i<type_array[Index.type[type]].cur_size; i++)
		type_array[Index.type[type]].id_list[i] = -1;

	return ES_OK;
}
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);
}
예제 #16
0
void centermass_vel(int type, double *com)
{
  /*center of mass velocity scaled with time_step*/
  int i, j;
  int count = 0;
  com[0]=com[1]=com[2]=0.;

  updatePartCfg(WITHOUT_BONDS);
  for (j=0; j<n_part; j++) {
    if (type == partCfg[j].p.type) {
      for (i=0; i<3; i++) {
      	com[i] += partCfg[j].m.v[i];
      }
      count++;
    }
  }

  for (i=0; i<3; i++) {
    com[i] /= count;
  }
  return;
}
예제 #17
0
std::vector<double> centerofmass_vel(int type)
{
    /*center of mass velocity scaled with time_step*/
    std::vector<double> com_vel (3);
    int i, j;
    int count = 0;

    updatePartCfg(WITHOUT_BONDS);
    for (j=0; j<n_part; j++) {
        if (type == partCfg[j].p.type) {
            for (i=0; i<3; i++) {
            	com_vel[i] += partCfg[j].m.v[i];
            }
            count++;
        }
    }

    for (i=0; i<3; i++) {
        com_vel[i] /= count;
    }
    return com_vel;
}
예제 #18
0
int updatePartCfg(int bonds_flag)
{
  int j;

  if(partCfg)
    return 1;

  partCfg = (Particle*)malloc(n_part*sizeof(Particle));
  if (bonds_flag != WITH_BONDS)
    mpi_get_particles(partCfg, NULL);
  else
    mpi_get_particles(partCfg,&partCfg_bl);

  for(j=0; j<n_part; j++)
#ifdef LEES_EDWARDS
    unfold_position(partCfg[j].r.p, partCfg[j].m.v, partCfg[j].l.i);
#else
    unfold_position(partCfg[j].r.p, partCfg[j].l.i);
#endif
  partCfgSorted = 0;
#ifdef VIRTUAL_SITES

  if (!sortPartCfg()) {
      ostringstream msg;
      msg <<"could not sort partCfg";
      runtimeError(msg);
    return 0;
  }
  if (!updatePartCfg(bonds_flag)) {
      ostringstream msg;
      msg <<"could not update positions of virtual sites in partcfg";
      runtimeError(msg);
    return 0;
  }
#endif
return 1;
}
예제 #19
0
int sortPartCfg()
{
  int i;
  Particle *sorted;

  if (!partCfg)
    updatePartCfg(WITHOUT_BONDS);

  if (partCfgSorted)
    return 1;

  if (n_part != max_seen_particle + 1)
    return 0;

  sorted = (Particle*)malloc(n_part*sizeof(Particle));
  for(i = 0; i < n_part; i++)
    memcpy(&sorted[partCfg[i].p.identity], &partCfg[i], sizeof(Particle));
  free(partCfg);
  partCfg = sorted;

  partCfgSorted = 1;

  return 1;
}
예제 #20
0
int calc_radial_density_map (int xbins,int ybins,int thetabins,double xrange,double yrange, double axis[3], double center[3], IntList *beadids, DoubleList *density_map, DoubleList *density_profile) {
  int i,j,t;
  int pi,bi;
  int nbeadtypes;
  int beadcount;
  double vectprod[3];
  double pvector[3];
  double xdist,ydist,rdist,xav,yav,theta;
  double xbinwidth,ybinwidth,binvolume;
  double thetabinwidth;
  double *thetaradii;
  int *thetacounts;
  int xindex,yindex,tindex;
  xbinwidth = xrange/(double)(xbins);
  ybinwidth = yrange/(double)(ybins);

  nbeadtypes = beadids->n;
  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);

  /*Make sure particles are folded  */
  for (i = 0 ; i < n_part ; i++) {
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,0);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,1);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,2);
  }

  beadcount = 0;
  xav = 0.0;
  yav = 0.0;
  for ( pi = 0 ; pi < n_part ; pi++ ) {
    for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
      if ( beadids->e[bi] == partCfg[pi].p.type ) {


	/* Find the vector from the point to the center */
	vecsub(center,partCfg[pi].r.p,pvector);

	/* Work out x and y coordinates with respect to rotation axis */
	
	/* Find the minimum distance of the point from the axis */
	vector_product(axis,pvector,vectprod);
	xdist = sqrt(sqrlen(vectprod)/sqrlen(axis));

	/* Find the projection of the vector from the point to the center
	   onto the axis vector */
	ydist = scalar(axis,pvector)/sqrt(sqrlen(axis));
	
    
	/* Work out relevant indices for x and y */
	xindex = (int)(floor(xdist/xbinwidth));
	yindex = (int)(floor((ydist+yrange*0.5)/ybinwidth));
	/*
	printf("x %d y %d \n",xindex,yindex);
	printf("p %f %f %f \n",partCfg[pi].r.p[0],partCfg[pi].r.p[1],partCfg[pi].r.p[2]);
	printf("pvec %f %f %f \n",pvector[0],pvector[1],pvector[2]);
	printf("axis %f %f %f \n",axis[0],axis[1],axis[2]);
	printf("dists %f %f \n",xdist,ydist);
	fflush(stdout);
	*/
	/* Check array bounds */
	if ( (xindex < xbins && xindex > 0) && (yindex < ybins && yindex > 0) ) {
	  density_map[bi].e[ybins*xindex+yindex] += 1;
	  xav += xdist;
	  yav += ydist;
	  beadcount += 1;
	} else {
	  //	    fprintf(stderr,"ERROR: outside array bounds in calc_radial_density_map"); fflush(NULL); errexit(); 
	}
      }

    }
  }


  /* Now turn counts into densities for the density map */
  for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
    for ( i = 0 ; i < xbins ; i++ ) {
      /* All bins are cylinders and therefore constant in yindex */
      binvolume = PI*(2*i*xbinwidth + xbinwidth*xbinwidth)*yrange;
      for ( j = 0 ; j < ybins ; j++ ) {
	density_map[bi].e[ybins*i+j] /= binvolume;
      }
    }
  }


  /* if required calculate the theta density profile */
  if ( thetabins > 0 ) {
    /* Convert the center to an output of the density center */
    xav = xav/(double)(beadcount);
    yav = yav/(double)(beadcount);
    thetabinwidth = 2*PI/(double)(thetabins);
    thetaradii = (double*)malloc(thetabins*nbeadtypes*sizeof(double));
    thetacounts = (int*)malloc(thetabins*nbeadtypes*sizeof(int));
    for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
      for ( t = 0 ; t < thetabins ; t++ ) {
	thetaradii[bi*thetabins+t] = 0.0;
	thetacounts[bi*thetabins+t] = 0.0;
      }
    }
    /* Maybe there is a nicer way to do this but now I will just repeat the loop over all particles */
      for ( pi = 0 ; pi < n_part ; pi++ ) {
	for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
	  if ( beadids->e[bi] == partCfg[pi].p.type ) {
	    vecsub(center,partCfg[pi].r.p,pvector);
	    vector_product(axis,pvector,vectprod);
	    xdist = sqrt(sqrlen(vectprod)/sqrlen(axis));
	    ydist = scalar(axis,pvector)/sqrt(sqrlen(axis));
	    /* Center the coordinates */

	    xdist = xdist - xav;
	    ydist = ydist - yav;
	    rdist = sqrt(xdist*xdist+ydist*ydist);
	    if ( ydist >= 0 ) {
	      theta = acos(xdist/rdist);
	    } else {
	      theta = 2*PI-acos(xdist/rdist);
	    }
	    tindex = (int)(floor(theta/thetabinwidth));
	    thetaradii[bi*thetabins+tindex] += xdist + xav;
	    thetacounts[bi*thetabins+tindex] += 1;
	    if ( tindex >= thetabins ) {
	      fprintf(stderr,"ERROR: outside density_profile array bounds in calc_radial_density_map"); fflush(NULL); errexit(); 
	    } else {
	      density_profile[bi].e[tindex] += 1;
	    }
	  }	  
	}
      }



      /* normalize the theta densities*/
      for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
	for ( t = 0 ; t < thetabins ; t++ ) {
	  rdist = thetaradii[bi*thetabins+t]/(double)(thetacounts[bi*thetabins+t]);
	  density_profile[bi].e[t] /= rdist*rdist;
	}
      }
       


      free(thetaradii);
      free(thetacounts);

  }
  






  //  printf("done \n");
  return ES_OK;
}
예제 #21
0
int init_type_array(int type){
	if (init_gc() == ES_ERROR)
		return ES_ERROR;

	updatePartCfg(WITHOUT_BONDS);

	if (!partCfg)
		return ES_ERROR;

	int type_index=-1;
	type_index= (Type.max_entry++);
	if ( type_index == number_of_type_lists ) {
		reallocate_global_type_list(number_of_type_lists*2);
	}

	Type.index = (int *) realloc ( (void *) Type.index, sizeof(int)*Type.max_entry);

	//reallocate the array that holds the particle type and points to the type index used for the type_list
	
	if ( type >= Index.max_entry ) { 
		Index.type= (int * ) realloc( (void *) Index.type, (type+1)*sizeof(int));
		Index.max_entry = type + 1;
	}
	for (int i=0; i<Type.max_entry; i++) 
		Index.type[i]=-1;

	if (Type.index == (int *) 0 || Index.type == (int *) 0)
		return ES_ERROR;

	//allocates a list for ids for as many entries as there are particles right now
	if ( !(partCfg) ||  type < 0 ) { 
		return ES_ERROR;
	}
	Type.index[type_index]=type;
	//fill in array type_index_of_type
	for (int i=0; i<Type.max_entry; i++ ) {
		Index.type[Type.index[i]] = i;
	}

	int t_c = 0; //index
	type_array[Index.type[type]].id_list = (int *) malloc (sizeof (int) * n_part);
	for (int i=0; i<n_part; i++) {
		if ( partCfg[i].p.type==type ) 
			type_array[Index.type[type]].id_list[t_c++]=partCfg[i].p.identity;
	}
	int max_size=n_part;
	if ( t_c != 0 ) { 
		while ( t_c < (double) max_size/4.0) { 
			max_size= floor( (double ) max_size/2.0);
		}
		// now the array is shrinked to at least 4 times the highest entry
		type_array[Index.type[type]].id_list= (int *) realloc( (void *) type_array[Index.type[type]].id_list, sizeof(int)*2*max_size);
		type_array[Index.type[type]].max_entry = t_c;
		type_array[Index.type[type]].cur_size = max_size*2;
	} else {
		//no particles of the given type were found, so leave array size fixed at a reasonable start entry 64 ints in this case
		type_array[Index.type[type]].id_list= (int *) realloc( (void *) type_array[Index.type[type]].id_list, sizeof(int)*64);
		type_array[Index.type[type]].max_entry = t_c;
		type_array[Index.type[type]].cur_size = 64;
	}
	//fill remaining entries with -1
	for (int i=type_array[Index.type[type]].max_entry; i<type_array[Index.type[type]].cur_size; i++) {
		type_array[Index.type[type]].id_list[i] = -1;
	}
	Type_array_init = 1;
	return ES_OK;
}
예제 #22
0
void calc_gyration_tensor(int type, double **_gt)
{
  int i, j, count;
  double com[3];
  double eva[3],eve0[3],eve1[3],eve2[3];
  double *gt=NULL, tmp;
  double Smatrix[9],p1[3];

  for (i=0; i<9; i++) Smatrix[i] = 0;
  /* 3*ev, rg, b, c, kappa, eve0[3], eve1[3], eve2[3]*/
  *_gt = gt = (double*)realloc(gt,16*sizeof(double)); 

  updatePartCfg(WITHOUT_BONDS);

  /* Calculate the position of COM */
  centermass(type,com);

  /* Calculate the gyration tensor Smatrix */
  count=0;
  for (i=0;i<n_part;i++) {
    if ((partCfg[i].p.type == type) || (type == -1)) {
      for ( j=0; j<3 ; j++ ) { 
        p1[j] = partCfg[i].r.p[j] - com[j];
      }
      count ++;
      Smatrix[0] += p1[0]*p1[0];
      Smatrix[1] += p1[0]*p1[1];
      Smatrix[2] += p1[0]*p1[2];
      Smatrix[4] += p1[1]*p1[1];
      Smatrix[5] += p1[1]*p1[2];
      Smatrix[8] += p1[2]*p1[2];
    }
  }
  /* use symmetry */
  Smatrix[3]=Smatrix[1];
  Smatrix[6]=Smatrix[2];
  Smatrix[7]=Smatrix[5];
  for (i=0;i<9;i++){
    Smatrix[i] /= count;
  }

  /* Calculate the eigenvalues of Smatrix */
  i=calc_eigenvalues_3x3(Smatrix, eva);
  tmp=0.0;
  for (i=0;i<3;i++) {
    /* Eigenvalues */
    gt[i] = eva[i];
    tmp += eva[i];
  }
  
  i=calc_eigenvector_3x3(Smatrix,eva[0],eve0); 
  i=calc_eigenvector_3x3(Smatrix,eva[1],eve1); 
  i=calc_eigenvector_3x3(Smatrix,eva[2],eve2); 
  gt[3] = tmp; /* Squared Radius of Gyration */
  gt[4] = eva[0]-0.5*(eva[1]+eva[2]);  /* Asphericity */
  gt[5] = eva[1]-eva[2];  /* Acylindricity */
  gt[6] = (gt[4]*gt[4]+0.75*gt[5]*gt[5])/(gt[3]*gt[3]); /* Relative shape anisotropy */
  /* Eigenvectors */
  for (j=0;j<3;j++) {
    gt[7+j]=eve0[j]; 
    gt[10+j]=eve1[j];
    gt[13+j]=eve2[j];
  }
}
예제 #23
0
/**
   This routine calculates the orientational order parameter for a
   lipid bilayer.  
*/
int orient_order(double* result, double* stored_dirs)
{
  double dir[3];
  double refdir[3] = {0,0,1};
  double sumdir[3] = {0,0,0};
  double zref;
  int bilayer_cnt;
  int i,atom,tmpzdir;
  double dp;
  double len;

  IntList l_orient;
  init_intlist(&l_orient);
  realloc_intlist(&l_orient, n_molecules);

  bilayer_cnt = 0;
  *result = 0;


  // Check to see if the grid has been set and if not then interpret
  if ( xdir + ydir + zdir == -3 ) {
    tmpzdir = 2;
  } else { 
    tmpzdir = zdir;
  };

  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  /* Make sure particles are sorted */
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt, "{035 could not sort partCfg, particles have to start at 0 and have consecutive identities} ");
    return ES_ERROR;
  }

  /* Calculate the reference z position as its mean.*/
  zref = calc_zref( tmpzdir );
 

  /* Calculate the orientation of all the lipids in turn and include
   only UP or DOWN lipids in a calculation of the overall orientation
   direction of the bilayer .. ie the reference vector from which we
   can calculate the orientational order. */

  for ( i = 0 ; i < n_molecules ; i++) {
    atom = topology[i].part.e[0];
    l_orient.e[i] = lipid_orientation(atom,partCfg,zref,dir,refdir);
    stored_dirs[i*3] = dir[0];
    stored_dirs[i*3+1] = dir[1];
    stored_dirs[i*3+2] = dir[2];

    if ( l_orient.e[i] == LIPID_UP ) {
      sumdir[0] += dir[0];
      sumdir[1] += dir[1];
      sumdir[2] += dir[2];
      bilayer_cnt++;
    }
    if ( l_orient.e[i] == LIPID_DOWN ) {
      sumdir[0] -= dir[0];
      sumdir[1] -= dir[1];
      sumdir[2] -= dir[2];
      bilayer_cnt++;
    }
  }

  /* Normalise the bilayer normal vector */
  len = 0.0;
  for ( i = 0 ; i < 3 ; i++) {
    sumdir[i] = sumdir[i]/(double)(bilayer_cnt);
    len += sumdir[i]*sumdir[i];
  }
  for ( i = 0 ; i < 3 ; i++) {
    sumdir[i] = sumdir[i]/sqrt(len);
  }

  /* Calculate the orientational order */
  for ( i = 0 ; i < n_molecules ; i++ ) {
    dir[0] = stored_dirs[i*3];
    dir[1] = stored_dirs[i*3+1];
    dir[2] = stored_dirs[i*3+2];

    if ( l_orient.e[i] != LIPID_STRAY && l_orient.e[i] != REAL_LIPID_STRAY ) {
      dp = scalar(dir,sumdir);
      *result += dp*dp*1.5-0.5;      
    }

  }

  
  realloc_intlist(&l_orient, 0);

  *result = *result/(double)(bilayer_cnt);
  return ES_OK;
}
예제 #24
0
/** This routine performs must of the work involved in the analyze
    modes2d command.  A breakdown of what the routine does is as
    follows

    \li fftw plans and in / out arrays are initialized as required

    \li calculate height function is called

    \li The height function is fourier transformed using the fftw library.

    Note: argument switch_fluc
    switch_fluc == 1 for height grid
    switch_fluc == 0 for thickness
*/
int modes2d(fftw_complex* modes, int switch_fluc) {
  /* All these variables need to be static so that the fftw3 plan can
     be initialised and reused */
  static  fftw_plan mode_analysis_plan; // height grid
  /** Input values for the fft */
  static  double* height_grid;
  /** Output values for the fft */
  static  fftw_complex* result;

/** 
    Every time a change is made to the grid calculate the fftw plan
    for the subsequent fft and destroy any existing plans
*/
  if ( mode_grid_changed ) {
    STAT_TRACE(fprintf(stderr,"%d,initializing fftw for mode analysis \n",this_node));
    if ( xdir + ydir + zdir == -3 ) {
      char *errtxt = runtime_error(128);
      ERROR_SPRINTF(errtxt,"{092 attempt to perform mode analysis with uninitialized grid} ");
      return -1;
    }

    STAT_TRACE(fprintf(stderr,"%d,destroying old fftw plan \n",this_node));

    /* Make sure all memory is free and old plan is destroyed. It's ok
       to call these functions on uninitialised pointers I think */
    fftw_free(result);
    fftw_free(height_grid);
    fftw_destroy_plan(mode_analysis_plan);
    fftw_cleanup(); 
    /* Allocate memory for input and output arrays */
    height_grid = (double*) malloc((mode_grid_3d[xdir])*sizeof(double)*mode_grid_3d[ydir]);
    result      = (fftw_complex*) malloc((mode_grid_3d[ydir]/2+1)*(mode_grid_3d[xdir])*sizeof(fftw_complex)); 
    mode_analysis_plan = fftw_plan_dft_r2c_2d(mode_grid_3d[xdir],mode_grid_3d[ydir],height_grid, result,FFTW_ESTIMATE);

    STAT_TRACE(fprintf(stderr,"%d,created new fftw plan \n",this_node));
    mode_grid_changed = 0;  
    
  }

  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  //Make sure particles are sorted
  if (!sortPartCfg()) {
    fprintf(stderr,"%d,could not sort partCfg \n",this_node);
    return -1;
  }
  
  if ( !calc_fluctuations(height_grid, switch_fluc)) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{034 calculation of height grid failed } ");
    return -1;
  }

  STAT_TRACE(fprintf(stderr,"%d,calling fftw \n",this_node));

  fftw_execute(mode_analysis_plan);
  /* Copy result to modes */
  memcpy(modes, result, mode_grid_3d[xdir]*(mode_grid_3d[ydir]/2 + 1)*sizeof(fftw_complex));
  
  
  STAT_TRACE(fprintf(stderr,"%d,called fftw \n",this_node));    
    
  return 1;
    
}
예제 #25
0
/** This routine calculates density profiles for given bead types as a
    function of height relative to the bilayer midplane where the
    bilayer is assumed to wrap around a sphere of radius r and center
    cx,cy,cz.

    \li The radius value of each bead is then calculated relative to
    the colloid radius and the population of the relevant bin
    is increased.
**/
int bilayer_density_profile_sphere (IntList *beadids, double rrange , DoubleList *density_profile, double radius, double center[3]) {
  int i,j;
  int thisbin,nbins;
  double binwidth;
  int nbeadtypes,l_orient;
  double relativeradius;
  double rvec[3];
  double direction[3]; 
  double innerr;
  double outerr;
  double binvolume;
  double piconst;
  double rs;


  nbins = density_profile[0].max;
  nbeadtypes=beadids->max;
  binwidth = 2*rrange/(double)nbins;


  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  //Make sure particles are sorted
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} ");
    return -1;
  }

  if ( density_profile == NULL ) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{095 density_profile not initialized in calc_bilayer_density_profile } ");
    return -1;
  }

  // Do this to fold the particles
  fold_all( );


   for (i = 0 ; i < n_total_particles ; i++) {
    for ( j = 0 ; j < nbeadtypes ; j++ ) {
      if ( beadids->e[j] == partCfg[i].p.type ) {
	/* What is the relative height compared to the grid */
	get_mi_vector(rvec,partCfg[i].r.p,center);
	relativeradius = sqrt(sqrlen(rvec)) - radius;

	/* If the particle is within our zrange then add it to the profile */
	if ( ( -rrange < relativeradius) && ( relativeradius < rrange) ) {
	  thisbin = (int)(floor((relativeradius+rrange)/binwidth));
	  if ( thisbin < 0 || thisbin >= density_profile[j].max ) {
	        char *errtxt = runtime_error(128);
		ERROR_SPRINTF(errtxt,"{095 bin is outside range } ");
		return -1;
	  }

	  l_orient = lipid_orientation(i,partCfg,0.0,direction,rvec);
	  /* Distinguish between lipids that are in the top and bottom layers */
	  if ( l_orient == LIPID_UP ) {
	    density_profile[j].e[thisbin] += 1.0;
	  }
	  if ( l_orient == LIPID_DOWN ) {
	    density_profile[2*nbeadtypes-j-1].e[thisbin] += 1.0;	    
	  }
	}
	    
      }
    }
  }
  /* Normalize the density profile */
  piconst = (4.0*3.141592)/(3.0);
  rs = radius - rrange;
  for ( i = 0 ; i < 2*nbeadtypes ; i++ ) {
    for ( j = 0 ; j < nbins ; j++ ) {

      innerr = j*binwidth+rs;
      outerr = (j+1)*binwidth + rs;
      binvolume = piconst*(outerr*outerr*outerr - innerr*innerr*innerr);
      density_profile[i].e[j] = density_profile[i].e[j]/binvolume;
    }
  }

   return 1;

}
예제 #26
0
/* parser for hole cluster analyzation:
   analyze holes <prob_part_type_number> <mesh_size>.
   Needs feature LENNARD_JONES compiled in. */
int tclcommand_analyze_parse_holes(Tcl_Interp *interp, int argc, char **argv)
{
  int i,j;
  int probe_part_type;
  int mesh_size=1, meshdim[3];
  double freevol=0.0;
  char buffer[TCL_INTEGER_SPACE+TCL_DOUBLE_SPACE];

  IntList mesh;

  int n_holes;
  int **holes;
  int max_size=0;
  int *surface;

#ifndef LENNARD_JONES
   Tcl_AppendResult(interp, "analyze holes needs feature LENNARD_JONES compiled in.\n", (char *)NULL);
    return TCL_ERROR;
#endif

  /* check # of parameters */
  if (argc < 2) {
    Tcl_AppendResult(interp, "analyze holes needs 2 parameters:\n", (char *)NULL);
    Tcl_AppendResult(interp, "<prob_part_type_number> <mesh_size>", (char *)NULL);
    return TCL_ERROR;
  }

  /* check parameter types */
  if( (! ARG_IS_I(0, probe_part_type)) ||
      (! ARG_IS_I(1, mesh_size))  ) {
    Tcl_AppendResult(interp, "analyze holes needs 2 parameters of type and meaning:\n", (char *)NULL);
    Tcl_AppendResult(interp, "INT INT\n", (char *)NULL);
    Tcl_AppendResult(interp, "<prob_part_type_number> <mesh_size>", (char *)NULL);
    return TCL_ERROR;
  }

  /* check parameter values */
  if( probe_part_type > n_particle_types || probe_part_type < 0 ) {
    Tcl_AppendResult(interp, "analyze holes: probe particle type number does not exist", (char *)NULL);
    return TCL_ERROR;
  }
  if( mesh_size < 1  ) {
    Tcl_AppendResult(interp, "analyze holes: mesh size must be positive (min=1)", (char *)NULL);
    return TCL_ERROR;
  }

  /* preparation */
  updatePartCfg(WITHOUT_BONDS);
  meshdim[0]=mesh_size;
  meshdim[1]=mesh_size;
  meshdim[2]=mesh_size;
  alloc_intlist(&mesh, (meshdim[0]*meshdim[1]*meshdim[2]));

  /* perform free space identification*/
  create_free_volume_grid(mesh, meshdim, probe_part_type);
  /* perfrom hole cluster algorithm */
  n_holes = cluster_free_volume_grid(mesh, meshdim, &holes);
  /* surface to volume ratio */
  surface = (int *) malloc(sizeof(int)*(n_holes+1));
  cluster_free_volume_surface(mesh, meshdim, n_holes, holes, surface);
  /* calculate accessible volume / max size*/
  for ( i=0; i<=n_holes; i++ ) { 
    freevol += holes[i][0];
    if ( holes[i][0]> max_size ) max_size = holes[i][0];
  }

  /* Append result to tcl interpreter */
  Tcl_AppendResult(interp, "{ n_holes mean_hole_size max_hole_size free_volume_fraction { sizes } { surfaces }  { element_lists } } ", (char *)NULL);

  Tcl_AppendResult(interp, "{", (char *)NULL);

  /* number of holes */
  sprintf(buffer,"%d ",n_holes+1); Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  /* mean hole size */
  sprintf(buffer,"%f ",freevol/(n_holes+1.0)); Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  /* max hole size */
  sprintf(buffer,"%d ",max_size); Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  /* free volume fraction */
  sprintf(buffer,"%f ",freevol/(meshdim[0]*meshdim[1]*meshdim[2]));
  Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  /* hole sizes */
  Tcl_AppendResult(interp, "{ ", (char *)NULL);
  for ( i=0; i<=n_holes; i++ ) { 
    sprintf(buffer,"%d ",holes[i][0]); Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  }
  Tcl_AppendResult(interp, "} ", (char *)NULL);
  /* hole surfaces */
  Tcl_AppendResult(interp, "{ ", (char *)NULL);
  for ( i=0; i<=n_holes; i++ ) { 
    sprintf(buffer,"%d ",surface[i]); Tcl_AppendResult(interp, buffer, " ", (char *)NULL);
  }
  Tcl_AppendResult(interp, "} ", (char *)NULL);
  /* hole elements */ 
  Tcl_AppendResult(interp, "{ ", (char *)NULL);
  for ( i=0; i<=n_holes; i++ ) { 
    Tcl_AppendResult(interp, "{ ", (char *)NULL);
    for ( j=1; j <= holes[i][0]; j++ ) {
      sprintf(buffer,"%d",holes[i][j]);
      Tcl_AppendResult(interp, buffer, " ",(char *)NULL);
    }
    Tcl_AppendResult(interp, "} ", (char *)NULL);
  }
  Tcl_AppendResult(interp, "} ", (char *)NULL);
  
  Tcl_AppendResult(interp, "}", (char *)NULL);

  /* free allocated memory */
  realloc_intlist(&mesh, 0);
  free(surface);
  for ( i=0; i<=n_holes; i++ ) { free(holes[i]); }
  free(holes);

  return (TCL_OK);
}
예제 #27
0
int tclcommand_imd_parse_pos(Tcl_Interp *interp, int argc, char **argv)
{
  enum flag {NONE, UNFOLDED, FOLD_CHAINS};
  double shift[3] = {0.0,0.0,0.0};
  //double part_selected=n_total_particles;

  float *coord;
  int flag = NONE;
  int i, j;

  // Determine how many arguments we have and set the value of flag
  switch (argc)
    {
    case 2:
      flag = NONE; 
      break;
    case 3:
      {
	if (ARG_IS_S(2,"-unfolded"))
	  {flag = UNFOLDED;}
	else if (ARG_IS_S(2,"-fold_chains"))
	  {flag = FOLD_CHAINS;}
	else{
	  Tcl_AppendResult(interp, "wrong flag to",argv[0],
			   " positions: should be \" -fold_chains or -unfolded \"",
			   (char *) NULL);
	  return (TCL_ERROR);
	}
      }
      break;
    default:
      Tcl_AppendResult(interp, "wrong # args:  should be \"",
		       argv[0], " positions [-flag]\"",
		       (char *) NULL);
      return (TCL_ERROR);
    }

  if (!initsock) {
    Tcl_AppendResult(interp, "no connection",
		     (char *) NULL);
    return (TCL_OK);
  }
  if (!sock) {
    if (tclcommand_imd_print_check_connect(interp) == TCL_ERROR)
      return (TCL_ERROR);
    
    /* no VMD is ok, but tell the user */
    if (!sock) {
      Tcl_AppendResult(interp, "no connection",
		       (char *) NULL);
      return (TCL_OK);
    }
  }

  if (tclcommand_imd_print_drain_socket(interp) == TCL_ERROR)
    return (TCL_ERROR);
  
  /* we do not consider a non connected VMD as error, but tell the user */
  if (!sock) {
    Tcl_AppendResult(interp, "no connection",
		     (char *) NULL);
    return (TCL_OK);
  }

  if (!(vmdsock_selwrite(sock, 60) > 0)) {
    Tcl_AppendResult(interp, "could not write to IMD socket.",
		     (char *) NULL);
    return (TCL_ERROR);
  }

  if (n_part != max_seen_particle + 1) {
    Tcl_AppendResult(interp, "for IMD, store particles consecutively starting with 0.",
		     (char *) NULL);
    return (TCL_ERROR);      
  }

  updatePartCfg(WITH_BONDS);
  coord = (float*)Utils::malloc(n_part*3*sizeof(float));
  /* sort partcles according to identities */
  for (i = 0; i < n_part; i++) {
    int dummy[3] = {0,0,0};
    double tmpCoord[3];
    tmpCoord[0] = partCfg[i].r.p[0];
    tmpCoord[1] = partCfg[i].r.p[1];
    tmpCoord[2] = partCfg[i].r.p[2];
    if (flag == NONE)  {   // perform folding by particle
      fold_position(tmpCoord, dummy);
    }
    j = 3*partCfg[i].p.identity;
    coord[j    ] = tmpCoord[0];
    coord[j + 1] = tmpCoord[1];
    coord[j + 2] = tmpCoord[2];
  }


  // Use information from the analyse set command to fold chain molecules
  if ( flag == FOLD_CHAINS ){
    if(analyze_fold_molecules(coord, shift ) != TCL_OK){
      Tcl_AppendResult(interp, "could not fold chains: \"analyze set chains <chain_start> <n_chains> <chain_length>\" must be used first",
		       (char *) NULL);
      return (TCL_ERROR);   
    }
  }

 
  if (imd_send_fcoords(sock, n_part, coord)) {
    Tcl_AppendResult(interp, "could not write to IMD socket.",
		     (char *) NULL);
    return (TCL_ERROR);      
  }
  free(coord);
  
  Tcl_AppendResult(interp, "connected",
		   (char *) NULL);
  return (TCL_OK);
}
예제 #28
0
int calc_fluctuations ( double* height_grid, int switch_fluc ) {
  if (switch_fluc == 1){
    STAT_TRACE(fprintf(stderr,"%d,calculating height grid \n",this_node));
  } else { if (switch_fluc == 0) {
    STAT_TRACE(fprintf(stderr,"%d,calculating thickness \n",this_node));
    } else {
       char *errtxt = runtime_error(128);
       ERROR_SPRINTF(errtxt,"{097 Wrong argument in calc_fluctuations function} ");
       return -1;
    }
  }
    
  int i, j, gi, gj;
  double grid_size[2];
  double direction[3];  
  double refdir[3] = {0,0,1};
  double* height_grid_up;
  double* height_grid_down;
  int* grid_parts;
  int* grid_parts_up;
  int* grid_parts_down;
  double zreflocal, zref;
  int nup;
  int ndown;
  int nstray;
  int nrealstray;
  int l_orient;
  double norm;
  int xi, yi;
  double meanval;
  int nonzerocnt, gapcnt;






  if ( xdir + ydir + zdir == -3 ) {
      char *errtxt = runtime_error(128);
      ERROR_SPRINTF(errtxt,"{092 attempt to calculate height grid / thickness with uninitialized grid} ");
      return -1;
  }
  

  if ( height_grid == NULL ) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{093 you must allocate memory for the height grid / thickness first} ");
    return -1;
  }



  /* Allocate memory for height grid / thickness arrays and initialize these arrays */

  height_grid_up = (double*) malloc((mode_grid_3d[xdir])*sizeof(double)*mode_grid_3d[ydir]);
  height_grid_down = (double*) malloc((mode_grid_3d[xdir])*sizeof(double)*mode_grid_3d[ydir]);
  grid_parts_up = (int*) malloc((mode_grid_3d[xdir])*sizeof(int)*mode_grid_3d[ydir]);
  grid_parts_down = (int*) malloc((mode_grid_3d[xdir])*sizeof(int)*mode_grid_3d[ydir]);
  grid_parts = (int*) malloc((mode_grid_3d[xdir])*sizeof(int)*mode_grid_3d[ydir]);
  for ( i = 0 ; i < mode_grid_3d[xdir] ; i++) {
    for ( j = 0 ; j < mode_grid_3d[ydir] ; j++) {
      height_grid[j+i*mode_grid_3d[xdir]] = 0;
      grid_parts[j+i*mode_grid_3d[xdir]] = 0;
      height_grid_up[j+i*mode_grid_3d[xdir]] = 0;
      grid_parts_up[j+i*mode_grid_3d[xdir]] = 0;
      height_grid_down[j+i*mode_grid_3d[xdir]] = 0;
      grid_parts_down[j+i*mode_grid_3d[xdir]] = 0;
    }
  }
  
  /* Calculate physical size of grid mesh */
  grid_size[xdir] = box_l[xdir]/(double)mode_grid_3d[xdir];
  grid_size[ydir] = box_l[ydir]/(double)mode_grid_3d[ydir];
  
  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  //Make sure particles are sorted
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} ");
    return -1;
  }
  
  
  
  /* Find the mean z position of folded coordinates*/ 
  zref = calc_zref( zdir );
  
  /* Calculate an initial height function of all particles */
  for (i = 0 ; i < n_total_particles ; i++) {
    gi = floor( partCfg[i].r.p[xdir]/grid_size[xdir] );
    gj = floor( partCfg[i].r.p[ydir]/grid_size[ydir] );
    height_grid[gj + gi*mode_grid_3d[xdir]] += partCfg[i].r.p[zdir];
    grid_parts[gj + gi*mode_grid_3d[xdir]] += 1;
  }
  
  /* Normalise the initial height function */
  for ( i = 0 ; i < mode_grid_3d[xdir] ; i++) {
    for ( j = 0 ; j < mode_grid_3d[ydir] ; j++) {
      if ( grid_parts[j+i*mode_grid_3d[xdir]] > 0 ) {
	height_grid[j+i*mode_grid_3d[xdir]] = height_grid[j+i*mode_grid_3d[xdir]]/(double)(grid_parts[j+i*mode_grid_3d[xdir]]);
      } else {
	height_grid[j+i*mode_grid_3d[xdir]] = zref;
      }
    }
  }
  
  /* We now use this initial height function to calculate the
     lipid_orientation and thereby calculate populations in upper and
     lower leaflets */
  
  
  /* Calculate the non normalized height function based on all lipids */
  nup = ndown = nstray = nrealstray = 0;
  for (i = 0 ; i < n_total_particles ; i++) {
    gi = floor( partCfg[i].r.p[xdir]/grid_size[xdir] );
    gj = floor( partCfg[i].r.p[ydir]/grid_size[ydir] );
    
    zreflocal = height_grid[gj+gi*mode_grid_3d[xdir]];
    
    l_orient = lipid_orientation(i,partCfg,zreflocal,direction,refdir);
    
    if ( l_orient != LIPID_STRAY && l_orient != REAL_LIPID_STRAY) {
      if ( l_orient == LIPID_UP ) {
	nup++;
	height_grid_up[gj + gi*mode_grid_3d[xdir]] += partCfg[i].r.p[zdir] - zref;
	grid_parts_up[gj + gi*mode_grid_3d[xdir]] += 1;
      } else if ( l_orient == LIPID_DOWN ) {
	ndown++;
	height_grid_down[gj + gi*mode_grid_3d[xdir]] += partCfg[i].r.p[zdir] - zref;
	grid_parts_down[gj + gi*mode_grid_3d[xdir]] += 1;
      }
    } else {
      if ( l_orient == REAL_LIPID_STRAY ) {
	nrealstray++;
      }
    }
  }



  /*
    if ( nrealstray > 0 || nstray > 0) {
    printf("Warning: there were %d stray lipid particles in height calculation \n", nrealstray);
    }
    printf(" Lipid particles up = %d , Lipid particles down = %d \n",nup, ndown); */
  
  STAT_TRACE(fprintf(stderr,"%d, Lipids up = %d , Lipids down = %d \n",this_node, nup, ndown));
  
  /* Reinitialise the height grid */
  for ( i = 0 ; i < mode_grid_3d[xdir] ; i++) {
    for ( j = 0 ; j < mode_grid_3d[ydir] ; j++) {
      height_grid[j+i*mode_grid_3d[xdir]] = 0.0;
      grid_parts[j+i*mode_grid_3d[xdir]] = 0;
    }
  }
  
  /* Norm we normalize the height function according the number of
     points in each grid cell */
  norm = 1.0;
  for ( i = 0 ; i < mode_grid_3d[xdir] ; i++) {
    for ( j = 0 ; j < mode_grid_3d[ydir] ; j++) {
      
      if ( ( grid_parts_up[j + i*mode_grid_3d[xdir]] > 0 ) && ( grid_parts_down[j + i*mode_grid_3d[xdir]] > 0 ) ) {
	/* 
	   This is where we distinguish between height_grid and thickness:
	   h = .5*(h_up + h_down)
	   t = h_up - h_down
	*/
	if (switch_fluc == 1)
	  height_grid[j+i*mode_grid_3d[xdir]] = 
	    0.5*norm*((height_grid_up[j+i*mode_grid_3d[xdir]])/(double)(grid_parts_up[j + i*mode_grid_3d[xdir]]) + 
		      (height_grid_down[j+i*mode_grid_3d[xdir]])/(double)(grid_parts_down[j + i*mode_grid_3d[xdir]]));
	else
	  height_grid[j+i*mode_grid_3d[xdir]] = 
	    norm*((height_grid_up[j+i*mode_grid_3d[xdir]])/(double)(grid_parts_up[j + i*mode_grid_3d[xdir]]) - 
		  (height_grid_down[j+i*mode_grid_3d[xdir]])/(double)(grid_parts_down[j + i*mode_grid_3d[xdir]]));

	grid_parts[j+i*mode_grid_3d[xdir]] = grid_parts_up[j + i*mode_grid_3d[xdir]] + grid_parts_down[j + i*mode_grid_3d[xdir]];
      } else {
	// Either upper or lower layer has no lipids
	
	

	height_grid[j+i*mode_grid_3d[xdir]] = 0.0;
	grid_parts[j+i*mode_grid_3d[xdir]] = 0;
      }
    }
  }
  
  
  /* Check height grid for zero values and substitute mean of surrounding cells */
  gapcnt = 0;
  for ( i = 0 ; i < mode_grid_3d[xdir] ; i++) {
    for ( j = 0 ; j < mode_grid_3d[ydir] ; j++) {
      if ( grid_parts[j + i*mode_grid_3d[xdir]] ==  0) {
	meanval = 0.0;
	nonzerocnt = 0;
	for ( xi = (i-1) ; xi <= (i+1) ; xi++) {
	  for ( yi = (j-1) ; yi <= (j+1) ; yi++) {
	    if ( height_grid[yi+xi*mode_grid_3d[xdir]] != 0 ) {
	      meanval += height_grid[yi+xi*mode_grid_3d[xdir]];
	      nonzerocnt++;
	    }
	  }
	}
	if ( nonzerocnt == 0 ) { 
	  char *errtxt = runtime_error(128);
	  ERROR_SPRINTF(errtxt,"{095 hole in membrane} ");
	  return -1;
	}
	gapcnt++;
      }      
    }
  }
  if ( gapcnt != 0 ) { 
    fprintf(stderr,"Warning: %d, gridpoints with no particles \n",gapcnt);
    fflush(stdout);
  }
  
  free(grid_parts);
  free(height_grid_up);
  free(height_grid_down);
  free(grid_parts_up);
  free(grid_parts_down);
  
  return 1;
  
}
예제 #29
0
int calc_cylindrical_average(std::vector<double> center, std::vector<double> direction, double length,
                             double radius, int bins_axial, int bins_radial, std::vector<int> types,
                             std::map<std::string, std::vector<std::vector<std::vector<double> > > > &distribution)
{
  int index_axial;
  int index_radial;
  double binwd_axial  = length / bins_axial;
  double binwd_radial = radius / bins_radial;

  // Select all particle types if the only entry in types is -1
  bool all_types = false;
  if (types.size() == 1 && types[0] == -1) all_types = true;

  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("density",   std::vector<std::vector<std::vector<double> > >(types.size())) );
  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("v_r",       std::vector<std::vector<std::vector<double> > >(types.size())) );
  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("v_t",       std::vector<std::vector<std::vector<double> > >(types.size())) );

  for (unsigned int type = 0; type < types.size(); type++) {
    distribution["density"][type].resize(bins_radial);
        distribution["v_r"][type].resize(bins_radial);
        distribution["v_t"][type].resize(bins_radial);
    for (int index_radial = 0; index_radial < bins_radial; index_radial++) {
      distribution["density"][type][index_radial].assign(bins_axial, 0.0);
          distribution["v_r"][type][index_radial].assign(bins_axial, 0.0);
          distribution["v_t"][type][index_radial].assign(bins_axial, 0.0);
    }
  }

  // Update particles
  updatePartCfg(WITHOUT_BONDS);

  // Make sure particles are folded
  for (int i = 0 ; i < n_part ; i++) {
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,0);
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,1);
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,2);
  }

  // Declare variables for the density calculation
  double height, dist, v_radial, v_axial;
  double norm_direction = utils::veclen(direction);
  std::vector<double> pos(3), vel(3), diff, hat;

  for (int part_id = 0; part_id < n_part; part_id++) {
    for (unsigned int type_id = 0; type_id < types.size(); type_id++) {
      if ( types[type_id] == partCfg[part_id].p.type || all_types) {
        pos[0] = partCfg[part_id].r.p[0];
        pos[1] = partCfg[part_id].r.p[1];
        pos[2] = partCfg[part_id].r.p[2];
        vel[0] = partCfg[part_id].m.v[0];
        vel[1] = partCfg[part_id].m.v[1];
        vel[2] = partCfg[part_id].m.v[2];

        // Find the vector from center to the current particle
        diff = utils::vecsub(pos,center);

        // Find the height of the particle above the axis (height) and
        // the distance from the center point (dist)
        hat    = utils::cross_product(direction,diff);
        height = utils::veclen(hat);
        dist   = utils::dot_product(direction,diff) / norm_direction;

        // Determine the components of the velocity parallel and
        // perpendicular to the direction vector
        if ( height == 0 )
          v_radial = utils::veclen(utils::cross_product(vel,direction)) / norm_direction;
        else
          v_radial = utils::dot_product(vel,hat) / height;
        v_axial  = utils::dot_product(vel,direction) / norm_direction;
        
        // Work out relevant indices for x and y
        index_radial = static_cast<int>( floor(height / binwd_radial) );
        index_axial  = static_cast<int>( floor((dist + 0.5*length) / binwd_axial) );

        if ( (index_radial < bins_radial && index_radial >= 0) &&
             (index_axial  < bins_axial  && index_axial  >= 0) ) {
          distribution["density"][type_id][index_radial][index_axial] += 1;
          distribution["v_r"][type_id][index_radial][index_axial] += v_radial;
          distribution["v_t"][type_id][index_radial][index_axial] += v_axial;
        }
      }
    }
  }

  // Now we turn the counts into densities by dividing by one radial
  // bin (binvolume).  We also divide the velocites by the counts.
  double binvolume;
  for (unsigned int type_id = 0; type_id < types.size(); type_id++) {
    for (int index_radial = 0 ; index_radial < bins_radial ; index_radial++) {
      // All bins are cylindrical shells of thickness binwd_radial.
      // The volume is thus: binvolume = pi*(r_outer - r_inner)^2 * length
      if ( index_radial == 0 )
        binvolume = M_PI * binwd_radial*binwd_radial * length;
      else
        binvolume = M_PI * (index_radial*index_radial + 2*index_radial) * binwd_radial*binwd_radial * length;
      for (int index_axial = 0 ; index_axial < bins_axial ; index_axial++) {
        if ( distribution["density"][type_id][index_radial][index_axial] != 0 ) {
          distribution["v_r"][type_id][index_radial][index_axial] /= distribution["density"][type_id][index_radial][index_axial];
          distribution["v_t"][type_id][index_radial][index_axial] /= distribution["density"][type_id][index_radial][index_axial];
          distribution["density"][type_id][index_radial][index_axial] /= binvolume;
        }
      }
    }
  }

  return ES_OK;
}
int tclcommand_analyze_parse_and_print_dipmom_mol(Tcl_Interp *interp,int argc, char **argv)
{
#ifndef ELECTROSTATICS
   Tcl_ResetResult(interp);
   Tcl_AppendResult(interp, "calc_dipole_mol is not possible without ELECTROSTATICS", (char *)NULL);
   return (TCL_ERROR);
#else
   int k,type;
   char buffer[TCL_DOUBLE_SPACE];
   double dipole[4];
   updatePartCfg(WITHOUT_BONDS);
   if (!sortPartCfg()) {
      char *errtxt = runtime_error(128);
      ERROR_SPRINTF(errtxt, "{059 parse_and_print_dipole: could not sort particle config, particle ids not consecutive?} ");
      return TCL_ERROR;
   }
   if (n_molecules==0) {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "No molecules defined !", (char *)NULL);
      return (TCL_ERROR);
   }
   if (argc < 2) {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "usage: analyze parse_and_print_dipole_mol <type>", (char *)NULL);
      return (TCL_ERROR);
   }

   if (!ARG1_IS_I(type)) {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "usage: analyze parse_and_print_dipole_mol <type>", (char *)NULL);
      return (TCL_ERROR);
   }
   if (ARG0_IS_S("total")){
      calc_total_dipolmoment_mol(type,dipole);
      sprintf(buffer,"%i ",type);
      Tcl_AppendResult(interp,"{ dipolemoment_mol total ",buffer,(char *)NULL);
      for (k=0;k<3;k++)
      {
            sprintf(buffer,"%e ",dipole[k]);
            Tcl_AppendResult(interp, buffer,(char *)NULL);
      }
      sprintf(buffer,"%e",dipole[3]);
      Tcl_AppendResult(interp,buffer,"}",(char *)NULL);
   }
   else if (ARG0_IS_S("absolute")){
      calc_absolute_dipolmoment_mol(type,dipole);
      sprintf(buffer,"%i ",type);
      Tcl_AppendResult(interp,"{ dipolemoment_mol absolute ",buffer,(char *)NULL);
      sprintf(buffer,"%e ",dipole[0]);
      Tcl_AppendResult(interp, buffer,(char *)NULL);
      sprintf(buffer,"%e",dipole[1]);
      Tcl_AppendResult(interp,buffer,"}",(char *)NULL);
   }
   else
   {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "Feature not implemented", (char *)NULL);
      return (TCL_ERROR);
   }
   argc-=2; argv+=2;
   return TCL_OK;
#endif
}