Skip to content
Snippets Groups Projects
Unbreakable_Polymers.v1.c++ 6.19 KiB
Newer Older
dmichiel's avatar
dmichiel committed
/*
This code simulates the reptation model (eq.10) in Cates1987 without breakage and fusion
1. The reptation of a polymer within a tube
=> How does it change the viscosity with L0?
*/

#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<sstream>
#include<fstream>
#include<string>
#include<iomanip>
#include<vector>
using namespace std;

/* CONSTANTS */
const int REPMAX=300;
const double dL=0.01; //
const double dt=0.01; //integration time
const double tau=1.0; //unit of time (100dt)
double L0=1.0; //L0 sets the units of length (100dL)
const double D0=0.01; //monomer diffusion. In units of L0^2/dt
                        //if L0=1; set D0=(1/dt) to get L0^2 monomer diffusion every
                        //tau=(1/dt) steps. [D0]=0.01[L0^2/dt]=1[L0^2/tau]
const int bin=10;//for histogram. Time units
const int Tmaxmax=10000000; // this is bc it wants something not variable for arrays

/* ARRAYS */
double pos_left[Tmaxmax];
double pos_right[Tmaxmax];
int RelaxTime[REPMAX];
int Histo[Tmaxmax];
int Survival[Tmaxmax];
int CountBreaks[REPMAX];
int CountFusions[REPMAX];

/* FUNCTIONS */
double Diff(double L);

