Exemple #1
0
int main(int argc, char *argv[])
{

	if (argc < 9)
	{
		printf("Usage: %s <N> <eta> <dr> <nequil> <nproduct> <binwidth>\n", argv[0]);
		printf("\t<N>        Number of particles\n");
		printf("\t<rho>      Particle density\n");
		printf("\t<T>        Temperature\n");
		printf("\t<rc>       Lennard-Jones cut-off radius\n");
		printf("\t<dt>       Length of one timestep\n");
		printf("\t<nequil>   Number of equilibration timesteps to be performed\n");
		printf("\t<nproduct> Number of production timesteps to be performed\n");
		printf("\t<binwidth> Width of a bin for correlation length histogram\n");
		exit(EXIT_SUCCESS);
	}

	outGr = fopen("outGr.txt", "w+");
	outTrajectories = fopen("outTrajectories.txt", "w+");
	outAverages = fopen("outAverages.txt", "w+");

	// Parse commandline parameters
	N = atoi(argv[1]);
	rho = atof(argv[2]);
	T = atof(argv[3]);
	rc = atof(argv[4]);
	rc2 = rc*rc;
	dt = atof(argv[5]);
	nequil = atof(argv[6]);
	nproduct = atof(argv[7]);
	nt = nequil+nproduct;
	double tequil = nequil*dt;
	double tproduct = nproduct*dt;
	tmax = nt*dt;

	// Calculate corresponding system parameters
	lx = ly = sqrt((double)N/rho);

	printf("========== PARAMETERS ==========\n");
	printf("Particles:\t\t%d\n", N);
	printf("Density:\t\t%g\n", rho);
	printf("Simulationbox lx:\t%g\n", lx);
	printf("Simulationbox ly:\t%g\n", ly);
	printf("Temperature:\t\t%g\n", T);
	printf("Timestep length:\t%g\n", dt);
	printf("Equilibration steps:\t%d\n", nequil);
	printf("Production steps:\t%d\n", nproduct);
	printf("Total steps:\t%d\n", nt);
	printf("Equilibration time:\t%g\n", tequil);
	printf("Production time:\t%g\n", tproduct);
	printf("Total time:\t\t%g\n", tmax);
	printf("================================\n\n");


	printf("======== INIT PARTICLES ========\n");
	// Initialize arrays for particle positions & velocities
	r = new TVector[N];
	r_next = new TVector[N];
	v = new TVector[N];
	v_next = new TVector[N];

	// Put all particles equally spaced in the box and assign random velocities
	int nrows = sqrt(N);
	double dlx = lx/(double)nrows;
	double dly = ly/(double)nrows;
	vsum = .0;
	vsum2 = 0;
	for (int i = 0; i < N; i++)
	{
		// Positions
		r[i].x = i%nrows*dlx+0.5;
		r[i].y = floor(i/nrows)*dly+0.5;
		// Velocities
		v[i].x = rand_value(-1., 1.);
		v[i].y = rand_value(-1., 1.);
		vsum += v[i];
		vsum2 += v[i].x*v[i].x + v[i].y*v[i].y;
	}
	printf("Center of mass velocity after initialization:\t(%g,%g)\n", vsum.x, vsum.y);
	printf("Kinetic energy after initialization:\t\t%g\n", vsum2);
	printf("Instantaneous temperature after initialization:\t%g\n", vsum2/(2.0*(double)N));
	// Calculate average velocities
	vsum = vsum/(double)N;
	// Scalefactor for velocities to match the desired temperature (we neglect the fact
	// that the whole system with constrained center of mass has only (2N - 2) degrees
	// of freedom and approximate (2N - 2) \approx 2N since we won't run the simulation
	// with less than N = 100 particles.)
	double fs = sqrt(2.0*(double)N*T/vsum2);
	printf("Scaling factor for velocities:\t\t\t%g\n", fs);
	TVector vsumcheck;
	vsumcheck = .0;
	vsum2 = 0;
	for (int i = 0; i < N; i++)
	{
		v[i] = (v[i]-vsum)*fs;
		vsumcheck += v[i];
		vsum2 += v[i].x*v[i].x + v[i].y*v[i].y;
	}
	printf("Center of mass velocity after scaling:\t\t(%g,%g)\n", vsumcheck.x, vsumcheck.y);
	printf("Kinetic energy after scaling:\t\t\t%g\n", vsum2);
	printf("Instantaneous temperature after scaling:\t%g\n", vsum2/(2.0*(double)N));
	print_coords("outCoords_start.txt");
	printf("================================\n\n");


	printf("======== INIT POTENTIAL ========\n");
	// Init the potential
	init_lj_shift();
	F = new TVector[N];
	printf("Potential initialized.\n");
	printf("U(r_c)\t\t= %g\n", u_lj_shift);
	printf("U'(r_c)\t\t= %g\n", u_lj_deriv_shift);
	printf("U_s(r_c)\t= %g\n", u_lj_shifted(rc2));
	printf("U'_s(r_c)\t= %g\n", u_lj_deriv_shifted(rc2));
	printf("================================\n\n");


	printf("======== INIT AVERAGERS ========\n");
	avg_temp.init();
	avg_epot.init();
	avg_ekin.init();
	avg_etot.init();
	avg_vir.init();
	printf("Averagers initialized!\n");

	// Histogram for pair correlation function
	binwidth = atof(argv[8]);				// Width of a histogram-bin
	nbins = ceil(grmax/binwidth);			// Maximum correlation length to be measured should be L/2 due to periodic BC
	bincount = 0;							// Number of counts done on the histogram
	hist = new int[nbins];
	for (int i = 0; i < nbins; i++) {
		hist[i] = 0;
	}
	printf("Using histogram with %d bins of width %f\n", nbins, binwidth);
	printf("================================\n\n");

	printf("======= START INTEGRATION ======\n");
	t = 0;
	fprintf(outTrajectories, "#t\tn\tr_x\t\tr_y\t\tv_x\t\tv_y\n");
	fprintf(outAverages, "#t\tT(t)\t\t<T(t)>\t\tE_tot(T)\t\t<E_tot(T)>\n");
	for (int n = 0; n <= nt; n++)
	{
		if (n == 0)
		{
			printf("Equilibration phase started.\n");
		}
		if (n == nequil)
		{
			printf("Production phase started.\n");
		}

		// Current time
		t = dt*n;
		if(debug) printf("t:\t%6.3f\t\n", t);
		// Calculate all forces
		forces();
		vsum = .0;
		vsum2 = .0;
		// update all particles
		for (int i = 0; i < N; i++)
		{
			// perform leap-frog-integration
			v_next[i] = v[i] + F[i]*dt;
			r_next[i] = r[i] + v_next[i]*dt;
			// Calculate energies
			vsum += v_next[i];
			// vsum2 += v[i].x*v[i].x + v[i].y*v[i].y; // naiv?
			vsum2 += pow(v_next[i].x+v[i].x, 2)/4.0 + pow(v_next[i].y+v[i].y, 2)/4.0; // sophisticated by Frenkel/Smit
			// update particle coordinates
			v[i] = v_next[i];
			r[i] = r_next[i];

			// Write trajectories to a file
			// fprintf(outTrajectories, "%6.3f\t%6d\t%e\t%e\t%e\t%e\n", t, i, r[i].x, r[i].y, v[i].x, v[i].y);
		}

		// Equilibration phase, scale velocities to keep temperature
		if (n < nequil)
		{
			// Rescale velocities every ?? timesteps
			if (n%10 == 0)
			{
				scale_velocities();
			}
		}
		else if (n%nsamp == 0)
		{
			double Tt = vsum2/(2.0*(double)N);
			avg_temp.add(Tt);

			avg_epot.add(epot);
			avg_vir.add(virial);

			double ekin = 0.5*vsum2;
			avg_ekin.add(ekin);

			double etot = (epot + ekin);
			avg_etot.add(etot);

			update_histogram();

			fprintf(outAverages, "%6.3f\t%e\t%e\t%e\t%e\n", t, Tt, avg_temp.average(), etot, avg_etot.average());
		}

		if ((n+1)%(nt/10) == 0 || n == 0) {
			printf("Finished %5d (t = %5.1f) out of %d (t = %g) timesteps: %3.f %% <T> = %g\n", n+1, t, nt, tmax, (double)n/(double)nt*100, avg_temp.average());
		}

		if(debug) printf("\n");
	}
	printf("================================\n\n");

	print_coords("outCoords_end.txt");

	printf("Printing histogram for g(r) & calculating pressure\n");
	fprintf(outGr, "#r\tg(r)\n");
	double p = 0; // Pressure
	for(int i = 0; i < nbins; i++) {
		double R = i*binwidth;
		double area = 2.0*PI*R*binwidth;
		// Multiply g(r) by two, since in the histogram we only counted each pair once, but each pair
		// gives two contributions to g(r)
		double gr = 2.0*(double)hist[i]/(rho*area*(double)bincount*N);
		fprintf(outGr, "%f\t%f\n", R, gr);
		// Calculate other quantities from g(r)
		if (R > 0 && R < rc) {
			double r6i = pow(1.0/R, 6);
			p += gr*2*PI*rho*rho*R*R*48*(r6i*r6i-0.5*r6i)*binwidth/2;
		}
	}
	p = p + rho*avg_temp.average();
	printf("Final pressure P(%g) = %g\n", rho, p);


	FILE *outAvgFinal;
	outAvgFinal = fopen("outAvgFinal.txt", "w+");
	fprintf(outAvgFinal, "#t\t<T(t)>\t\t<E_tot(T)>\trho\t\t1/rho\t\tp\n");
	fprintf(outAvgFinal, "%6.3f\t%e\t%e\t%e\t%e\t%e\n", t, avg_temp.average(), avg_etot.average(), rho, 1.0/rho, p);
	fclose(outAvgFinal); outAvgFinal = NULL;


	delete [] r;
	delete [] r_next;
	delete [] v;
	delete [] v_next;
	delete [] F;
	r = r_next = v = v_next = F = NULL;

	// Close filepointer
	fclose(outGr); outGr = NULL;
	fclose(outTrajectories); outTrajectories = NULL;
	fclose(outAverages); outAverages = NULL;

	exit(EXIT_SUCCESS);
}
Exemple #2
0
gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *re,
                          t_state *state, gmx_enerdata_t *enerd,
                          t_state *state_local, gmx_int64_t step, real time)
{
    int i, j;
    int replica_id = 0;
    int exchange_partner;
    int maxswap = 0;
    /* Number of rounds of exchanges needed to deal with any multiple
     * exchanges. */
    /* Where each replica ends up after the exchange attempt(s). */
    /* The order in which multiple exchanges will occur. */
    gmx_bool bThisReplicaExchanged = FALSE;

    if (MASTER(cr))
    {
        replica_id  = re->repl;
        test_for_replica_exchange(fplog, cr->ms, re, enerd, det(state_local->box), step, time);
        prepare_to_do_exchange(fplog, re->destinations, replica_id, re->nrepl, &maxswap,
                               re->order, re->cyclic, re->incycle, &bThisReplicaExchanged);
    }
    /* Do intra-simulation broadcast so all processors belonging to
     * each simulation know whether they need to participate in
     * collecting the state. Otherwise, they might as well get on with
     * the next thing to do. */
    if (DOMAINDECOMP(cr))
    {
#ifdef GMX_MPI
        MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr),
                  cr->mpi_comm_mygroup);
