Пример #1
0
void analyze_activate(int ind) {
  int i;
  double pos[3];
  n_part_conf = n_part;

  for(i=0; i<n_part_conf; i++) {
    pos[0] = configs[ind][3*i];
    pos[1] = configs[ind][3*i+1];
    pos[2] = configs[ind][3*i+2];
    if (place_particle(i, pos)==ES_ERROR) {
        runtimeErrorMsg() <<"failed upon replacing particle " << i << "  in Espresso";
    }
  }
}
Пример #2
0
void analyze_activate(int ind) {
  int i;
  double pos[3];
  n_part_conf = n_part;

  for(i=0; i<n_part_conf; i++) {
    pos[0] = configs[ind][3*i];
    pos[1] = configs[ind][3*i+1];
    pos[2] = configs[ind][3*i+2];
    if (place_particle(i, pos)==ES_ERROR) {
      char *errtxt = runtime_error(128 + ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt, "{057 failed upon replacing particle %d in Espresso} ", i); 
    }
  }
}
Пример #3
0
int counterionsC(int N_CI, int part_id, int mode, double shield, int max_try, double val_CI, int type_CI) {
  int n, cnt1,max_cnt;
  double pos[3];

  cnt1 = max_cnt = 0;
  for (n=0; n<N_CI; n++) {
    for (cnt1=0; cnt1<max_try; cnt1++) {
      pos[0]=box_l[0]*d_random();
      pos[1]=box_l[1]*d_random();
      pos[2]=box_l[2]*d_random();
      if ((mode!=0) || (collision(pos, shield, 0, NULL)==0)) break;
      POLY_TRACE(printf("c"); fflush(NULL));
    }
    if (cnt1 >= max_try) return (-1);
    if (place_particle(part_id, pos)==ES_PART_ERROR) return (-3);
    if (set_particle_q(part_id, val_CI)==ES_ERROR) return (-3);
    if (set_particle_type(part_id, type_CI)==ES_ERROR) return (-3);
    part_id++; max_cnt=imax(cnt1, max_cnt);
    POLY_TRACE(printf("C"); fflush(NULL));
  }
  POLY_TRACE(printf(" %d->%d \n",cnt1,max_cnt));
  if (cnt1 >= max_try) return(-1);
  return(imax(max_cnt,cnt1));
}
Пример #4
0
// Handle the collisions stored in the queue
void handle_collisions ()
{
  // If we don't have virtual_sites_relative, only bonds between centers of 
  // colliding particles are possible and nothing is to be done here
#ifdef VIRTUAL_SITES_RELATIVE
  // Does the user want bonds between virtual sites placed at the point of collision
  if (collision_detection_mode==2)
    {

      //	printf("number of collisions in handle collision are %d\n",number_of_collisions);  
      int bondG[3], i;

      if (number_of_collisions > 0) {
	// Go through the queue
	for (i=0;i<number_of_collisions;i++) {
	  //  printf("Handling collision of particles %d %d\n", collision_queue[i].pp1, collision_queue[i].pp2);
	  //  fflush(stdout);
   

	  // The following lines will remove the relative velocity from
	  // colliding particles
	  //   double v[3];
	  //   for (j=0;j<3;j++)
	  //   {
	  //    v[j] =0.5 *((local_particles[collision_queue[i].pp1])->m.v[j] +(local_particles[collision_queue[i].pp2])->m.v[j]);
	  //    (local_particles[collision_queue[i].pp1])->m.v[j] =v[j];
	  //    (local_particles[collision_queue[i].pp2])->m.v[j] =v[j];
	  //   }

	  // Create virtual sites and bind them together
  
	  // Virtual site related to first particle in the collision
	  place_particle(max_seen_particle+1,collision_queue[i].point_of_collision);
	  vs_relate_to(max_seen_particle,collision_queue[i].pp1);
	  (local_particles[max_seen_particle])->p.isVirtual=1;
	  (local_particles[max_seen_particle])->p.type=collision_vs_particle_type;
  
	  // Virtual particle related to 2nd particle of the collision
	  place_particle(max_seen_particle+1,collision_queue[i].point_of_collision);
	  vs_relate_to(max_seen_particle,collision_queue[i].pp2);
	  (local_particles[max_seen_particle])->p.isVirtual=1;
	  (local_particles[max_seen_particle])->p.type=collision_vs_particle_type;
  
          switch (bonded_ia_params[collision_detection_bond_vs].num) {
	  case 1: {
	    // Create bond between the virtual particles
	    bondG[0] = collision_detection_bond_vs;
	    bondG[1] = max_seen_particle-1;
	    local_change_bond(max_seen_particle, bondG, 0);
            break;
          }
	  case 2: {
	    // Create 1st bond between the virtual particles
	    bondG[0] = collision_detection_bond_vs;
	    bondG[1] = collision_queue[i].pp1;
	    bondG[2] = collision_queue[i].pp2;
	    local_change_bond(max_seen_particle,   bondG, 0);
	    local_change_bond(max_seen_particle-1, bondG, 0);
	    break;
          }
          }
	}

      }

    }
#endif

  // Reset the collision queue	 
  number_of_collisions = 0;
  free(collision_queue);

}
Пример #5
0
int tclcommand_readmd(ClientData dummy, Tcl_Interp *interp,
	   int argc, char **argv)
{
  char *row;
  int pos_row[3] = { -1 }, v_row[3] = { -1 }, 
  #ifdef DIPOLES 
  dip_row[3] = { -1 }, 
  #endif
  f_row[3] = { -1 };
  
  int av_pos = 0, av_v = 0, 
#ifdef DIPOLES 
    av_dip=0, 
#endif
#ifdef MASS
    av_mass=0,
#endif
#ifdef SHANCHEN
    av_solvation=0,
#endif
    av_f = 0,
#ifdef ELECTROSTATICS
    av_q = 0,
#endif
    av_type = 0;
  
  int node, i;
  struct MDHeader header;
  Particle data;
  int tcl_file_mode;
  Tcl_Channel channel;

  if (argc != 2) {
    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		     argv[0], " <file>\"",
		     (char *) NULL);
    return (TCL_ERROR);
  }

  if ((channel = Tcl_GetChannel(interp, argv[1], &tcl_file_mode)) == NULL)
    return (TCL_ERROR);

  /* tune channel to binary translation, e.g. none */
  Tcl_SetChannelOption(interp, channel, "-translation", "binary");

  Tcl_Read(channel, (char *)&header, sizeof(header));
  /* check token */
  if (strncmp(header.magic, MDMAGIC, 4) || header.n_rows < 0) {
    Tcl_AppendResult(interp, "data file \"", argv[1],
		     "\" does not contain tcl MD data",
		     (char *) NULL);
    return (TCL_ERROR);
  }

  if (!particle_node)
    build_particle_node();

  /* parse rows */
  row = (char*)malloc(header.n_rows*sizeof(char));
  for (i = 0; i < header.n_rows; i++) {
    Tcl_Read(channel, (char *)&row[i], sizeof(char));
    switch (row[i]) {
    case POSX: pos_row[0] = i; break;
    case POSY: pos_row[1] = i; break;
    case POSZ: pos_row[2] = i; break;
    case   VX:   v_row[0] = i; break;
    case   VY:   v_row[1] = i; break;
    case   VZ:   v_row[2] = i; break;
#ifdef DIPOLES
    case   MX:   dip_row[0] = i; break;
    case   MY:   dip_row[1] = i; break;
    case   MZ:   dip_row[2] = i; break;
#endif
    case   FX:   f_row[0] = i; break;
    case   FY:   f_row[1] = i; break;
    case   FZ:   f_row[2] = i; break;
#ifdef MASS
    case MASSES: av_mass  = 1; break;
#endif
#ifdef SHANCHEN
    case SOLVATION: av_solvation = 1; break;
#endif
#ifdef ELECTROSTATICS
    case    Q:   av_q     = 1; break;
#endif
    case TYPE:   av_type  = 1; break;
    }
  }

  /* *_row[0] tells if * data is completely available -
   * otherwise we ignore it */
  if (pos_row[0] != -1 && pos_row[1] != -1 && pos_row[2] != -1) {
    av_pos = 1;
  }
  if (v_row[0] != -1 && v_row[1] != -1 && v_row[2] != -1) {
    av_v = 1;
  }
  if (f_row[0] != -1 && f_row[1] != -1 && f_row[2] != -1) {
    av_f = 1;
  }
  
  #ifdef DIPOLES
  if (dip_row[0] != -1 && dip_row[1] != -1 && dip_row[2] != -1) {
    av_dip = 1;
  }
  #endif


  while (!Tcl_Eof(channel)) {
    Tcl_Read(channel, (char *)&data.p.identity, sizeof(int));
    if (data.p.identity == -1)
      break;

    /* printf("id=%d\n", data.identity); */

    if (data.p.identity < 0) {
      Tcl_AppendResult(interp, "illegal data format in data file \"", argv[1],
		       "\", perhaps wrong file?",
		       (char *) NULL);
      free(row);
      return (TCL_ERROR);
    }

    for (i = 0; i < header.n_rows; i++) {
      switch (row[i]) {
      case POSX: Tcl_Read(channel, (char *)&data.r.p[0], sizeof(double)); break;
      case POSY: Tcl_Read(channel, (char *)&data.r.p[1], sizeof(double)); break;
      case POSZ: Tcl_Read(channel, (char *)&data.r.p[2], sizeof(double)); break;
      case   VX: Tcl_Read(channel, (char *)&data.m.v[0], sizeof(double)); break;
      case   VY: Tcl_Read(channel, (char *)&data.m.v[1], sizeof(double)); break;
      case   VZ: Tcl_Read(channel, (char *)&data.m.v[2], sizeof(double)); break;
      case   FX: Tcl_Read(channel, (char *)&data.f.f[0], sizeof(double)); break;
      case   FY: Tcl_Read(channel, (char *)&data.f.f[1], sizeof(double)); break;
      case   FZ: Tcl_Read(channel, (char *)&data.f.f[2], sizeof(double)); break;
      case MASSES:
#ifdef MASS
          Tcl_Read(channel, (char *)&data.p.mass, sizeof(double)); break;
#else
          {
              double dummy_mass;
              Tcl_Read(channel, (char *)&dummy_mass, sizeof(double)); break;
          }
#endif
#ifdef ELECTROSTATICS
      case    Q: Tcl_Read(channel, (char *)&data.p.q, sizeof(double)); break;
#endif
#ifdef DIPOLES
      case   MX: Tcl_Read(channel, (char *)&data.r.dip[0], sizeof(double)); break;
      case   MY: Tcl_Read(channel, (char *)&data.r.dip[1], sizeof(double)); break;
      case   MZ: Tcl_Read(channel, (char *)&data.r.dip[2], sizeof(double)); break;
#endif

      case TYPE: Tcl_Read(channel, (char *)&data.p.type, sizeof(int)); break;
      }
    }

    node = (data.p.identity <= max_seen_particle) ? particle_node[data.p.identity] : -1;
    if (node == -1) {
      if (!av_pos) {
	Tcl_AppendResult(interp, "new particle without position data",
			 (char *) NULL);
	free(row);
	return (TCL_ERROR);
      }
    }

    if (av_pos)
      place_particle(data.p.identity, data.r.p);
#ifdef MASS
    if (av_mass)
      set_particle_mass(data.p.identity, data.p.mass);
#endif
#ifdef SHANCHEN
    if (av_solvation)
      set_particle_solvation(data.p.identity, data.p.solvation);
#endif
#ifdef ELECTROSTATICS
    if (av_q)
      set_particle_q(data.p.identity, data.p.q);
#endif
#ifdef DIPOLES
    if (av_dip)
      set_particle_dip(data.p.identity, data.r.dip);
#endif
    if (av_v)
      set_particle_v(data.p.identity, data.m.v);
    if (av_f)
      set_particle_f(data.p.identity, data.f.f);
    if (av_type)
      set_particle_type(data.p.identity, data.p.type);
  }

  free(row);
  return TCL_OK;
}
Пример #6
0
int saltC(int N_pS, int N_nS, int part_id, int mode, double shield, int max_try, double val_pS, double val_nS, int type_pS, int type_nS, double rad) {
  int n, cnt1,max_cnt;
  double pos[3], dis2;

  cnt1 = max_cnt = 0;

  /* Place positive salt ions */
  for (n=0; n<N_pS; n++) {
    for (cnt1=0; cnt1<max_try; cnt1++) {
      if (rad > 0.) {
        pos[0]=rad*(2.*d_random()-1.);
        pos[1]=rad*(2.*d_random()-1.);
        pos[2]=rad*(2.*d_random()-1.);
        dis2 = pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2];
        pos[0] += box_l[0]*0.5;
        pos[1] += box_l[1]*0.5;
        pos[2] += box_l[2]*0.5;
        if (((mode!=0) || (collision(pos, shield, 0, NULL)==0)) && (dis2 < (rad * rad))) break;
      } else {
        pos[0]=box_l[0]*d_random();
        pos[1]=box_l[1]*d_random();
        pos[2]=box_l[2]*d_random();
        if ((mode!=0) || (collision(pos, shield, 0, NULL)==0)) break;
      }
      POLY_TRACE(printf("p"); fflush(NULL));
    }
    if (cnt1 >= max_try) return (-1);
    if (place_particle(part_id, pos)==ES_PART_ERROR) return (-3);
    if (set_particle_q(part_id, val_pS)==ES_ERROR) return (-3);
    if (set_particle_type(part_id, type_pS)==ES_ERROR) return (-3);
    part_id++; max_cnt=imax(cnt1, max_cnt);
    POLY_TRACE(printf("P"); fflush(NULL));
  }
  POLY_TRACE(printf(" %d->%d \n",cnt1,max_cnt));
  if (cnt1 >= max_try) return(-1);

  /* Place negative salt ions */
  for (n=0; n<N_nS; n++) {
    for (cnt1=0; cnt1<max_try; cnt1++) {
      if (rad > 0.) {
        pos[0]=rad*(2.*d_random()-1.);
        pos[1]=rad*(2.*d_random()-1.);
        pos[2]=rad*(2.*d_random()-1.);
        dis2 = pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2];
        pos[0] += box_l[0]*0.5;
        pos[1] += box_l[1]*0.5;
        pos[2] += box_l[2]*0.5;
        if (((mode!=0) || (collision(pos, shield, 0, NULL)==0)) && (dis2 < (rad * rad))) break;
      } else {
        pos[0]=box_l[0]*d_random();
        pos[1]=box_l[1]*d_random();
        pos[2]=box_l[2]*d_random();
        if ((mode!=0) || (collision(pos, shield, 0, NULL)==0)) break;
      }
      POLY_TRACE(printf("n"); fflush(NULL));
    }
    if (cnt1 >= max_try) return (-1);
    if (place_particle(part_id, pos)==ES_PART_ERROR) return (-3);
    if (set_particle_q(part_id, val_nS)==ES_ERROR) return (-3);
    if (set_particle_type(part_id, type_nS)==ES_ERROR) return (-3);
    part_id++; max_cnt=imax(cnt1, max_cnt);
    POLY_TRACE(printf("N"); fflush(NULL));
  }
  POLY_TRACE(printf(" %d->%d \n",cnt1,max_cnt));
  if (cnt1 >= max_try) return(-2);
  return(imax(max_cnt,cnt1));
}
Пример #7
0
int polymerC(int N_P, int MPC, double bond_length, int part_id, double *posed, 
	     int mode, double shield, int max_try, double val_cM, int cM_dist, 
	     int type_nM, int type_cM, int type_bond, 
	     double angle, double angle2, double *posed2, int constr) {
  int p,n, cnt1,cnt2,max_cnt, bond_size, *bond, i;
  double phi,zz,rr;
  double *poly;
  double pos[3];
  double poz[3];
  double poy[3] = {0, 0, 0};
  double pox[3] = {0, 0, 0};
  double a[3] = {0, 0, 0};
  double b[3],c[3]={0., 0., 0.},d[3];
  double absc;
  poly = (double*)malloc(3*MPC*sizeof(double));

  bond_size = bonded_ia_params[type_bond].num;
  bond = (int*)malloc(sizeof(int) * (bond_size + 1));
  bond[0] = type_bond;

  cnt1 = cnt2 = max_cnt = 0;
  for (p=0; p < N_P; p++) {
    for (cnt2=0; cnt2 < max_try; cnt2++) {
      /* place start monomer */
      if (posed!=NULL) {
	/* if position of 1st monomer is given */
	if (p > 0) {
	  free(posed);
	  posed=NULL;
	} else {
	  pos[0]=posed[0];
	  pos[1]=posed[1];
	  pos[2]=posed[2];
	}
      } else {
	/* randomly set position */
	for (cnt1=0; cnt1<max_try; cnt1++) {
	  pos[0]=box_l[0]*d_random();
	  pos[1]=box_l[1]*d_random();
	  pos[2]=box_l[2]*d_random();
	  if ((mode==1) || (collision(pos, shield, 0, NULL)==0)) break;
	  POLY_TRACE(printf("s"); fflush(NULL));
	}
	if (cnt1 >= max_try) { free(poly); return (-1); }
      }
      poly[0] = pos[0]; poly[1] = pos[1]; poly[2] = pos[2];
      max_cnt=imax(cnt1, max_cnt);
      POLY_TRACE(printf("S"); fflush(NULL));
      //POLY_TRACE(/* printf("placed Monomer 0 at (%f,%f,%f)\n",pos[0],pos[1],pos[2]) */);

      poz[0]=pos[0]; poz[1]=pos[1]; poz[2]=pos[2];

      /* place 2nd monomer */
      n=1;
      if (posed2 != NULL && posed != NULL && angle2 > -1.0) {
	/* if position of 2nd monomer is given */
	pos[0]=posed2[0];
	pos[1]=posed2[1];
	pos[2]=posed2[2];
	/* calculate preceding monomer so that bond_length is correct */
	absc=sqrt(SQR(pos[0]-poz[0])+SQR(pos[1]-poz[1])+SQR(pos[2]-poz[2]));
	poz[0]=pos[0]+(poz[0]-pos[0])*bond_length/absc;
	poz[1]=pos[1]+(poz[1]-pos[1])*bond_length/absc;
	poz[2]=pos[2]+(poz[2]-pos[2])*bond_length/absc;
	//POLY_TRACE(/* printf("virtually shifted position of first monomer to (%f,%f,%f)\n",poz[0],poz[1],poz[2]) */);
      } else {
	/* randomly place 2nd monomer */
	for (cnt1=0; cnt1<max_try; cnt1++) {
	  zz     = (2.0*d_random()-1.0)*bond_length;
          rr     = sqrt(SQR(bond_length)-SQR(zz));
	  phi    = 2.0*PI*d_random();
	  pos[0] = poz[0]+rr*cos(phi);
	  pos[1] = poz[1]+rr*sin(phi);
	  pos[2] = poz[2]+zz;
#ifdef CONSTRAINTS
	  if(constr==0 || constraint_collision(pos,poly+3*(n-1))==0){
#endif

	    if (mode==1 || collision(pos, shield, n, poly)==0) break;
	    if (mode==0) { cnt1 = -1; break; }
#ifdef CONSTRAINTS
	  }
#endif
	  POLY_TRACE(printf("m"); fflush(NULL));
	}
	if (cnt1 >= max_try) {
	  fprintf(stderr,"\nWarning! Attempt #%d to build polymer %d failed while placing monomer 2!\n",cnt2+1,p);
	  fprintf(stderr,"         Retrying by re-setting the start-monomer of current chain...\n");
	}
	if (cnt1 == -1 || cnt1 >= max_try) {
	  continue; /* continue the main loop */
	}
      }
      if(posed2!=NULL && p>0) {
	free(posed2);
	posed2=NULL;
      }
      poly[3*n] = pos[0]; poly[3*n+1] = pos[1]; poly[3*n+2] = pos[2];
      max_cnt=imax(cnt1, max_cnt);
      POLY_TRACE(printf("M"); fflush(NULL));
      //POLY_TRACE(/* printf("placed Monomer 1 at (%f,%f,%f)\n",pos[0],pos[1],pos[2]) */);
      
      /* place remaining monomers */
      for (n=2; n<MPC; n++) { 
	if (angle2 > -1.0) {
	  if(n==2) { /* if the 2nd angle is set, construct preceding monomer 
		       with resulting plane perpendicular on the xy-plane */
	    poy[0]=2*poz[0]-pos[0];
	    poy[1]=2*poz[1]-pos[1];
	    if(pos[2]==poz[2])
	      poy[2]=poz[2]+1;
	    else
	      poy[2]=poz[2];
	  } else { 
	    /* save 3rd last monomer */
	    pox[0]=poy[0]; pox[1]=poy[1]; pox[2]=poy[2]; 
	  }
	}
	if (angle > -1.0) { 
	  /* save one but last monomer */
	  poy[0]=poz[0]; poy[1]=poz[1]; poy[2]=poz[2]; 
	}
	/* save last monomer */
	poz[0]=pos[0]; poz[1]=pos[1]; poz[2]=pos[2];

	if(angle > -1.0){
	  a[0]=poy[0]-poz[0];
	  a[1]=poy[1]-poz[1];
	  a[2]=poy[2]-poz[2];

	  b[0]=pox[0]-poy[0];
	  b[1]=pox[1]-poy[1];
	  b[2]=pox[2]-poy[2];

	  vector_product(a,b,c);	  
	}

	for (cnt1=0; cnt1<max_try; cnt1++) {
	  if(angle > -1.0) {
	    if (sqrlen(c) < ROUND_ERROR_PREC) {
	      fprintf(stderr, "WARNING: rotation axis is 0,0,0, check the angles given to the polymer command\n");
	      c[0] = 1; c[1] = 0; c[2] = 0;
	    }
	    if(angle2 > -1.0 && n>2) {
	      vec_rotate(a,angle2,c,d);
	    } else {
	      phi = 2.0*PI*d_random();
	      vec_rotate(a,phi,c,d);
	    }

	    vec_rotate(d,angle,a,b);

	    pos[0] = poz[0] + b[0];
	    pos[1] = poz[1] + b[1];
	    pos[2] = poz[2] + b[2];

	  } else {
            zz     = (2.0*d_random()-1.0)*bond_length;
            rr     = sqrt(SQR(bond_length)-SQR(zz));
            phi    = 2.0*PI*d_random();
            pos[0] = poz[0]+rr*cos(phi);
            pos[1] = poz[1]+rr*sin(phi);
            pos[2] = poz[2]+zz;
	  }
	  
	  //POLY_TRACE(/* printf("a=(%f,%f,%f) absa=%f M=(%f,%f,%f) c=(%f,%f,%f) absMc=%f a*c=%f)\n",a[0],a[1],a[2],sqrt(SQR(a[0])+SQR(a[1])+SQR(a[2])),M[0],M[1],M[2],c[0],c[1],c[2],sqrt(SQR(M[0]+c[0])+SQR(M[1]+c[1])+SQR(M[2]+c[2])),a[0]*c[0]+a[1]*c[1]+a[2]*c[2]) */);
	  //POLY_TRACE(/* printf("placed Monomer %d at (%f,%f,%f)\n",n,pos[0],pos[1],pos[2]) */);

#ifdef CONSTRAINTS
	  if(constr==0 || constraint_collision(pos,poly+3*(n-1))==0){
#endif
	    if (mode==1 || collision(pos, shield, n, poly)==0) break;
	    if (mode==0) { cnt1 = -2; break; }
#ifdef CONSTRAINTS
	  }
#endif
	  POLY_TRACE(printf("m"); fflush(NULL));
	}
	if (cnt1 >= max_try) {
	  fprintf(stderr,"\nWarning! Attempt #%d to build polymer %d failed after %d unsuccessful trials to place monomer %d!\n",cnt2+1,p,cnt1,n);
	  fprintf(stderr,"         Retrying by re-setting the start-monomer of current chain...\n");
	}
	if (cnt1 == -2 || cnt1 >= max_try) {
	  n=0; break;
	}
	poly[3*n] = pos[0]; poly[3*n+1] = pos[1]; poly[3*n+2] = pos[2];
	max_cnt=imax(cnt1, max_cnt);
	POLY_TRACE(printf("M"); fflush(NULL));
      }
      if (n>0) break;
    } /* cnt2 */
    POLY_TRACE(printf(" %d/%d->%d \n",cnt1,cnt2,max_cnt));
    if (cnt2 >= max_try) { free(poly); return(-2); } else max_cnt = imax(max_cnt,imax(cnt1,cnt2));

    /* actually creating current polymer in ESPResSo */
    for (n=0; n<MPC; n++) {
      
      pos[0] = poly[3*n]; pos[1] = poly[3*n+1]; pos[2] = poly[3*n+2];
      if (place_particle(part_id, pos)==ES_PART_ERROR ||
	  (set_particle_q(part_id, ((n % cM_dist==0) ? val_cM : 0.0) )==ES_ERROR) ||
	  (set_particle_type(part_id, ((n % cM_dist==0) ? type_cM : type_nM) )==ES_ERROR))
	{ free(poly); return (-3); }
      
      if(n>=bond_size){
	bond[1] = part_id - bond_size;
	for(i=2;i<=bond_size;i++){
	  bond[i] = part_id - bond_size + i;
	}
	if(change_particle_bond(part_id-bond_size+1, bond, 0)==ES_ERROR)
	  { free(poly); return (-3); }
      }
      part_id++;
      //POLY_TRACE(/* printf("placed Monomer %d at (%f,%f,%f)\n",n,pos[0],pos[1],pos[2]) */);
    }
  }
  free(poly);
  return(imax(max_cnt,cnt2));
}