/* MAIN */
int main(int argc, char* argv[]){
srand(time(NULL));
//cout << "Trep=" << Trep <<endl;

double L0=atof(argv[1]);
double Trep=pow(L0,3.0)/D0; //reptation time (units dt)
int Tmax=int(100*Trep); //true maximum time (units dt)

double xi=0;
double c1=(1.0/Trep)*(1/xi);//1/Trep*1/Xi
double Tbreak=1/(c1*L0);
//double xi=Tbreak/Trep;

/*Initialise arrays*/
for(int t=0;t<Tmax;t++) pos_left[t]=pos_right[t]=Survival[t]=0;
for(int i=0;i<REPMAX;i++)RelaxTime[i]=Tmax;

/* CREATE/OPEN FILES */
stringstream namepos;
namepos << "Position_"<<L0<<".dat";
ofstream writepos;
writepos.open(namepos.str().c_str());
//
stringstream namefi;
namefi << "Survival_"<<L0<<".dat";
ofstream writeSu;
writeSu.open(namefi.str().c_str());
//
stringstream namefieta;
namefieta << "eta_"<<L0<<".dat";
ofstream writeETA;
writeETA.open(namefieta.str().c_str());
//
stringstream namefitopo;
namefitopo << "topo_"<<L0<<".dat";
ofstream writetopo;
writetopo.open(namefitopo.str().c_str());
//

/*Start loop over attempts*/
for(int i=0; i<REPMAX; i++){
cout << "============= " <<endl;
cout << "== NEW REP == " <<endl;
cout << "============= " <<endl;

/* Define initial condition with Length exponentially distributed ~exp(-l/l0) */
//left end
pos_left[0]=-L0*log(rand()*1.0/RAND_MAX); //sample from exponential distro
//right end
pos_right[0]=-L0*log(rand()*1.0/RAND_MAX); //sampled from expoential ditro

/* Tube segment starts at 0 */
writepos << 0 << " " << -pos_left[0] <<" " << pos_right[0]<< " "<< i << endl;

double b1,b2,L;

/* =============== */
/*    START TIME   */
/* =============== */
/* Start time. The particle is at 0.*/
/* Pos_left is actually to negative value*/
for(int t=1;t<=Tmax; t++){

L=pos_right[t-1]+pos_left[t-1];
b1=pos_left[t-1];
b2=pos_right[t-1];

/* At each timestep there is a chance of breakage or fusion */
/* BREAKAGE at rate c1 per unit time per unit length */
/*
for(int l=0;l<int(b1/dL);l++){
//cout << "attemp break @ " << l << endl;
double pbreak_left=rand()*1.0/RAND_MAX;
    if(pbreak_left<c1*dL*dt){
    //cout << "pbreak_left " << pbreak_left << " " << c1*dL*dt <<endl;
    cout << "LEFT BREAK " << b1<<" -> " << l*dL << endl; //cin.get();
    b1=l*dL;
    CountBreaks[i]++;
    break;
    }
}

for(int l=0;l<int(b2/dL);l++){
double pbreak_right=rand()*1.0/RAND_MAX;
    if(pbreak_right<c1*dL*dt){
    //cout << "pbreak_right " << pbreak_right << " " << c1*dL*dt <<endl;
    cout << "RIGHT BREAK " << b2<<" -> " << l*dL << endl; //cin.get();
    b2=l*dL;
    CountBreaks[i]++;
    break;
    }
}
*/

/* FUSION at rate c2 per unit time per unit length */
/* in reality it becomes c2*N(l)=c2*c1/c2*exp(-l/L0)=c1*exp(-l/L0) */
/* so propto the concentration of chains of length l */
//double l_left=-L0*log(rand()*1.0/RAND_MAX);
/*
for(int l_left=1;l_left<1000;l_left++){
double pfus_left=rand()*1.0/RAND_MAX;
if(pfus_left<c1*dL*dt*exp(-l_left/L0)){
    cout << "LEFT FUSION " << b1<<" -> " << b1+l_left << endl;
    b1=b1+l_left;
    CountFusions[i]++;
    break;
}
}
//double l_right=-L0*log(rand()*1.0/RAND_MAX);
for(int l_right=1;l_right<1000;l_right++){
double pfus_right=rand()*1.0/RAND_MAX;
if(pfus_right<c1*dL*dt*exp(-l_right/L0)){
    cout << "RIGHT FUSION " << b2<<" -> " << b2+l_right << endl;
    b2=b2+l_right;
    CountFusions[i]++;
    break;
}
}
*/

/* NEW LENGTH */
L=b2+b1;

/* UPDATE */
//pos_left[t]=b1;
//pos_right[t]=b2;

/* DIFFUSE THE TWO ENDS */
/* USE b1 and b2 otherwise missing the breaks */
/* CAREFUL! They are not independent otherwise the chain changes length! */
int dir=(rand()%2)*2-1; //+1 or -1
pos_left[t]=b1+dir*sqrt(2*Diff(L)*dt);
pos_right[t]=b2-dir*sqrt(2*Diff(L)*dt);

cout << t*dt << " " << -pos_left[t] << " " << pos_right[t] << " "<< i << endl;
writepos << t*dt << " " << -pos_left[t] << " " << pos_right[t] << " "<< i << endl;

/* Survival function */
if(pos_left[t]>0 && pos_right[t]>0)Survival[t]++;

/* if one of them hit 0 break */
if(pos_left[t]<0 || pos_right[t]<0){
RelaxTime[i]=t;
break;
}

}//close loop over time

writepos << endl;
writepos << endl;

}//close loop over attempts

/* SURVIVAL */
writeSu <<"#t P_survived(t) " << endl;
for(int i=0;i<=Tmax;i++) writeSu << i*dt << " " << Survival[i]*1.0/REPMAX << endl;

/* VISCOSITY*/
/* this is the integral of the survival function */
double eta=0;
for(int i=0;i<Tmax;i++) eta+=Survival[i]*1.0/REPMAX*dt;
cout << L0 << " " << xi << " " <<  eta <<endl;
writeETA << L0 << " " << xi << " " <<  eta <<endl;


double meanb=0;
double meanfus=0;
for(int i=0;i<REPMAX;i++){
writetopo << i << " " << CountBreaks[i] << " " << CountFusions[i] << " " << RelaxTime[i] <<endl;
meanb+=CountBreaks[i]*1.0/RelaxTime[i];
meanfus+=CountFusions[i]*1.0/RelaxTime[i];
}
writetopo<<endl;
writetopo<<endl;
writetopo << "Xi c_1 <breaks/time> <fusion/time> " <<endl;
writetopo << xi << " " << c1 <<" " << meanb/REPMAX << " " << meanfus/REPMAX <<endl;

return 0;
}


/* curivlinear diffusion coeff and function of L */
double Diff(double L){
return D0/L; //L is in units of L0
}