int main(int argc, char * argv[]) { int world_size; int error; int n; int T_todo; int i,j,k,l; int dim; int type; int my_rank; double ratio; int *spin_out, *spin_in; int dest, recv; int swap; double r; int flips; int swap_attempts, swap_success; double *Es ,*Ts, *E_out, *T_out; double *Rs, *R_out; double e_recv, e_mine; double T_max, T_min, T_steps, T_curr, t_recv; spintype *s; MPI_Status status_info; double coupl[3] = {-1,-1,-1}; coupling = coupl; /* Get in Command line Args */ if (argc != 8) { printf("Usage: a.out N dim type T_Min T_step T_max Flips\n"); exit(EXIT_FAILURE); } n = atoi(argv[1]); dim = atoi(argv[2]); type = atoi(argv[3]); T_min = atof(argv[4]); T_steps = atof(argv[5]); T_max = atof(argv[6]); flips = atoi(argv[7]); DEBUGLINE printf("Passed: %d %d %d %lf %lf %lf\n", n, dim, type, T_min, T_steps, T_max); /* Allocate S */ s = malloc(sizeof(spintype)*pow(n,dim)); spin_out = malloc(sizeof(int)* pow(n,dim)); spin_in = malloc(sizeof(int) * pow(n,dim)); if (s == NULL || spin_out == NULL || spin_in == NULL) { printf("Didn't get the memory for S :( \n"); exit(EXIT_FAILURE); } /* Setup */ switch (type) { case 1: setupSqrSystem(s,n, dim); break; case 2: setupTriSystem(s,n, dim); break; default: setupTriSystem(s,n, dim); } initSpins(s, n, dim); MPI_Init(&argc, &argv); //Find out how big the world is swap_attempts =0; swap_success =0; MPI_Comm_size(MPI_COMM_WORLD, &world_size); T_todo = (int)ceil(((T_max - T_min)/T_steps)/world_size); DEBUGLINE printf("EACH HAS %d to do\n", T_todo); if (world_size == 1) { printf("Only got 1 processor... Bailing out\n"); //exit(EXIT_FAILURE); } MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if(my_rank ==0) printf("#Got %d processors \n", world_size); Es = malloc(sizeof(double)*T_todo); Ts = malloc(sizeof(double)*T_todo); Rs = malloc(sizeof(double)*T_todo); if (!Es || !Ts) { printf("Didn't get enough memory"); exit(EXIT_FAILURE); } if (my_rank ==0) { T_out = malloc(sizeof(double) *(world_size*T_todo+GOOD_MEASURE)); for(j=0; j<world_size;j++) { for (i = 0; i < T_todo; i++) { T_out[i+(j*T_todo)] = T_min + (world_size*i +j)* T_steps; // printf("#%d = %lf\n",i+j*T_todo, T_out[i+j*T_todo]); } } } // DEBUGLINE printf("Starting scatter\n", my_rank, j,T_curr); MPI_Scatter(T_out, T_todo, MPI_DOUBLE, Ts, T_todo, MPI_DOUBLE, 0, MPI_COMM_WORLD); // DEBUGLINE printf("%d, Finished Scatter\n has %d to do", my_rank ,T_todo); // for(i=0; i < T_todo; i++) // printf("%d: %lf\n", my_rank, Ts[i]); // //DEBUGLINE printf("%d entering main loop\n", my_rank); for (l = 0; l < T_todo; l++) { T_curr = Ts[l]; // printf("#%d: Running Metroprolis at %lf\n", my_rank, T_curr); swap_success=0; swap_attempts=0; for ( j =0; j < SWAPS; j ++) { //DEBUGLINE printf("#%d: Running Metroprolis run %d at %lf\n", my_rank, j,T_curr); metropolis(s, n, dim, flips, T_curr, &ratio, 0); for (k = 0; k < 2; k++) { /* Prepare spins for transport */ for (i =0; i <pow(n,dim); i++) spin_out[i] = s[i].s; dest = my_rank-1; recv = my_rank +1; e_mine = energy_calc(s,n,dim,0.0); if ((my_rank+1) %2 == k) { if(dest >=0 ) { swap_attempts++; // DEBUGLINE printf("%d: has energy %lf, Partner: %d\n", my_rank, e_mine,dest); MPI_Recv(&t_recv, 1, MPI_DOUBLE, dest, TEMP, MPI_COMM_WORLD, &status_info); MPI_Recv(&e_recv, 1, MPI_DOUBLE, dest, ENERGY, MPI_COMM_WORLD, &status_info); // DEBUGLINE printf("%d: ....Parnter answered\n", my_rank); r = rand(); r = (double)r/RAND_MAX; if (r < exp((1/(kb*T_curr) - 1/(kb*t_recv))*(e_mine - e_recv))) { swap_success++; swap = 1; MPI_Ssend(&swap, 1, MPI_INT, dest, SWAP, MPI_COMM_WORLD); // DEBUGLINE printf("%d: sending to %d\n", my_rank, dest); MPI_Ssend(spin_out, pow(n,dim), MPI_INT, dest, HIGH_T, MPI_COMM_WORLD); // DEBUGLINE printf("%d: Sent\n", my_rank); MPI_Recv(spin_in, pow(n,dim), MPI_INT, dest, LOW_T, MPI_COMM_WORLD, &status_info); } else { swap = 0; //DEBUGLINE printf("%d is at %lf has just rejected %d at %lf\n", my_rank, T_curr, dest, t_recv); MPI_Ssend(&swap, 1, MPI_INT, dest, SWAP, MPI_COMM_WORLD); } } } else { swap=0; if (recv <world_size) { swap_attempts++; MPI_Ssend(&T_curr, 1, MPI_DOUBLE, recv, TEMP, MPI_COMM_WORLD); // DEBUGLINE printf("%d: has energy %lf, Partner %d\n", my_rank, e_mine,recv); MPI_Ssend(&e_mine, 1, MPI_DOUBLE, recv, ENERGY, MPI_COMM_WORLD); // DEBUGLINE printf("%d: ....Parnter answered\n", my_rank); // DEBUGLINE("%d: Waiting for Swap confirmation......\n", my_rank); MPI_Recv(&swap, 1, MPI_INT, recv, SWAP, MPI_COMM_WORLD, &status_info); // DEBUGLINE printf("%d: ....Swap details recieved\n", my_rank); if(swap == 1) { swap_success++; // DEBUGLINE printf("%d: Waiting for data from %d\n", my_rank, recv); MPI_Recv(spin_in, pow(n,dim), MPI_INT, recv, HIGH_T, MPI_COMM_WORLD, &status_info); // DEBUGLINE printf("%d: Swapping\n", my_rank); // DEBUGLINE printf("%d: Recieved\n", my_rank); MPI_Ssend(spin_out, pow(n,dim), MPI_INT, recv, LOW_T, MPI_COMM_WORLD); } } } /* Put new spins into our system */ if (swap==1) { for (i =0; i < pow(n,dim); i++) s[i].s = spin_in[i]; } } metropolis(s, n, dim, flips, T_curr, &ratio, 0); } metropolis(s, n, dim, flips*10, T_curr, &ratio, 0); Es[l] = energy_calc(s, n, dim, 0.0); Rs[l] = (double) swap_success; //Rs[l] = (double) (my_rank==1 || my_rank==2)? (swap_success/2.0):swap_success; Rs[l] = (double) Rs[l]/swap_attempts; if (Rs[l] ==1 ) { printf("#%d: has swapped every time at %lf\n", my_rank, T_curr); } // if (Es[l] == 0) // printf("%d: Zero energy\n", my_rank); Ts[l] = T_curr; } //if (my_rank ==0) { k = world_size*T_todo; E_out = malloc(sizeof(double) *(world_size*T_todo+GOOD_MEASURE)); R_out = malloc(sizeof(double) *(world_size*T_todo+GOOD_MEASURE)); //} DEBUGLINE printf("#GATHERING Es\n"); MPI_Gather(Es, T_todo, MPI_DOUBLE, E_out, T_todo, MPI_DOUBLE, 0, MPI_COMM_WORLD); DEBUGLINE printf("#GATHERING Ts\n"); MPI_Gather(Ts, T_todo, MPI_DOUBLE, T_out, T_todo, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Gather(Rs, T_todo, MPI_DOUBLE, R_out, T_todo, MPI_DOUBLE, 0, MPI_COMM_WORLD); if (my_rank == 0) { for(i =0; i < T_todo*world_size; i++) printf("%lf\t%lf\t%lf\n", T_out[i], E_out[i], R_out[i]); } printf("#%d: My ratio was: %lf\n", my_rank, (double)swap_success/swap_attempts); MPI_Finalize(); return(0); }
int main(int argc, char *argv[]){ long k,q; long i,j,t; /* 追加しました */ unsigned int iseed; //long imax; long mcs; long logcount,logstep, ocount, ocount_all; double delta2[NOMCS+1], delta2z[NOMCS+1], zsl[NOMCS+1]; double delta2av, delta2zav, zslav; double energy[NOMCS+1], energy_s[NOMCS+1]; double energy2[NOMCS+1], energy_s2[NOMCS+1]; double mag_av[NOMCS+1]; double mag_av2[NOMCS+1]; double energy_av, energy2_av, energy_s_av, energy_s2_av; double mag_av_av, mag_av2_av; double G2x_tmp[SL+1], G2y_tmp[SL+1], G2z_tmp[SL+1]; double G2x_all[SL+1], G2y_all[SL+1], G2z_all[SL+1]; double magz_tmp[Mz+1],mag2z_tmp[Mz+1]; double magz_all[Mz+1],mag2z_all[Mz+1]; double d_poly_tmp[Mz+1]; double d_poly_all[Mz+1]; double AC_a_all[M/2+1][SL+1],AC_b_all[M/2+1][SL+1],AC_p_all[M/2+1][SL+1]; double d_a_all[SL+1],d_b_all[SL+1],d_p_all[SL+1]; double c[SL+1],s_zav[Mz+1]; FILE *fp0; FILE *fp1; FILE *fp2; FILE *fp3; FILE *fp4; FILE *fp5; FILE *fp6; FILE *fp7; FILE *fp8; FILE *fp9; FILE *fp10; FILE *fp11; iseed=ISEED; rinit(iseed); transition_prob(K,J,h,T); /* initial distribution */ //もしargumentが特定の値ならばinit_conf()をread_rnd()とread_spin()に置き換える init_conf(M,Mz,SN,SL,s,x,y,z,xdummy,ydummy); logcount=TMCS; logstep=TMCS; //初期配置に置き、カウンターをTMCS分だけ進める for(mcs=1;mcs<TMCSMAX+1;mcs++){ //Thermatizationに達するまで繰り返す update(K,J,SL,SN,M,Mz,s,imsk,x,y,z,xdummy,ydummy); if (nonsolFlag==!1) { update_sol(K,J,h,M,Mz,s); } if(mcs==logcount){ delta2_calc(SL,SN,x,y,z); energy_calc(K,J,h,SL,SN,M,Mz,s,x,y,z); magnetization_calc(M,Mz,s); printf("%ld %d %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f\n", mcs, SL, DELTA2, DELTA2z, zSL, E, E2, Es, Es2, mag, mag2); fflush(stdout); logcount+=logstep; }; }; /* update observation */ logcount=OMCS; logstep=OMCS; for(k=1; k<NOMCS+1; k++){//配列の初期化 delta2[k]=0; energy[k]=0; energy2[k]=0; energy_s[k]=0; energy_s2[k]=0; mag_av[k]=0; mag_av2[k]=0; c[k]=0; s_zav[k]=0; } for(k=0;k<SL+1;k++){//配列の初期化 G2x_tmp[k]=0; G2x_all[k]=0; G2y_tmp[k]=0; G2y_all[k]=0; G2z_tmp[k]=0; G2z_all[k]=0; } ocount=0; ocount_all=0; for(k=1;k<Mz+1;k++){//配列の初期化 magz_tmp[k]=0; magz_all[k]=0; mag2z_tmp[k]=0; mag2z_all[k]=0; d_poly_tmp[k]=0; d_poly_all[k]=0; } for (i=1; i<=M/2; i++) { for (j=1; j<=SL; j++) { AC_a_all[i][j]=0; AC_b_all[i][j]=0; AC_p_all[i][j]=0; } } for (i=1; i<=SL; i++) { d_a_all[i]=0; d_b_all[i]=0; d_p_all[i]=0; } for(mcs=1;mcs<OMCSMAX+1;mcs++){ update(K,J,SL,SN,M,Mz,s,imsk,x,y,z,xdummy,ydummy); if (nonsolFlag==!1) { update_sol(K,J,h,M,Mz,s); } if(mcs==logcount){ ocount++; delta2_calc(SL,SN,x,y,z); energy_calc(K,J,h,SL,SN,M,Mz,s,x,y,z); magnetization_calc(M,Mz,s); G2_calc(SL,SN,G2x,G2y,G2z,x,y,z); magz_calc(M,Mz,s,magz); mag2z_calc(M, Mz, s, mag2z); d_poly_calc(M,Mz,s,d_poly); d_a_calc(SL,M,Mz,s,d_a); d_p_calc(SL,M,Mz,s,d_p); if (escapeACFlag==!1) { ac_a_calc(SL,M,Mz,s,AC_a); } delta2[ocount]=DELTA2; delta2z[ocount]=DELTA2z; zsl[ocount]=zSL; energy[ocount]=E; energy2[ocount]=E2; energy_s[ocount]=Es; energy_s2[ocount]=Es2; mag_av[ocount]=mag; mag_av2[ocount]=mag2; for(k=1;k<SL+1;k++){ G2x_tmp[k]+=G2x[k]; G2y_tmp[k]+=G2y[k]; G2z_tmp[k]+=G2z[k]; } for(k=1;k<Mz+1;k++){ magz_tmp[k]+=magz[k]; mag2z_tmp[k]+=mag2z[k]; d_poly_tmp[k]+=d_poly[k]; } for (i=1; i<=M/2; i++) { for (j=1; j<=SL; j++) { AC_a_all[i][j]+=AC_a[i][j]; } } for (i=1; i<=SL; i++) { d_a_all[i]+=d_a[i]; } if(ocount==NOMCS){ ocount_all++; delta2av=0; delta2zav=0; zslav=0; energy_av=0; energy2_av=0; energy_s_av=0; energy_s2_av=0; mag_av_av=0; mag_av2_av=0; for(k=1;k<NOMCS+1;k++){ delta2av+=delta2[k]; delta2zav+=delta2z[k]; zslav+=zsl[k]; energy_av+=energy[k]; energy2_av+=energy2[k]; energy_s_av+=energy_s[k]; energy_s2_av+=energy_s2[k]; mag_av_av+=mag_av[k]; mag_av2_av+=mag_av2[k]; }; delta2av/=NOMCS; delta2zav/=NOMCS; zslav/=NOMCS; energy_av/=NOMCS; energy2_av/=NOMCS; energy_s_av/=NOMCS; energy_s2_av/=NOMCS; mag_av_av/=NOMCS; mag_av2_av/=NOMCS; for(k=1;k<SL+1;k++){ G2x_tmp[k]/=NOMCS; G2x_all[k]+=G2x_tmp[k]; G2y_tmp[k]/=NOMCS; G2y_all[k]+=G2y_tmp[k]; G2z_tmp[k]/=NOMCS; G2z_all[k]+=G2z_tmp[k]; } for(k=0;k<SL+1;k++){ G2x_tmp[k]=0; G2y_tmp[k]=0; G2z_tmp[k]=0; } for(k=1;k<Mz+1;k++){ magz_tmp[k]/=NOMCS; magz_all[k]+=magz_tmp[k]; mag2z_tmp[k]/=NOMCS; mag2z_all[k]+=mag2z_tmp[k]; d_poly_tmp[k]/=NOMCS; d_poly_all[k]+=d_poly_tmp[k]; } for(k=1;k<Mz+1;k++){ //temporaryな配列の初期化 magz_tmp[k]=0; mag2z_tmp[k]=0; d_poly_tmp[k]=0; } ocount=0; printf("%ld %d %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f %15.12f\n",mcs,SL, delta2av, delta2zav,zslav,energy_av,energy2_av,energy_s_av,energy_s2_av,mag_av_av,mag_av2_av); fflush(stdout); } logcount+=logstep; } } //ファイルへの出力 fname(K,J,M,ISEED); fp0=fopen(file[0],"w"); for(k=1;k<SL+1;k++){ G2x_all[k]/=ocount_all; G2y_all[k]/=ocount_all; G2z_all[k]/=ocount_all; } for(k=1;k<SL+1;k++){ fprintf(fp0,"%ld\t %15.15f %15.12f %15.12f\n",k,G2x_all[k], G2y_all[k], G2z_all[k]); } fclose(fp0); fp1=fopen(file[1],"w"); for(k=1;k<Mz+1;k++){ magz_all[k]/=ocount_all; } for(k=1;k<Mz+1;k++){ fprintf(fp1,"%ld\t %15.15f\n",k,magz_all[k]); } fclose(fp1); fp2=fopen(file[2],"w"); for(j=1;j<SN+1;j++){ for(t=1;t<SL+1;t++){ fprintf(fp2,"%ld %ld %d %d %d\n",j,t,x[j][t],y[j][t],z[j][t]); } } fclose(fp2); fp3=fopen(file[3],"w"); for(j=1;j<SN+1;j++){ for(t=1;t<SL+1;t++){ fprintf(fp3,"%ld %ld %d %d %d\n",j,t,xdummy[j][t],ydummy[j][t],z[j][t]); } } fclose(fp3); fp4=fopen(file[4],"w"); for(k=1;k<Mz+1;k++){ d_poly_all[k]/=ocount_all; } for(k=1;k<Mz+1;k++){ fprintf(fp4,"%ld\t %15.15f\n",k,d_poly_all[k]); } fclose(fp4); fp5=fopen(file[5],"w"); for (i=1; i<=M; i++) { for (j=1; j<=M; j++) { for (k=1; k<=Mz; k++) { s_zav[k]+=s[i][j][k]; } } } for (k=1;k<=Mz; k++) { s_zav[k]/=(M*M); } for (q=1; q<=SL; q++) { for (k=1; k<=SL; k++) { c[q]+=s_zav[k]*s_zav[k+q]; } c[q]=c[q]/SL; } for (k=1; k<=SL; k++) { fprintf(fp5,"%ld %f\n",k,c[k]); } fclose(fp5); fp6=fopen(file[6], "w"); fprintf(fp6, "0\t%ld\n",IFORM1); fprintf(fp6, "0\t%ld\n",IFORM2); for (i=1; i<=251; i++) { fprintf(fp6,"%li\t%ld\n",i,IRND[i]); } fclose(fp6); fp7=fopen(file[7], "w"); for (i=1; i<=M; i++) { for (j=1; j<=M; j++) { for (k=1; k<=Mz; k++) { fprintf(fp7, "%ld\t%ld\t%ld\t%d\n",i,j,k,s[i][j][k]); } } } fclose(fp7); fp8=fopen(file[8],"w"); for (i=1; i<=M/2; i++) { for (j=1; j<=SL; j++) { AC_a_all[i][j]/=NOMCS; fprintf(fp8, "%ld\t%ld\t%f\n",i,j,AC_a_all[i][j]); } } fclose(fp8); fp9=fopen(file[9], "w"); for (i=1; i<=SL; i++) { d_a_all[i]/=ocount_all; fprintf(fp9,"%ld\t%f\n",i,d_a_all[i]); } fclose(fp9); fp10=fopen(file[10],"w"); for (i=1; i<=SL; i++) { d_p_all[i]/=ocount_all; fprintf(fp10,"%ld\t%f\n",i,d_p_all[i]); } fclose(fp10); fp11=fopen(file[11], "w"); for(k=1;k<Mz+1;k++){ mag2z_all[k]/=ocount_all; } for(k=1;k<Mz+1;k++){ fprintf(fp1,"%ld\t %15.15f\n",k,mag2z_all[k]-magz_all[k]*magz_all[k]); } fclose(fp11); return EXIT_SUCCESS; }