示例#1
0
文件: model.c 项目: dseaton/polymermc
void reset_XYZ(void)
{
	int i;
	double cx=0.0,cy=0.0,cz=0.0;

	//Find the center of mass for each component
	for(i=0;i<N;i++)
    {
		cx+=x[i];
		cy+=y[i];
		cz+=z[i];
    };

	cx*=invN;
	cy*=invN;
	cz*=invN;

	//fprintf(stderr,"%g\t%g\t%g\n",cmass(),currEtot,currnonbondE);
	for(i=0;i<N;i++)
    {
		x[i]=x[i]-cx;
		y[i]=y[i]-cy;
		z[i]=z[i]-cz;
    };
	
	//Recalculate the overall energies
	currEtot=Etot();
	currnonbondE=nonbondEnergy();
	
	//fprintf(stderr,"%g\t%g\t%g\n",cmass(),currEtot,currnonbondE);
}
示例#2
0
/*Monte Carlo bond fluctuation  algorithm
Similar to mcpivot, but rotates monomers betwee two randomly chosen monomers by a small amount 
axis of rotation is between the two chosen monomers

NOTE this algorithm should NOT change the bond lengths, use checkbonds() to check, but should change one bond angle at a time
*/
void mccrankshaft(void)
{
	int i=0,j=0,m1=0,m2=0,start=0,end=0;
    double Ei=0.0,Ef=0.0; //intial and final energies (before and after diffusion)
	double Ebondi=0.0,Ebondf=0.0,Enblocali=0.0,Enblocalf=0.0; //local energy variables
	double rx=0.0,ry=0.0,rz=0.0;
	double distr=0.0,rangle=0.0,c=0.0,s=0.0,u=0.0;
	double ttx=0.0,tty=0.0,ttz=0.0;
	
	//set temporary positions
	for(j=0;j<N;++j)
    {
		tx[j]=x[j];
		ty[j]=y[j];
		tz[j]=z[j];
    };
	
	//randomly choose two monomers
	m1=(int) (randd1()*N);
	m2=(int) (randd1()*N);
	
	//choose random rotation angle
	rangle=DC*2.0*M_PI*(2.0*randd1()-1.0);
	
	//below are the cases where the move wouldn't change anything
	while( (m1==m2) || (abs(m1-m2)==N-1) || (abs(m1-m2)==1) )  
	{
		m1=(int) (randd1()*N);
		m2=(int) (randd1()*N);
	};
	
	//set indices for energy calculation
	if( m1<m2 )
	{
		start=m1;
		end=m2;
	}
	else
	{
		start=m2;
		end=m1;
	};
	
	//Set initial energies
	Ei=currEtot;
	
	//////////Rotation
	//rotation axis is the vector between m1 and m2
	distr = sqrt( (x[m1]-x[m2])*(x[m1]-x[m2]) + (y[m1]-y[m2])*(y[m1]-y[m2]) + (z[m1]-z[m2])*(z[m1]-z[m2]) );
	rx = (x[m1]-x[m2])/distr;
	ry = (y[m1]-y[m2])/distr;
	rz = (z[m1]-z[m2])/distr;
	
	//angle constants
	c=cos(rangle);
	s=sin(rangle);
	u=1.0-c;
	
	//Calculate the initial local bond energy
/*	for(i=start;i<end;i++)
	{
		distr = sqrt( (x[i]-x[i+1])*(x[i]-x[i+1]) + (y[i]-y[i+1])*(y[i]-y[i+1]) + (z[i]-z[i+1])*(z[i]-z[i+1]) );
		Ebondi = Ebondi + bondpot(distr);
	};
*/
	//Local bond and bond angle energy - assumes the above in unecessary
	Ebondi = localE(m1) + localE(m2);
	
	/////Rotation
	//now we perform the rotation
	for(i=start+1;i<end;i++)
	{
		//calculate initial local nonbonded energy
		for(j=0;j<N;j++)
			if( (j<start) || (j>end) )
			{
				distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
				Enblocali = Enblocali + nonbondpot(distr);
				//fprintf(stderr,"%d\t%d\t%20.16f\t%20.16f\t%20.16f\n",i,j,distr,nonbondpot(distr),Enblocali);
			};
		
		//translate the rotation segment to the origin
		x[i] -= x[start];
		y[i] -= y[start];
		z[i] -= z[start];
		
		//store old vector for the rotation matrix below
		ttx=x[i];
		tty=y[i];
		ttz=z[i];
		
		//Perform the rotation on the selected segment
		x[i] = (u*rx*rx + c)*ttx     + (u*ry*rx - s*rz)*tty  + (u*rz*rx + ry*s)*ttz;
		y[i] = (u*rx*ry + rz*s)*ttx  + (u*ry*ry + c)*tty     + (u*rz*ry - rx*s)*ttz;
		z[i] = (u*rx*rz - ry*s)*ttx  + (u*ry*rz + rx*s)*tty  + (u*rz*rz + c)*ttz;	
		
		//translate the rotation segment back to the original reference frame
		x[i] += x[start];
		y[i] += y[start];
		z[i] += z[start];
		
		//calculate final local nonbonded energy
		for(j=0;j<N;j++)
			if( (j<start) || (j>end) )
			{
				distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
				Enblocalf = Enblocalf + nonbondpot(distr);
				//fprintf(stderr,"%d\t%d\t%20.16f\t%20.16f\t%20.16f\n",i,j,distr,nonbondpot(distr),Enblocalf);
			};
	};
	
	//Calculate the initial local bond energy
/*	for(i=start;i<end;i++)
	{
		distr = sqrt( (x[i]-x[i+1])*(x[i]-x[i+1]) + (y[i]-y[i+1])*(y[i]-y[i+1]) + (z[i]-z[i+1])*(z[i]-z[i+1]) );
		Ebondf = Ebondf + bondpot(distr);
	};
*/
	//Local bond and bond angle energy - assumes the above in unecessary
	Ebondf = localE(m1) + localE(m2);
	
	//Bond-angles should be unaffected by this move
	
	Ef = Ei + (Ebondf - Ebondi) + (Enblocalf - Enblocali);
	
	attemptside+=1;
	
	if(Metropolis(Ei,Ef)==1)
	{
		acceptside+=1;
		if( (acceptside%1000) == 0 )
		{
			currEtot = Etot();
		};
	}
	else
    {
		//reject
		for(j=0;j<N;++j)
		{
			x[j]=tx[j];
			y[j]=ty[j];
			z[j]=tz[j];
		};
    };
}
示例#3
0
/*
Monte Carlo pivot around a random direction
Random direction generated using the Marsaglia method

NOTE this algorithm should NOT change the bond lengths, use checkbonds() to check, but should change one bond angle at a time
*/
void mcrandpivot(void)
{
	int m=0,i=0,j=0,direction=0,start=0,end1=0,end2=0;
	double Ei=0.0,Ef=0.0; //intial and final energies (before and after diffusion)
	double Ebondi=0.0,Ebondf=0.0,Enblocali=0.0,Enblocalf=0.0; //local energy variables
	double eta1=0.0,eta2=0.0,etasq=0.0,rx=0.0,ry=0.0,rz=0.0;
	double distr=0.0,rangle=0.0,c=0.0,s=0.0,u=0.0;
	double ttx=0.0,tty=0.0,ttz=0.0;
	
	//set temperorary variables
	for(j=0;j<N;++j)
    {
		tx[j]=x[j];
		ty[j]=y[j];
		tz[j]=z[j];
    };
	
	//choose random monomer
	m=(int) (randd1()*(N-2)+1.0);  //note, never choses monomers on the ends, as this would do nothing to the internal degrees of freedom
	
	//choose random rotation angle
	rangle=DC*2.0*M_PI*(2.0*randd1()-1.0);
	
	//select the shortest portion of the chain to the left or right of the random monomer
	if(m < N/2.0)
	{
		direction = -1;
		start=m;
		end1=0;
		end2=N-1;
	}
	else
	{
		direction = 1;
		start=m;
		end1=N-1;
		end2=0;
	};
	
	//choose a random direction using the Marsaglia method
	etasq = 2.0;  //simply set to a value greater than 1.0 (the while condition below)
    while( etasq > 1.0 )
	{
		eta1 = 1.0 - 2.0*randd1();
		eta2 = 1.0 - 2.0*randd1();
		
		etasq = eta1*eta1 + eta2*eta2;
	};
	
	//these are the new unit vectors
	rx = 2.0*eta1*sqrt(1.0-etasq);
	ry = 2.0*eta2*sqrt(1.0-etasq);
	rz = 1.0 - 2.0*etasq;
	
	//angle constants
	c=cos(rangle);
	s=sin(rangle);
	u=1.0-c;
	
	//set energies
	Ei=currEtot;
	
	//Calculate the initial local bond energy (NOTE: this cannot go in the rotation loop)
/*	i=start;
	while( i != end1 )
	{
		i=i+direction;
		j=i-direction;
		distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
		Ebondi = Ebondi + bondpot(distr);	
		//fprintf(stderr,"%d\t%d\t%d\t%f\t%f\n",m,i,i-direction,distr,bondpot(distr));
	};
*/
	//Local bond and bond angle energy - assumes bond lengths don't change (unlike above commented out section)
	Ebondi = Ebondi + localE(m);
	
	/////Rotation
	//now we perform the rotation
	i=start;
	while( i != end1 )
	{
		i=i+direction;
		
		//Calculate the initial local nonbond energy
		for(j=end2;j!=start;j+=direction)
		{	
			distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
			Enblocali = Enblocali + nonbondpot(distr);
			//fprintf(stderr,"%d\t%d\n",i,j);
		};
		
		//translate the rotation segment to the origin
		x[i] -= x[start];
		y[i] -= y[start];
		z[i] -= z[start];
		
		//store old vector for the rotation matrix below
		ttx=x[i];
		tty=y[i];
		ttz=z[i];
		
		//Perform the rotation on the selected segment
		x[i] = (u*rx*rx + c)*ttx     + (u*ry*rx - s*rz)*tty  + (u*rz*rx + ry*s)*ttz;
		y[i] = (u*rx*ry + rz*s)*ttx  + (u*ry*ry + c)*tty     + (u*rz*ry - rx*s)*ttz;
		z[i] = (u*rx*rz - ry*s)*ttx  + (u*ry*rz + rx*s)*tty  + (u*rz*rz + c)*ttz;	
		
		//translate the rotation segment back to the original reference frame
		x[i] += x[start];
		y[i] += y[start];
		z[i] += z[start];
		
		//Final local nonbond energy
		for(j=end2;j!=start;j+=direction)
		{	
			distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
			Enblocalf = Enblocalf + nonbondpot(distr);
			//fprintf(stderr,"%d\t%d\n",i,j);
		};
	};
	
	//Calculate the final local bond energy (NOTE: this cannot go in the rotation loop)

/*	i=start;
	while( i != end1 )
	{
		i=i+direction;
		j=i-direction;
		distr = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]) );
		Ebondf = Ebondf + bondpot(distr);	
		//fprintf(stderr,"%d\t%d\t%d\t%f\t%f\n",m,i,i-direction,distr,bondpot(distr));
	};
*/
	//Local bond and bond angle energy - assumes bond lengths don't change (unlike above commented out section)
	Ebondf = Ebondf + localE(m);
	
	Ef = Ei + (Ebondf - Ebondi) + (Enblocalf - Enblocali);	
	//Ef=Etot();
	
	attemptpivot+=1;
	
	if(Metropolis(Ei,Ef)==1)
	{
		acceptpivot+=1;
		if( (acceptpivot%1000) == 0 )  //this insures that errors do not accumulate over time
		{
			currEtot = Etot();
		};
	}
	else
    {
		//reject
		for(j=0;j<N;++j)
		{
			x[j]=tx[j];
			y[j]=ty[j];
			z[j]=tz[j];
		};
	};
}
示例#4
0
double Planet::Etotal(int i){
    return Etot(i);
}
示例#5
0
文件: model.c 项目: dseaton/polymermc
//initialize the polymer chain with one end at the origin
//and all nn bonds at the ground state, in the x-y plane
void initialize(void)
{
	int i;
	double a=1.0;

	//for relatively big jumps
	D=0.05;  DC=1.0;  DD=0.1;

	//precalculations for chain length
	invN=1.0/(1.0*N);
	rootinvN = 1.0/sqrt(1.0*N);
  
	//term used to set the FENE+LJ potential's minimum at 1.0
	sigmaFENE = pow((0.5+sqrt(23.0/44.0)),(1.0/6.0));

	//precalculation for the LJ potential
	sigmaLJ=pow(0.5,1.0/6.0);
	
	//term used to shift the LJ potential such that it is zero at r=1.0
	shiftLJ = pow((1.0/Rcutnonbond),12.0) - 2.0*pow((1.0/Rcutnonbond),6.0);
  

	//precalculations for the nn bond angle potentials
	PI=2.0*acos(0.0);
	ANG=PI;
	COSANG=cos(ANG);
	 
	T=5.0;

	//Dynamic Memory Allocation - this has to be done because an input file is used.
	//x,y,z coordinates 
	x = malloc( N * sizeof(double) );
	y = malloc( N * sizeof(double) );
	z = malloc( N * sizeof(double) );
	if ( (x == NULL) || (y == NULL) || (z == NULL) )
    {
        fprintf(stderr,"\nFailure to allocate memory for 'x,y, or z'.  See 'initialize()'.\n");
        exit(1);
    };
  
	//tx,ty,tz - used as temporary coordinates in many of the "move" functions 
	tx = malloc( N * sizeof(double) );
	ty = malloc( N * sizeof(double) );
	tz = malloc( N * sizeof(double) );
	if ( (tx == NULL) || (ty == NULL) || (tz == NULL) )
    {
        fprintf(stderr,"\nFailure to allocate memory for 'tx,ty, or tz'.  See 'initialize()'.\n");
        exit(1);
    };

	//Initialize the tmp coordinates
	for(i=0;i++;i<N)
	{
		tx[i]=0.0;
		ty[i]=0.0;
		tz[i]=0.0;
	};
	
	//Initializing the chain
	//One end starts at the origin
	x[0]=0.0;
	y[0]=0.0;
	z[0]=0.0;
  
	//Initialize the rest of the chain
	for(i=1;i<N;++i)
	{
		x[i]=x[i-1]+1.0;
		y[i]=0.0;
		z[i]=0.0;
    };

	currEtot=Etot();
	currnonbondE=nonbondEnergy();
}