void simulation(float mu, float koff){
	
	/*set up variables for RNG, generate seed that's time-dependent,
	 * seed RNG with that value - guarantees that MPI instances will
	 * actually be different from each other*/
	const gsl_rng_type * T;
	gsl_rng_env_setup();
	T = gsl_rng_default;
	gsl_rng *r;
	r = gsl_rng_alloc (T);
	unsigned long int seed;
	seed=gen_seed();
    gsl_rng_set(r,seed);
    
    
    /*old legacy stuff    
	//memset(lanes,0,NLANES*L*sizeof(int));
	//lanes[8][48]=22;
	//FILE *fp;*/
    
    /*define total time of simulation (in units of polymerizing events)*/
    int totaltime=500;
    
    
    /*define number of ends in the system, necessary for depol 
     * calculation and rates. Also, define a toggle for the first pol
     * event to reset*/
     int ends=0;
     int newends=0;
     int first=1;
	
	/*just declare a bunch of stuff that we will use*/
	float domega,kon;
	int accepted=0;
	int filaments,noconsts;
	int int_i;
	int j,k,size,currfils,currlen,gap,l,m;
	float i,p,coverage;
	int type=0;
	
	/*declare two matrices for the filaments per lane, one for the 
	 * "permanent" stuff and one for temporary testing in the 
	 * Metropolis scheme*/
	int lanes[NLANES][L]={{0}};
	int newlanes[NLANES][L]={{0}};
	
	/*two floats to store the time of the next polymerization and depol
	 * events, that will be initialized later*/
	float nexton=0;
	float nextoff=VERYBIG;
	
	/*declare three GMP arbitrary precision values: one for storing the
	 * current number of microstates, one for the new number when testing
	 * in the Metropolis scheme and one to store the difference*/
	mpz_t states;
	mpz_t newstates;
	mpz_t deltastates;
	mpz_init(states);
	mpz_init(newstates);
	mpz_init(deltastates);
	
	/*sets up: the value of the chemical potential of a monomer, the
	 * on-rate (we're always taking it to be one), the off-rate
	 * (defined in relation to the on-rate) and the average size of
	 * a new polymer*/
	kon=1;
	//float kon=1.0;
	//float koff=0.1; //try based on ends
	//printf("%f %f\n",kon,koff);
	int avg_size=3;
	p=1.0/avg_size;
	
	
	float inv_sites=1.0/(NLANES*(L-1));
	
	clock_t t1 = clock();
	
	/*sets up the I/O to a file - filename is dependent on MPI
	 * instance number to avoid conflicts*/
	char* filename[40];
	//int my_rank=0;
	int my_rank;
	MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
	sprintf(filename,"outputs_%1.1f_%1.1f/run%d.txt",mu,koff,my_rank);
	
	FILE *fp = fopen(filename, "w");
	//strcat(filename,threadnum);
	//strcat(filename,".txt");
	
	
	/*sets up the time for the first on event (first off only calculated
	 * after we have filaments!)*/	
    nexton=gsl_ran_exponential(r,1.0/kon);
	//nextoff=gsl_ran_exponential(r,1.0/koff);
	
	
	//printf("nexton=%f nexoff=%f, avg on=%f avg off=%f thread=%d\n",nexton,nextoff,1.0/kon,1.0/koff,omp_get_thread_num());
	
	/*start of the main loop*/
	for (i=0;i<totaltime;i=i+0.01){
		clock_t t2 = clock();
		//printf("thread=%d i=%f\n",omp_get_thread_num(),i);
		
		/*before anything else, make a copy of the current lanes into
		 * the matrix newlanes*/
		memcpy(newlanes,lanes,sizeof(lanes));
		newends=ends;
		
		/*calculate the current coverage (sites occupied divided by the 
		 * total number of sites) and output to file the current "time" 
		 * and coverage*/ 
		coverage=0;
		for (k=0;k<NLANES;k++){
			
			for (j=1;j<lanes[k][0]+1;j++){
				coverage=coverage+lanes[k][j];
			}
			
		}
		//printf("total length=%f\n",coverage);
		coverage=coverage*inv_sites;
		//printf("coverage=%f\n",coverage);
		fprintf(fp, "%f %f %f\n", i,coverage,ends,(double)(t2-t1)/CLOCKS_PER_SEC);
		
		
		//printf("%f %f\n",i,coverage);
		//printf("i=%f nexton=%f nextoff=%f type=%d\n",i,nexton,nextoff,type);
		
		
		/*tests for events, with priority for polymerizing - if both
		 * are due, it will polymerize first and only depol in the next 
		 * timestep*/
		if (i>=nextoff){
			type=2;}
		if (i>=nexton){
			type=1;
		}
		
		
		/*we will now calculate the number of filaments and constraints
		 * in the system, going over each lane - relatively 
		 * straightforward!*/
		filaments=0;
		noconsts=0;
		for (k=0;k<NLANES;k++){
				//printf("according to main, %d filaments in lane %d\n",newlanes[k][0],k);
			filaments=filaments+newlanes[k][0];
			noconsts=noconsts+2*newlanes[k][0];
			if (newlanes[k][0]>1){
				noconsts=noconsts+newlanes[k][0];
			}
		}
		
		
		/*polymerization event!*/	
		if (type==1){
			
			
			
			/*big legacy stuff - leave it alone!*/
			//printf("lanes at beginning: filaments=%d noconsts=%d\n",filaments,noconsts);
			//for (k=0;k<NLANES;k++){
			//printf("lane %d: ",k);
			//for (j=1;j<lanes[k][0]+1;j++){
				//printf("%d ",lanes[k][j]);
			//}
			//printf("\n");
		//}
			//if (i>0) count(states,argc, argv, lanes, filaments, noconsts);
			//gmp_printf("%Zd\n",states);
			
			
			/*sample exponential to get the size of the filament to be
			 * added (integer exponential is geometric!)*/ 
			size=gsl_ran_geometric(r,p);
			
			/*pick a lane at random to add the new filament*/
			/*parentheses: in the system without stickers, as long as
			 * this step of random sampling doesn't change, we're fine - 
			 * order inside lane doesn't really matter!*/
			j=gsl_rng_uniform_int(r,NLANES);
			
			
			/*calculate the current number of filaments and occupied
			 * length in the chosen lane*/
			currfils=lanes[j][0];
			currlen=0;
			for (k=1;k<currfils+1;k++){
				currlen=currlen+lanes[j][k];
			}
			
			
			
			//printf("currlen %d currfils %d\n",currlen,currfils);
			
			/*test if there's enough space to insert the new filament*/
			if (currlen+currfils+size+2>L)
				continue;
			
			/*if there is, pick a "gap" to insert the filament in 
			 * (i.e. the place in the order of filaments of that lane)*/
			else{
				gap=1+gsl_rng_uniform_int(r,currfils+1);
				
			/*if it's not at the end of the order, need to move the other
			 * ones in the lanes matrix to open space for the new one*/	
				if (gap!=currfils+1){
					for (k=currfils;k>gap-1;k--){
						newlanes[j][k+1]=newlanes[j][k];
					}
				}
				
				/*insert new filament...*/
				newlanes[j][gap]=size;
				
				/*...and update the number of filaments in the lane*/
				newlanes[j][0]++;
			}
			
			
			
			/*calculate number of filaments and constraints for the
			 * newlanes matrix - seems like a waste of a for loop, eh?*/
			filaments=0;
			noconsts=0;
			for (k=0;k<NLANES;k++){
				//printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k);
				filaments=filaments+newlanes[k][0];
				noconsts=noconsts+2*newlanes[k][0];
			if (newlanes[k][0]>1){
				noconsts=noconsts+newlanes[k][0];
			}
		}
		
		
		
		//printf("lanes after adding: filaments=%d noconsts=%d\n",filaments,noconsts);
		//printf("proposed change:\n");
		//for (k=0;k<NLANES;k++){
			//printf("lane %d: ",k);
			//for (j=1;j<newlanes[k][0]+1;j++){
				//printf("%d ",newlanes[k][j]);
			//}
			//printf("\n");
		//}
		
		
		/*count microstates after addition!*/
		count_new(&newstates, newlanes, filaments, noconsts); 
		//fprintf(fp,"count=");
		//value_print(fp, P_VALUE_FMT, newstates);
		//fprintf(fp,"\n");
		//gmp_printf("states=%Zd\n",states);
		//gmp_printf("newstates=%Zd\n",newstates);
		
		
		/*calculate delta omega for the addition - chemical potential
		 * plus entropy difference - this should always work since we
		 * set states to 0 in the very first iteration*/
		domega=-mu*size-mpzln(newstates)+mpzln(states);
		//printf("delta omega: %f log10newstates=%f log10states=%f\n",domega, mpzln(newstates),mpzln(states));
		
		
		/*metropolis test - if delta omega is negative, we accept
		 * the addition*/
		if (domega<0){
			memcpy(lanes,newlanes,sizeof(lanes));
			mpz_set(states,newstates);
			if (size==1){
				ends=ends+1;
			}else if (size>1){
				ends=ends+2;
			}
			if (first==1){
				first=0;
				nextoff=gsl_ran_exponential(r,1.0/(koff*ends));
			}else{
				nextoff=i+gsl_ran_exponential(r,1.0/(koff*ends));
			}
		}
		
		
		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
		else{
			double prob=exp(-1.0*domega);
			double fromthehat=gsl_rng_uniform(r);
			//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
			if (fromthehat<prob){
				memcpy(lanes,newlanes,sizeof(lanes));
				mpz_set(states,newstates);
					if (size==1){
					ends=ends+1;
				}else if (size>1){
					ends=ends+2;
				}
				if (first==1){
				first=0;
				nextoff=gsl_ran_exponential(r,1.0/(koff*ends));
				}else{
					nextoff=i+gsl_ran_exponential(r,1.0/(koff*ends));
				}
				//printf("accepted anyway!\n");
			}
		}
		
		
		
		//printf("final result:\n");
		//for (k=0;k<NLANES;k++){
			//printf("lane %d: ",k);
			//for (j=1;j<lanes[k][0]+1;j++){
				//printf("%d ",lanes[k][j]);
			//}
			//printf("\n");
		//}
		
		
		/*calculate time of next polymerization event and reset type*/
		nexton=nexton+gsl_ran_exponential(r,1.0/kon);
		//printf("nexton: %f\n",nexton);
		type=0;
	}
	
		
		
		/*Depol event! We need to check for number of filaments here
		 * (note that "filaments" here is the one calculated at the 
		 * beginning of the for loop) because if there are no filaments
		 * we just need to recalculate nextoff and keep going*/
		if (type==2 && filaments>0){
			//printf("entered depol\n");
			
			//printf("filaments: %d\n",filaments);
			
			
			
			/*this is one of those conditions that shouldn't be necessary,
			 * but I needed to add this at some point and now I'm afraid
			 * to take it out and break the whole thing, so there you go*/
			if (i>0 && filaments>0 ) {
				
			
				//count(states,argc, argv, lanes, filaments, noconsts);
			
				//gmp_printf("%Zd\n",states);
				
				
			/*pick a filament to decrease size - this will be changed 
			 * soon!*/
			//j=gsl_rng_uniform_int(r,filaments)+1;
			//printf("j=%d\n",j);
			j=gsl_rng_uniform_int(r,ends)+1;
			//fprintf(fp,"j=%d out of %d\n",j,ends);
			
			/*need to replicate the routine below, but with more 
			 * intelligence to track ends - maybe create small
			 * test program to try it in isolation?*/
			
			
			/*go through lanes until you find the filament to be 
			 * decreased in size. Then, decrease size by one, check 
			 * whether the filament disappeared (in which case following
			 * filaments need to be shifted left and number of filaments
			 * in lane decreased). Finally, break from the for loop*/
			int end_counter=0;
			int doneit=0;
			for (k=0;k<NLANES;k++){
					//fprintf(fp,"k=%d nd_counter=%d, lane has %d filaments\n",k,end_counter,lanes[k][0]);
				for (l=1;l<lanes[k][0]+1;l++){
					if (lanes[k][l]==1){
						end_counter=end_counter+1;
					}else{
						end_counter=end_counter+2;
					}	
				if (j<=end_counter){
					//fprintf(fp,"filaments=%d k=%d end_counter=%d thing to change=%d\n",filaments,k,end_counter,newlanes[k][l]);
					newlanes[k][l]=newlanes[k][l]-1;
					if (newlanes[k][l]==1){
						newends=newends-1;
					}
					if (newlanes[k][l]==0){
						for (m=l;m<newlanes[k][0];m++){
							newlanes[k][m]=newlanes[k][m+1];
						}
						newlanes[k][0]--;
						newends=newends-1;
					}
					doneit=1;
					break;
				}
				
				
			}
			if (doneit==1){
					break;
					}
		}	
		}
		
			
			
			//printf("nextoff=%f\n",nextoff);
			type=0;
			
			filaments=0;
			noconsts=0;
			
			for (k=0;k<NLANES;k++){
				//printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k);
				filaments=filaments+newlanes[k][0];
				noconsts=noconsts+2*newlanes[k][0];
			if (newlanes[k][0]>1){
				noconsts=noconsts+newlanes[k][0];
			}
		}
			//printf("rank %d is dumping previous lanes:\n",my_rank);
			//dump_lanes(lanes);
			//printf("rank %d is dumping its %d filaments and noconsts %d\n",my_rank,filaments,noconsts);
			//dump_lanes(newlanes);
			
			/*metropolis test should go in here*/
			count_new(&newstates, newlanes, filaments, noconsts); //<-segfault is here!
			//fprintf(fp,"count=");
			//value_print(fp, P_VALUE_FMT, newstates);
			//fprintf(fp,"\n");
			//gmp_printf("states=%Zd\n",states);
			//gmp_printf("newstates=%Zd\n",newstates);
			
			
			/*calculate delta omega for the addition - chemical potential
			 * plus entropy difference - this should always work since we
			 * set states to 0 in the very first iteration*/
			domega=mu-mpzln(newstates)+mpzln(states);
			//fprintf(fp,"depol domega=%f, diff in mpzln=%f\n",domega,domega-1);	
			if (domega<0){
				memcpy(lanes,newlanes,sizeof(lanes));
				mpz_set(states,newstates);
				ends=newends;
				
			}
		
		
		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					memcpy(lanes,newlanes,sizeof(lanes));
					mpz_set(states,newstates);
					
				}
			}
			if (ends>0){
			/*recalculate nextoff and reset type*/
			nextoff=nextoff+gsl_ran_exponential(r,1.0/(koff*ends));
		}else{
			nextoff=VERYBIG;
			//first=1;
		}
			
			/*recalculate the number of filaments and constraints (could 
			 * be done more efficiently, but whatever)*/
			filaments=0;
			noconsts=0;
			for (k=0;k<NLANES;k++){
				//printf("according to lanes, %d filaments in lane %d\n",newlanes[k][0],k);
				filaments=filaments+lanes[k][0];
				noconsts=noconsts+2*lanes[k][0];
			if (lanes[k][0]>1){
				noconsts=noconsts+lanes[k][0];
			}
			//printf("before counting: filaments=%d noconsts=%d\n",filaments,noconsts);
			
		}
		
		
		/*recalculate total number of states - this will probably be
		 * part of the Metropolis test further up when this is done*/
		count_new(&states, lanes, filaments, noconsts);
		//fprintf(fp,"count=");
		//value_print(fp, P_VALUE_FMT, states);
		//fprintf(fp,"\n");
	}
	
	
	/*in case there's nothing to depolimerize, we set nextoff as a big 
	 * float and reset the first flag*/
	if (type==2 && filaments==0){
		nextoff=VERYBIG;
		//first=1;
			type=0;
		}
		
		
		
		/*also, in any situation where there's no filament in the system,
		 * we set states to zero just to be on the safe side*/
		if (filaments==0){
			mpz_set_si(states,0);}
			
			
			
			
			//else{
				////printf("pass/ng to count: %d %d \n",filaments, noconsts);
			//count_new(&states,lanes, filaments, noconsts);}
			////for (k=0;k<NLANES;k++){
			//////printf("lane %d: ",k);
			////for (j=1;j<lanes[k][0]+1;j++){
				//////printf("%d ",lanes[k][j]);
			////}
			////printf("\n");
		//}
			
		
		//printf("%d %d\n",size,j);
	
	//printf("%d %f\n",omp_get_thread_num(),coverage);	
	}
	
	
	/*clearing up - deallocating the arbitrary precision stuff, closing
	 * the I/O file and returning!*/ 
	mpz_clear(states);
    mpz_clear(newstates);
    mpz_clear(deltastates);
    gsl_rng_free (r);
	fclose(fp);
    return coverage;
	}
