예제 #1
0
void Exchange(double spin1[XMAX][YMAX],double spin2[XMAX][YMAX],int N,int L,double *E,double *M,double *accept)
{
  /*one Monte Carlo step per spin  */
  int ispin,x,y,dE,choose=0;
  //Check If Temperature
  OnTempChange();
  for (ispin=1; ispin <= N; ispin++)
    {
      /* random x and y coordinates for trial spin  */
      x = L*rnd();
      y = L*rnd();
      dE = DeltaE(spin1,x,y,L);      
      choose = lambda != 0 ? 1+(int)(spin1[x][y]*spin2[x][y]): 1+(int)spin1[x][y];
      if (rnd() <= w[dE+8][choose])
	{
	  spin1[x][y] = -spin1[x][y];
	  *accept = *accept + 1;
	  *M = *M + 2*spin1[x][y];
	  *E = *E + dE;
	}
    }
}
예제 #2
0
int main (int argc, char * argv[])
{
	if(argc == 1)
	{
		printf("\nNumero di parametri insufficiente!");
		printf("\nImpostare tipo di inzializzazione:\n");
		printf("\t1 -> a freddo;\n");
		printf("\t2 -> a caldo\n\n");
		exit(EXIT_FAILURE);
	}

	if(argc > 2)
	{
		STEPS = atoi(argv[2]);
		if(STEPS%DBIN != 0)
		{
			printf("\n# sweeps non è multiplo intero della lunghezza dei bins!\n\n");
			exit(EXIT_FAILURE);
		}
	}

	int Nbins = STEPS/DBIN;
	int i, step, Dt, bin, t;
	int choice = 0;
	double action, Sum, Sum1, Err, Err1;
	
	/* Stringhe per il nome del file di output */
	char *file_autocorr, *file_action;
	file_autocorr	= malloc(100*sizeof(char));
	file_action		= malloc(100*sizeof(char));

	/*
	 * Vettori utili:
	 * _ state -> contiene la posizione dell'oscillatore in ogni passo del 
	 * 		reticolo (N passi totali);
	 * 
	 * _ corrDtstep -> contiene i valori stimati a ciascun passo del Metropolis 
	 * 		di <x_i*x_{i+Dt}>;
	 * 
	 * _ Vtemp, Vtemp1 -> vettori ausiliari per costruire i correlatori di x e
	 *		di x^2 con il metodo del binning;
	 **/
	double *state, *corrDtstep, *Vtemp, *Vtemp1, *autocorr;

	/*
	 * Clusters jackknife utili:
	 * _ clusterDt -> N cluster jk che contengono i correlatori di x e gli
	 *		errori;
	 * 
	 * _ clusterSQDt -> cluster jk che contengono i correlatori di x^2 e gli
	 *		errori;
	 *
	 * _ DEtemp e EMtemp -> clusters jk ausiliari per il calcolo del gap di
	 *		energia e dell'elemento di matrice <0|x|1>
	 **/
	cluster *clusterDt, *clusterSQDt;
	cluster DEtemp, EMtemp;

	/* Eliminazione dei vecchi dati e creazione cartelle per i nuovi dati
	 * dell'autocorrelazione
	 */
	system("rm -r harmosc/autocorrelation");
	system("mkdir harmosc/autocorrelation");

	/* 
	 * File di output utili:
	 * _ out_action -> azione dell'oscillatore armonico in funzione dello sweep
	 * 		del Metropolis;
	 * 
	 * _ out_corr -> correlatori <x_l x_k> ed errori;
	 * 
	 * _ out_deltaE -> valori di deltaE (mediato sugli Nbins bin) in funzione di
	 * 		Dt (variabile della correlazione);
	 * _ out_deltaE_errors -> errori sul calcolo di DeltaE;
	 * 
	 * _ out_EM -> valore elemento di matrice di <0|x|1>;
	 * _ out_EM_errors -> errori sul calcolo di <0|x|1>;
	 *
	 * _ out_x2gs -> risultati ed errori di <x^2> sullo stato
	 *		fondamentale;
	 * 
	 * _ out_corrsq -> correlatori <x^2_l x^2_k> ed errori;
	 * 
	 * _ out_autocorr -> files labellati dal valore di Dt in cui viene salvata
	 * 		la funzione di autocorrelazione per <x_l x_{l+Dt}>
	 */
	FILE *out_action, *out_corr, *out_deltaE, *out_EM, *out_deltaE_errors,\
		*out_EM_errors, *out_x2gs, *out_corrsq;
	FILE *out_autocorr[DMAX+1];
	out_corr	= fopen("harmosc/corr_results.dat","w");
	out_deltaE	= fopen("harmosc/deltaE_results.dat","a");
	out_EM		= fopen("harmosc/matrixelement_results.dat","a");
	out_deltaE_errors	= fopen("harmosc/deltaE_errors.dat","a");
	out_EM_errors		= fopen("harmosc/matrixelement_errors.dat","a");
	out_x2gs	= fopen("harmosc/Egs_results.dat", "a");
	out_corrsq	= fopen("harmosc/corrSQ_results.dat", "a");
	for(i=0; i<DMAX+1; i++)
	{
		sprintf(file_autocorr, "harmosc/autocorrelation/autocorr_%d", i);
		out_autocorr[i] = fopen(file_autocorr, "w");
	}

	/* Allocazione vettori e cluster jk utili */
	state 		= malloc(N*sizeof(double));
	corrDtstep	= malloc((N*STEPS)*sizeof(double));
	Vtemp		= malloc(N*sizeof(double));
	Vtemp1		= malloc(N*sizeof(double));
	autocorr	= malloc(N*sizeof(double));
	clusterDt	= malloc(N*sizeof(cluster));
	clusterSQDt	= malloc(N*sizeof(cluster));

	/* Inizializzazione strutture cluster jackknife */
	for(Dt=0; Dt<N; Dt++)
	{
		cluster_init(clusterDt+Dt,Nbins);
		cluster_init(clusterSQDt+Dt,Nbins);
	}
	cluster_init(&DEtemp,Nbins);
	cluster_init(&EMtemp,Nbins);

	srand(time(NULL));
	rlxd_init(1,rand());

	/* Scelta di inizializzazione "a freddo" o "a caldo" dello stato iniziale */
	choice = atoi(argv[1]);
	switch(choice)
	{
		case 1:
			cold_init(state,N);
			sprintf(file_action, "harmosc/action_coldinit.dat");
			break;

		case 2:
			hot_init(state,N);
			sprintf(file_action, "harmosc/action_hotinit.dat");
			break;
	}
	out_action	= fopen(file_action,"w");

	cold_init(Vtemp,N);

	fprintf(out_action,\
		"#\n# Azione euclidea ad ogni sweep dell'algoritmo Metropolis\n");
	fprintf(out_action,"# Le colonne sono:\n");
	fprintf(out_action,"# Sweep\t azione\n#\n");


	/* Valuto l'azione del sistema nella configurazione iniziale
	 * (dipenderà dal tipo di inizializzazione di state scelta)
	 */
	action = HOeAction(state,N);
	fprintf(out_action,"%d\t%e\n", -1, action);

	/* Finché non si è raggiunto il tempo di termalizzazione NTH faccio evolvere
	 * il sistema con il Metropolis
	 */
	for(step=0; step<NTH; step++)
	{
		action += HOmetropolis(state,N);
		fprintf(out_action,"%d\t%e\n", step, action);
	}

	bin = 0;
	/* Raggiunto il tempo di termalizzazione, si fa evolvere il sistema per un
	 * numero STEPS di sweeps del Metropolis utilizzando gli stati ottenuti
	 * per il calcolo della correlazione
	 */
	for(step=NTH; step<STEPS+NTH; step++)
	{
		action += HOmetropolis(state,N);
		fprintf(out_action,"%d\t%e\n", step, action);

		for(Dt=0; Dt<N; Dt++)
		{
			Sum = 0;
			Sum1 = 0;
			/* media sul vettore di reticolo (somme su i) di x_i*x_{i+K} e di
			 * x^2_i*x^2_{i+K}
			 */
			for(i=0; i<N; i++)
			{
				Sum  += state[i]*state[(i+Dt)%N];
				Sum1 += state[i]*state[(i+Dt)%N]*state[i]*state[(i+Dt)%N];
			}
			Vtemp[Dt]  += Sum/((double)N);
			Vtemp1[Dt] += Sum1/((double)N);
		}

		/* Salvataggio della media sul bin nell vettore del cluster jackknife */
		if((step-NTH+1)%DBIN == 0)
		{
			for(Dt=0; Dt<N; Dt++)
			{
				clusterDt[Dt].Vec[bin] = Vtemp[Dt]/(double)DBIN;
				Vtemp[Dt] = 0;
				clusterSQDt[Dt].Vec[bin] = Vtemp1[Dt]/(double)DBIN;
				Vtemp1[Dt] = 0;
			}
			bin++;
		}
	}

	Sum = 0; Err = 0;
	/* Calcolo e stampa di media e deviazione standard della media dei 
	 * correlatori.
	 */
	for(Dt=0; Dt<N; Dt++)
	{
		clusterJK(clusterDt+Dt);
		fprintf(out_corr,"%d\t%e\t%e\n", Dt, clusterDt[Dt].Mean, \
			sqrt(clusterDt[Dt].Sigma));
		clusterJK(clusterSQDt+Dt);		
		fprintf(out_corrsq, "%d\t%e\t%e\n", Dt, clusterSQDt[Dt].Mean, \
			sqrt(clusterSQDt[Dt].Sigma));
		
		/* Calcolo l'elemento di matrice di x^2 sul ground state */
		EMtemp = sqrt_jk(clusterSQDt+Dt);
		Sum		+= (EMtemp.Mean)/(EMtemp.Sigma);
		Err		+= 1.0/(EMtemp.Sigma);
	}
	fprintf(out_x2gs, "%e\t%e\n",Sum/Err, sqrt(Err/((double)Nbins)));
	fprintf(out_x2gs, "%e\n", Sum/Err);

	/* Calcolo del gap di energia e degli elementi di matrice con varianze.
	 * Si prendono in considerazione soltanto i correlatori per piccoli
	 * valodi di Dt: i valori centrali non hanno un andamento regolare
	 * (si veda dal plot dei correlatori)
	 */
	for(Dt=2; Dt<NCL; Dt++)
	{
		Sum = 0; Sum1 = 0;
		Err = 0; Err1 = 0;
		
		DEtemp = DeltaE(clusterDt+(Dt-1), clusterDt+Dt, clusterDt+(Dt+1));
		EMtemp = MatrixElementX(&DEtemp, clusterDt+Dt, Dt, N);
			
		/* Si effettua la media pesata di DeltaE per i valori di Dt
		 * presi in considerazione
		 */
		Sum		+= (DEtemp.Mean)/(DEtemp.Sigma);
		Sum1	+= (EMtemp.Mean)/(EMtemp.Sigma);

		Err		+= 1.0/(DEtemp.Sigma);
		Err1	+= 1.0/(EMtemp.Sigma);
	}

	fprintf(out_deltaE_errors,	"%d\t%e\n", STEPS, sqrt(Err/((double)Nbins)));
	fprintf(out_EM_errors,		"%d\t%e\n", STEPS, sqrt(Err1/((double)Nbins)));

	fprintf(out_deltaE,	"%e\n",Sum/Err);
	fprintf(out_EM,		"%e\n",Sum1/Err1);

	/*
	 * Calcolo e stampa delle autocorrelazioni per i correlatori delle x per i
	 * primi TMAX+1 valori di Dt
	 */
	for(t=0; t<TMAX+1; t++)
	{
		autocorrelation(corrDtstep, t, autocorr, N, STEPS);
		for(Dt=0; Dt<DMAX+1; Dt++)
		{
			fprintf(out_autocorr[Dt], "%d\t%e\n", t, autocorr[Dt]);
		}
	}

	for(i=0; i<DMAX+1; i++)
		fclose(out_autocorr[i]);
	for(i=0; i<N; i++)
	{
		free((clusterDt + i)->Vec);
		free((clusterSQDt + i)->Vec);
	}
	free(clusterDt);
	free(clusterSQDt);
	fclose(out_corr);
	fclose(out_action);
	fclose(out_deltaE);
	fclose(out_EM);
	fclose(out_x2gs);
	fclose(out_corrsq);
	fclose(out_deltaE_errors);
	fclose(out_EM_errors);

	exit(EXIT_SUCCESS);
}