#endif
    }

    if (bThisReplicaExchanged)
    {
        /* Exchange the states */
        /* Collect the global state on the master node */
        if (DOMAINDECOMP(cr))
        {
            dd_collect_state(cr->dd, state_local, state);
        }
        else
        {
            copy_state_nonatomdata(state_local, state);
        }

        if (MASTER(cr))
        {
            /* There will be only one swap cycle with standard replica
             * exchange, but there may be multiple swap cycles if we
             * allow multiple swaps. */

            for (j = 0; j < maxswap; j++)
            {
                exchange_partner = re->order[replica_id][j];

                if (exchange_partner != replica_id)
                {
                    /* Exchange the global states between the master nodes */
                    if (debug)
                    {
                        fprintf(debug, "Exchanging %d with %d\n", replica_id, exchange_partner);
                    }
                    exchange_state(cr->ms, exchange_partner, state);
                }
            }
            /* For temperature-type replica exchange, we need to scale
             * the velocities. */
            if (re->type == ereTEMP || re->type == ereTL)
            {
                scale_velocities(state, sqrt(re->q[ereTEMP][replica_id]/re->q[ereTEMP][re->destinations[replica_id]]));
            }

        }

        /* With domain decomposition the global state is distributed later */
        if (!DOMAINDECOMP(cr))
        {
            /* Copy the global state to the local state data structure */
            copy_state_nonatomdata(state, state_local);
        }
    }

    return bThisReplicaExchanged;
}
Exemple #3
0
gmx_bool replica_exchange(FILE *fplog,const t_commrec *cr,struct gmx_repl_ex *re,
                          t_state *state,real *ener,
                          t_state *state_local,
                          int step,real time)
{
    gmx_multisim_t *ms;
    int  exchange=-1,shift;
    gmx_bool bExchanged=FALSE;
    
    ms = cr->ms;
  
    if (MASTER(cr))
    {
        exchange = get_replica_exchange(fplog,ms,re,ener,det(state->box),
                                        step,time);
        bExchanged = (exchange >= 0);
    }
    
    if (PAR(cr))
    {
#ifdef GMX_MPI
        MPI_Bcast(&bExchanged,sizeof(gmx_bool),MPI_BYTE,MASTERRANK(cr),
                  cr->mpi_comm_mygroup);
#endif
    }
    
    if (bExchanged)
    {
        /* Exchange the states */

        if (PAR(cr))
        {
            /* Collect the global state on the master node */
            if (DOMAINDECOMP(cr))
            {
                dd_collect_state(cr->dd,state_local,state);
            }
            else
            {
                pd_collect_state(cr,state);
            }
        }
        
        if (MASTER(cr))
        {
            /* Exchange the global states between the master nodes */
            if (debug)
            {
                fprintf(debug,"Exchanging %d with %d\n",ms->sim,exchange);
            }
            exchange_state(ms,exchange,state);
            
            if (re->type == ereTEMP)
            {
                scale_velocities(state,sqrt(re->q[ms->sim]/re->q[exchange]));
            }
        }

        /* With domain decomposition the global state is distributed later */
        if (!DOMAINDECOMP(cr))
        {
            /* Copy the global state to the local state data structure */
            copy_state_nonatomdata(state,state_local);
            
            if (PAR(cr))
            {
                bcast_state(cr,state,FALSE);
            }
        }
    }
        
    return bExchanged;
}