void simulation_single(){

	const int num_lanes=2;
	int lane_size=100;
	const gsl_rng_type * T;
	gsl_rng_env_setup();
	T = gsl_rng_default;
	gsl_rng *r;
	r = gsl_rng_alloc (T);
	unsigned long int seed;
	seed=gen_seed();
		gsl_rng_set(r,seed);
	int fil_length=150;
	int stickers=1;
	//glue-related!
	//int stickers=0;
	mpz_t states;
	mpz_t newstates;
	mpz_t deltastates;
	mpz_init(states);
	mpz_init(newstates);
	mpz_init(deltastates);

	const float timesteps=5000;
	int my_rank;
	MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
	char* filename[60];
  sprintf(filename,"./output_single_filament_compact/run%d.txt",my_rank);
	// sprintf(filename,"./output_single_filament_glue_%.2f/run%d.txt",kstick,my_rank);
	printf("%s\n",filename);
	FILE *fp = fopen(filename, "w");
	if (fp == NULL) {
    	printf("Error");
			return;
    }
	float mu=6.0;
	float glue=1.0;
	float koff=1.0;
	float i;
	int j,k;
	float kstick=0.01;
	float kunstick=0.01;
	float stick_energy=3.0;
	int type=0;

	float nextoff=gsl_ran_exponential(r,1.0/koff);
	float nextstick=gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
	float nextunstick=gsl_ran_exponential(r,1.0/(stickers*kunstick));
	//glue-related!
	// float nextstick=VERYBIG;
	// float nextunstick=VERYBIG;
	float peroverlap=kstick;
	double domega;
	float c0=1.0/lane_size;

	int att_depol=0;
	int acc_depol=0;
	int att_stick=0;
	int acc_stick=0;
	int att_unstick=0;
	int acc_unstick=0;
	int att_contr=0;
	int acc_contr=0;
	int att_expan=0;
	int acc_expan=0;
	int att_special=0;
	int acc_special=0;
	float eta=0.2;
	float fraction=0.0;
	float delta=0.0;
	clock_t t1 = clock();
	//printf("before first count: %f fil_length: %d\n",kstick,fil_length);
	count_isl_single(&states,fil_length,stickers,lane_size);
	gmp_printf("states= %Zd\n",states);
	int currpar=0;

	for (i=0;i<timesteps;i=i+0.01){
		fraction=fraction+0.01*delta;
		//printf("%f %f %d\n",fraction,delta,currpar);
		// if ((int)(fraction*20)%2!=currpar){
		// 	fprintf(fp, "fraction=%f delta=%f\n",fraction,delta);
		//
		// }
		// 	currpar=(int)(fraction*20)%2;

		if (fabs(fraction)>1.0){
			//fprintf(fp,"event occurring - i=%f delta=%f fraction=%f\n",i,delta,fraction);
			if (fraction>0){
				delta=check_contraction(fil_length,stickers,lane_size+1,c0,states,r,fp);
				if (delta>VERYBIG/10){

					delta=0;
					fraction=0;
					//fprintf(fp,"delta too big! delta is now %f\n",delta);
				}else{
					lane_size++;
				}

			}
			else{
				delta=check_contraction(fil_length,stickers,lane_size-1,c0,states,r,fp);
				if (delta>VERYBIG/10){
					delta=0;
					fraction=0;
					//fprintf(fp,"delta too big! delta is now %f\n",delta);
				}else{
					lane_size--;
				}
			}
			fraction=0;
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));


		}

		if (stickers==0){
			nextunstick=VERYBIG;
		}
		if (fil_length-lane_size-stickers<=0){
			nextstick=VERYBIG;
		}
		//fprintf(fp, "fraction=%f delta=%f\n",fraction,delta);
		//printf("%f %f %f %f %d %d %d %d %d %d %d %d %d %d %d %d %d\n", i,nextoff,nextstick,nextunstick,fil_length,stickers,lane_size,att_depol,acc_depol,att_stick,acc_stick,att_unstick,acc_unstick,att_contr,acc_contr,att_expan,acc_expan);
		if (fil_length==0){
			break;
		}
		if ((int)(i*100)%(int)timesteps==0){
			clock_t t2 = clock();
			printf("%d percent %f\n",(int)(i*100)/(int)timesteps,(double)(t2-t1)/CLOCKS_PER_SEC);
		}
		//fprintf(fp,"i=%f\n",i);
		if ((int)(i*100)%50==0){
			fprintf(fp, "%f %f %f %f %d %d %d %d %d %d %d %d %d %d %d %f %f %f %f\n", i,nextoff,nextstick,nextunstick,fil_length,stickers,lane_size,att_depol,acc_depol,att_stick,acc_stick,att_unstick,acc_unstick,att_special,acc_special,((fil_length-lane_size-stickers)*kstick),(stickers*kunstick),delta,fraction);
			//gmp_fprintf(fp,"states= %Zd\n",states);
		}

		if (i>=nextoff){
			type=1;}
		if (i>=nextstick){
			type=2;
		}
		if (i>=nextunstick){
			type=3;
		}

		if (type==1){
			int done=0;
			att_depol=att_depol+1;
			int newlength=fil_length-1;
			// clock_t t3 = clock();
			count_isl_single(&newstates,newlength,stickers,lane_size);
			// clock_t t4 = clock();
			// printf("depol time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);
			if (mpz_cmp_d(newstates,0.0)){
				domega=-mu+glue-mpzln(newstates)+mpzln(states);
				//glue-related!
				// domega=-mu+glue+peroverlap-mpzln(newstates)+mpzln(states);
				if (domega<0){
					acc_depol++;
					fil_length=newlength;
					mpz_set(states,newstates);
					done=1;
					// fprintf(fp,"depol - domega=%f\n",domega);
				}


			/*if it's positive, we calculate the probability of acceptance
			 * and test for it*/
				else{
					double prob=exp(-1.0*domega);
					double fromthehat=gsl_rng_uniform(r);
					//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
					if (fromthehat<prob){
						fil_length=newlength;
						acc_depol++;
						mpz_set(states,newstates);
						done=1;
						// fprintf(fp,"depol - domega=%f\n",domega);

					}else{
	          // fprintf(fp,"removal not accepted - domega=%f\n",domega);
	        }
				}
			}
			if (done==0){
					att_special++;
					// clock_t t3 = clock();
					count_isl_single(&newstates,newlength,stickers-1,lane_size);
					// clock_t t4 = clock();
					// printf("special depol time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);

					domega=stick_energy-mu+glue-mpzln(newstates)+mpzln(states);
					if (domega<0){

						fil_length=newlength;
						stickers=stickers-1;
						acc_depol++;
						acc_special++;
						mpz_set(states,newstates);
						//fprintf(fp,"depol and removal - domega=%f\n",domega);
					}
					else{
						double prob=exp(-1.0*domega);
						double fromthehat=gsl_rng_uniform(r);
						//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
						if (fromthehat<prob){
							fil_length=newlength;
							stickers=stickers-1;
							acc_depol++;
							acc_special++;
							mpz_set(states,newstates);
							 //fprintf(fp,"depol and removal - domega=%f\n",domega);

						}else{
		          // fprintf(fp,"depol w/unstick not accepted - domega=%f\n",domega);
		        }
					}
			}

			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;
			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextoff=i+gsl_ran_exponential(r,1.0/koff);
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			type=0;
		}



		if (type==2){
			att_stick++;
			int newstickers=stickers+1;
			// clock_t t3 = clock();
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			// clock_t t4 = clock();
			// printf("new sticker time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);

			domega=-stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				stickers=newstickers;
				acc_stick++;
				mpz_set(states,newstates);
				// fprintf(fp,"added sticker - domega=%f\n",domega);

			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_stick++;
					mpz_set(states,newstates);
					// fprintf(fp,"added sticker - domega=%f\n",domega);
				}else{
          // fprintf(fp,"addition sticker rejected - domega=%f\n",domega);
        }
			}

			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;
			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			nextunstick=i+gsl_ran_exponential(r,1.0/(stickers*kunstick));
			type=0;

		}

		if (type==3){
			att_unstick++;
			int newstickers=stickers-1;

			// clock_t t3 = clock();
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			// clock_t t4 = clock();
			// printf("remove sticker time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);
			domega=stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				acc_unstick++;
				stickers=newstickers;
				mpz_set(states,newstates);
			 //fprintf(fp,"removal - domega=%f\n",domega);
			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_unstick++;
					mpz_set(states,newstates);
				 //fprintf(fp,"removal - domega=%f\n",domega);
				}else{
          // fprintf(fp,"removal of sticker not accepted - domega=%f\n",domega);
        }
			}
			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;

			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextunstick=i+gsl_ran_exponential(r,1.0/(stickers*kunstick));
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			type=0;

		}



	}
	mpz_clear(states);
  mpz_clear(newstates);
  mpz_clear(deltastates);
  gsl_rng_free (r);
 	fclose(fp);

}
Example #3
0
 explicit randgen(boost::iterator_range<It> r, unsigned int seed = gen_seed())
         : seed_(seed),
           r_(r)
 {}
void simulation_single(float kstick){

	const int num_lanes=2;
	int lane_size=1000;
	const gsl_rng_type * T;
	gsl_rng_env_setup();
	T = gsl_rng_default;
	gsl_rng *r;
	r = gsl_rng_alloc (T);
	unsigned long int seed;
	seed=gen_seed();
		gsl_rng_set(r,seed);
	int fil_length=1500;
	int stickers=1;
	//glue-related!
	//int stickers=0;
	mpz_t states;
	mpz_t newstates;
	mpz_t deltastates;
	mpz_init(states);
	mpz_init(newstates);
	mpz_init(deltastates);

	float timesteps=50000;
	int my_rank;
	MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
	char* filename[60];
  sprintf(filename,"./output_single_filament_strong_%.2f/run%d.txt",kstick,my_rank);
	// sprintf(filename,"./output_single_filament_glue_%.2f/run%d.txt",kstick,my_rank);
	printf("%s\n",filename);
	FILE *fp = fopen(filename, "w");
	if (fp == NULL) {
    	printf("Error");
			return;
    }
	float mu=6.0;
	float glue=1.0;
	float koff=1.0;
	float i;
	int j,k;
	//float kstick=0.05;
	float kunstick=kstick;
	float stick_energy=8.0;
	int type=0;
	int delta=0;
	float nextoff=gsl_ran_exponential(r,1.0/koff);
	float nextstick=gsl_ran_exponential(r,1.0/kstick);
	float nextunstick=gsl_ran_exponential(r,1.0/kunstick);
	//glue-related!
	// float nextstick=VERYBIG;
	// float nextunstick=VERYBIG;
	float peroverlap=kstick;
	double domega;
	float c0=1.0/lane_size;

	int att_depol=0;
	int acc_depol=0;
	int att_stick=0;
	int acc_stick=0;
	int att_unstick=0;
	int acc_unstick=0;
	int att_contr=0;
	int acc_contr=0;
	int att_expan=0;
	int acc_expan=0;

	count_isl_single(&states,fil_length,stickers,lane_size);


	for (i=0;i<timesteps;i=i+0.01){
		if (fil_length==0){
			break;
		}
		if ((int)(i*100)%(int)timesteps==0){
			printf("%d\%\n",(int)(i*100)/timesteps);
		}
		if ((int)(i*100)%50==0){
			fprintf(fp, "%f %f %f %f %d %d %d %d %d %d %d %d %d %d %d %d %d\n", i,nextoff,nextstick,nextunstick,fil_length,stickers,lane_size,att_depol,acc_depol,att_stick,acc_stick,att_unstick,acc_unstick,att_contr,acc_contr,att_expan,acc_expan);
		}

		if (i>=nextoff){
			type=1;}
		if (i>=nextstick){
			type=2;
		}
		if (i>=nextunstick){
			type=3;
		}

		if (type==1){
			att_depol=att_depol+1;
			int newlength=fil_length-1;
			count_isl_single(&newstates,newlength,stickers,lane_size);
			if (!mpz_cmp_d(newstates,0.0)){
					count_isl_single(&newstates,newlength,stickers-1,lane_size);
					domega=stick_energy-mu+glue-mpzln(newstates)+mpzln(states);
					if (domega<0){

						fil_length=newlength;
						stickers=stickers-1;
						acc_depol++;
						mpz_set(states,newstates);
						//fprintf(fp,"depol and removal - domega=%f\n",domega);
					}
					else{
						double prob=exp(-1.0*domega);
						double fromthehat=gsl_rng_uniform(r);
						//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
						if (fromthehat<prob){
							fil_length=newlength;
							stickers=stickers-1;
							acc_depol++;
							mpz_set(states,newstates);
							//fprintf(fp,"depol and removal - domega=%f\n",domega);

						}else{
		          //fprintf(fp,"depol w/unstick not accepted - domega=%f\n",domega);
		        }
					}
			}else{
			domega=-mu+glue-mpzln(newstates)+mpzln(states);
			//glue-related!
			// domega=-mu+glue+peroverlap-mpzln(newstates)+mpzln(states);
			if (domega<0){
				acc_depol++;
				fil_length=newlength;
				mpz_set(states,newstates);
				//fprintf(fp,"depol - domega=%f\n",domega);
			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					fil_length=newlength;
					acc_depol++;
					mpz_set(states,newstates);
					//fprintf(fp,"depol - domega=%f\n",domega);

				}else{
          //fprintf(fp,"removal not accepted - domega=%f\n",domega);
        }
			}
		}
			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			if (delta==-1){
				acc_contr++;
			}
			if (delta==+1){
				acc_expan++;
			}
			lane_size=lane_size+delta;
			nextoff=i+gsl_ran_exponential(r,1.0/koff);
			type=0;
		}



		if (type==2){
			att_stick++;
			int newstickers=stickers+1;
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			domega=-stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				stickers=newstickers;
				acc_stick++;
				mpz_set(states,newstates);
				//fprintf(fp,"added sticker - domega=%f\n",domega);

			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_stick++;
					mpz_set(states,newstates);
					//fprintf(fp,"added sticker - domega=%f\n",domega);
				}else{
          //fprintf(fp,"addition sticker rejected - domega=%f\n",domega);
        }
			}


			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			if (delta==-1){
				acc_contr++;
			}
			if (delta==+1){
				acc_expan++;
			}
			lane_size=lane_size+delta;
			nextstick=i+gsl_ran_exponential(r,1.0/kstick);
			type=0;

		}

		if (type==3){
			att_unstick++;
			int newstickers=stickers-1;
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			domega=stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				acc_unstick++;
				stickers=newstickers;
				mpz_set(states,newstates);
				//fprintf(fp,"removal - domega=%f\n",domega);
			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_unstick++;
					mpz_set(states,newstates);
					//fprintf(fp,"removal - domega=%f\n",domega);
				}else{
          //fprintf(fp,"removal of sticker not accepted - domega=%f\n",domega);
        }
			}

			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			if (delta==-1){
				acc_contr++;
			}
			if (delta==+1){
				acc_expan++;
			}
			lane_size=lane_size+delta;
			nextunstick=i+gsl_ran_exponential(r,1.0/kunstick);
			type=0;

		}



	}