void force_LJ(mdsys_t *sys) 
{
    double rsq,ffac;
    double rx,ry,rz;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i,j;
    int natoms=sys->natoms;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    for(i=0; i < natoms-1; ++i) {
        for(j=i+1; j < natoms; ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], b);
            ry=pbc(sys->ry[i] - sys->ry[j], b);
            rz=pbc(sys->rz[i] - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (rsq < csq) {
		double rsqinv = 1/rsq;
		double r6 = rsqinv*rsqinv*rsqinv;
		double pr = p*r6;
		double p6 = 4.0*sys->epsilon*pr;
                double p12 = p6*pr;

		ffac = rsqinv*(12*p12-6*p6);
                
                sys->epot += 0.5*(p12-p6);

                sys->fx[i] += rx*ffac;
                sys->fy[i] += ry*ffac;
                sys->fz[i] += rz*ffac;
                sys->fx[j] -= rx*ffac;
                sys->fy[j] -= ry*ffac;
                sys->fz[j] -= rz*ffac;

            }
        }
    }
}
void force_morse(mdsys_t *sys) 
{
    double rsq,ffac;
    double rx,ry,rz;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i,j;
    int natoms=sys->natoms;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    for(i=0; i < natoms-1; ++i) {
        for(j=i+1; j < natoms; ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], b);
            ry=pbc(sys->ry[i] - sys->ry[j], b);
            rz=pbc(sys->rz[i] - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
			rs = sqrt(rsqi);
			rsq = rx*rx + ry*ry + rz*rz;

	       /* compute force and energy if within cutoff */
	       if (rsq < csq) {

			   esp = exp((-1)*sys->a*(rs-sys->rzero));
			   espq = exp((-1)*sys->a*(rs-sys->rzero)*(rs-sys->rzero));			 
			   
			   ffac = 2*sys->De * (1-esp)*sys->a*esp;
			   sys->epot += sys->De*(1-espq)


                sys->fx[i] += rx*ffac;
                sys->fy[i] += ry*ffac;
                sys->fz[i] += rz*ffac;
                sys->fx[j] -= rx*ffac;
                sys->fy[j] -= ry*ffac;
                sys->fz[j] -= rz*ffac;

            }
        }
    }
}
Esempio n. 3
0
void MyMD::readRestart() {
  FILE *fp=fopen(restfile,"r");
  if(fp) {
    int natoms=atoms->GetNAtoms();
    double index1, index2, index3;
    index1=index2=index3=0;
    for(int i=0; i<natoms; ++i) {
      fscanf(fp,"%lf%lf%lf", &index1, &index2, &index3);
      atoms->SetPosition(i, index1);
      atoms->SetPosition(i+natoms, index2);
      atoms->SetPosition(i+2*natoms, index3);
    }
    for(int i=0; i<natoms; ++i) {
      fscanf(fp,"%lf%lf%lf", &index1, &index2, &index3);
      atoms->SetVelocity(i, index1);
      atoms->SetVelocity(i+natoms,  index2);
      atoms->SetVelocity(i+2*natoms, index3);
    }
    fclose(fp);
    azzero(atoms->GetForce(), 3*nthreads*natoms);
  } else {
    perror("cannot read restart file");
    exit(1);
  }
}
Esempio n. 4
0
/* compute forces */
void force(mdsys_t *sys) 
{
    double r,ffac;
    double rx,ry,rz;
    int i,j;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,sys->natoms);
    azzero(sys->fy,sys->natoms);
    azzero(sys->fz,sys->natoms);

    for(i=0; i < (sys->natoms); ++i) {
        for(j=0; j < (sys->natoms); ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;
            
            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], 0.5*sys->box);
            ry=pbc(sys->ry[i] - sys->ry[j], 0.5*sys->box);
            rz=pbc(sys->rz[i] - sys->rz[j], 0.5*sys->box);
            r = sqrt(rx*rx + ry*ry + rz*rz);
      
            /* compute force and energy if within cutoff */
            if (r < sys->rcut) {
                ffac = -4.0*sys->epsilon*(-12.0*pow(sys->sigma/r,12.0)/r
                                         +6*pow(sys->sigma/r,6.0)/r);
                
                sys->epot += 0.5*4.0*sys->epsilon*(pow(sys->sigma/r,12.0)
                                               -pow(sys->sigma/r,6.0));

                sys->fx[i] += rx/r*ffac;
                sys->fy[i] += ry/r*ffac;
                sys->fz[i] += rz/r*ffac;
            }
        }
    }
}
Esempio n. 5
0
/* compute forces */
void force(mdsys_t *sys) 
{
    double r_c2 = sys->rcut * sys->rcut;
    double c1, c2, c3, c4, sig6;
	double epot;
    int i;

    /* zero energy and forces */
    epot=0.0;
    azzero(sys->fx,sys->natoms);
    azzero(sys->fy,sys->natoms);
    azzero(sys->fz,sys->natoms);

    /* Precalculate some of the constants used in the potential */
    sig6 = (sys->sigma)*(sys->sigma)*(sys->sigma) * (sys->sigma)*(sys->sigma)*(sys->sigma);
    c1   = -24.0  * sys->epsilon * sig6;
    c2   =  48.0  * sys->epsilon * sig6 * sig6;
    c3   =  -4.0  * sys->epsilon * sig6;        // Leading 4.0 includes factor 2
    c4   =   4.0  * sys->epsilon * sig6 * sig6; // for using Newton's 3rd law (Epot)

	
#ifdef _OPENMP
	#pragma omp parallel for private(i) reduction(+:epot)	
#endif
    for(i=0; i < (sys->natoms); ++i) {
		
		int j;
		double r6;
		double rxi, ryi, rzi;
		double fx, fy, fz;
		fx = fy = fz = 0.0;

		rxi = sys->rx[i];
		ryi = sys->ry[i];
		rzi = sys->rz[i];

        for(j=i+1; j < (sys->natoms); ++j) {

			double rx, ry, rz;
    		double r2, ffac;

            /* get distance between particle i and j */
            rx = pbc(rxi - sys->rx[j], 0.5*sys->box);
            ry = pbc(ryi - sys->ry[j], 0.5*sys->box);
            rz = pbc(rzi - sys->rz[j], 0.5*sys->box);

            r2 = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (r2 < r_c2) {
                r6 = r2*r2*r2;

                ffac = (c2 + c1*r6) / (r6*r6*r2);
                epot += (c4 + c3*r6) / (r6*r6);
/*
#ifdef _OPENMP
#pragma omp atomic
#endif
               	sys->fx[i] += rx*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fy[i] += ry*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fz[i] += rz*ffac;
*/
				fx += rx*ffac;
				fy += ry*ffac;
				fz += rz*ffac;

#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fx[j] -= rx*ffac; 
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fy[j] -= ry*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fz[j] -= rz*ffac;

			}

        } /* end loop j */

#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fx[i] += fx; 
#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fy[i] += fy;
#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fz[i] += fz;
		

    } /* end loop i */

	sys->epot = epot;
}
Esempio n. 6
0
/* main */
int main(int argc, char **argv) 
{

    omp_set_num_threads(MY_NUM_THREADS);
    
    clock_t start,end;  //timing variables
    double time_spent;

    int nprint, i;
    char restfile[BLEN], trajfile[BLEN], ergfile[BLEN], line[BLEN];
    FILE *fp,*traj,*erg;
    mdsys_t sys;

    /* read input file */
    if(get_a_line(stdin,line)) return 1;
    sys.natoms=atoi(line);
    if(get_a_line(stdin,line)) return 1;
    sys.mass=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.epsilon=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.sigma=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.rcut=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.box=atof(line);
    if(get_a_line(stdin,restfile)) return 1;
    if(get_a_line(stdin,trajfile)) return 1;
    if(get_a_line(stdin,ergfile)) return 1;
    if(get_a_line(stdin,line)) return 1;
    sys.nsteps=atoi(line);
    if(get_a_line(stdin,line)) return 1;
    sys.dt=atof(line);
    if(get_a_line(stdin,line)) return 1;
    nprint=atoi(line);

    /* allocate memory */
    sys.rx=(double *)malloc(sys.natoms*sizeof(double));
    sys.ry=(double *)malloc(sys.natoms*sizeof(double));
    sys.rz=(double *)malloc(sys.natoms*sizeof(double));
    sys.vx=(double *)malloc(sys.natoms*sizeof(double));
    sys.vy=(double *)malloc(sys.natoms*sizeof(double));
    sys.vz=(double *)malloc(sys.natoms*sizeof(double));
    sys.fx=(double *)malloc(sys.natoms*sizeof(double));
    sys.fy=(double *)malloc(sys.natoms*sizeof(double));
    sys.fz=(double *)malloc(sys.natoms*sizeof(double));

    /* read restart */
    fp=fopen(restfile,"r");
    if(fp) {
        for (i=0; i<sys.natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.rx+i, sys.ry+i, sys.rz+i);
        }
        for (i=0; i<sys.natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.vx+i, sys.vy+i, sys.vz+i);
        }
        fclose(fp);
        azzero(sys.fx, sys.natoms);
        azzero(sys.fy, sys.natoms);
        azzero(sys.fz, sys.natoms);
    } else {
        perror("cannot read restart file");
        return 3;
    }

    /* initialize forces and energies.*/
    sys.nfi=0;
    force(&sys);
    ekin(&sys);
    
    erg=fopen(ergfile,"w");
    traj=fopen(trajfile,"w");

    printf("Starting simulation with %d atoms for %d steps.\n",sys.natoms, sys.nsteps);
    printf("     NFI            TEMP            EKIN                 EPOT              ETOT\n");
    output(&sys, erg, traj);

	//Start timing
	start = clock();

    /**************************************************/
    /* main MD loop */
    for(sys.nfi=1; sys.nfi <= sys.nsteps; ++sys.nfi) {

        /* write output, if requested */
        if ((sys.nfi % nprint) == 0)
            output(&sys, erg, traj);

        /* propagate system and recompute energies */

        velverlet1(&sys);	//Velocity verlet Part 1

	/* compute forces and potential energy */
	force(&sys);

        velverlet2(&sys);	//Velocity verlet Part 2

        ekin(&sys);
    }
    /**************************************************/
	end = clock();
	//end timing
    time_spent = (double) (end - start) / CLOCKS_PER_SEC;

    /* clean up: close files, free memory */
    printf("Simulation Done.\n");
    printf("Timing: %f Seconds.\n", time_spent);
    fclose(erg);
    fclose(traj);

    free(sys.rx);
    free(sys.ry);
    free(sys.rz);
    free(sys.vx);
    free(sys.vy);
    free(sys.vz);
    free(sys.fx);
    free(sys.fy);
    free(sys.fz);

    return 0;
}
/* compute LJ forces */
void force_LJ(mdsys_t *sys) 
{
    double pot;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i;
    int natoms=sys->natoms;

    /* zero energy and forces */
    pot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    #pragma omp parallel for default(shared) private(i) reduction(+:pot)
    for(i = 0; i < (natoms - 1); ++i) {
    /* private versions of sys->rx[i] */
    int j;
    double rxi,ryi,rzi;
    rxi = sys->rx[i];
    ryi = sys->ry[i];
    rzi = sys->rz[i];
        for(j = (1 + i); j < natoms; ++j) {
        double rx,ry,rz,rsq;
            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(rxi - sys->rx[j], b);
            ry=pbc(ryi - sys->ry[j], b);
            rz=pbc(rzi - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (rsq < csq) {
		double rsqinv = 1/rsq;
		double r6 = rsqinv*rsqinv*rsqinv;
		double pr = p*r6;
		double p6 = 4.0*sys->epsilon*pr;
                double p12 = p6*pr; 
                double ffac;
		
                ffac = rsqinv*(12*p12-6*p6);
                
                pot += 0.5*(p12-p6);
                
                #pragma omp atomic
                sys->fx[i] += rx*ffac;
                #pragma omp atomic
                sys->fy[i] += ry*ffac;
                #pragma omp atomic
                sys->fz[i] += rz*ffac;
                #pragma omp atomic
                sys->fx[j] -= rx*ffac;
                #pragma omp atomic
                sys->fy[j] -= ry*ffac;
                #pragma omp atomic
                sys->fz[j] -= rz*ffac;
            }
        }
    } 
    sys->epot = pot;
}
/* compute MORSE forces */
void force_morse(mdsys_t *sys) 
{
    double pot;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i;
    int natoms=sys->natoms;

    /* zero energy and forces */
    pot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    #pragma omp parallel for default(shared) private(i) reduction(+:pot)
    for(i = 0; i < (natoms - 1); ++i) {
    /* private versions of sys->rx[i] */
    int j;
    double rxi,ryi,rzi;
    rxi = sys->rx[i];
    ryi = sys->ry[i];
    rzi = sys->rz[i];
    for(j = (1 + i); j < natoms; ++j) {
    double rx,ry,rz,rsq;
    /* particles have no interactions with themselves */
    if (i==j) continue;

    /* get distance between particle i and j */
    rx=pbc(rxi - sys->rx[j], b);
    ry=pbc(ryi - sys->ry[j], b);
    rz=pbc(rzi - sys->rz[j], b);
    rs = sqrt(rsqi);
    rsq = rx*rx + ry*ry + rz*rz;
            
	/* compute force and energy if within cutoff */
    if (rsq < csq) {
				
				esp = exp((-1)*sys->a*(rs-sys->rzero));
				espq = exp((-1)*sys->a*(rs-sys->rzero)*(rs-sys->rzero));
				
				ffac = 2*sys->De * (1-esp)*sys->a*esp;
				pot += sys->De*(1-espq)
                
				sys->fx[i] += rx*ffac;
                #pragma omp atomic
                sys->fy[i] += ry*ffac;
                #pragma omp atomic
                sys->fz[i] += rz*ffac;
                #pragma omp atomic
                sys->fx[j] -= rx*ffac;
                #pragma omp atomic
                sys->fy[j] -= ry*ffac;
                #pragma omp atomic
                sys->fz[j] -= rz*ffac;
            }
        }
    } 
    sys->epot = pot;
}
Esempio n. 9
0
/* main */
int main(int argc, char **argv) 
{
    int nprint, i;
    char restfile[BLEN], trajfile[BLEN], ergfile[BLEN], line[BLEN];
    FILE *fp,*traj,*erg;
    mdsys_t sys;

    /* read input file */
    if(get_me_a_line(stdin,line)) return 1;
    sys.natoms=atoi(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.mass=atof(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.epsilon=atof(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.sigma=atof(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.rcut=atof(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.box=atof(line);
    if(get_me_a_line(stdin,restfile)) return 1;
    if(get_me_a_line(stdin,trajfile)) return 1;
    if(get_me_a_line(stdin,ergfile)) return 1;
    if(get_me_a_line(stdin,line)) return 1;
    sys.nsteps=atoi(line);
    if(get_me_a_line(stdin,line)) return 1;
    sys.dt=atof(line);
    if(get_me_a_line(stdin,line)) return 1;
    nprint=atoi(line);

    /* allocate memory */
    sys.rx=(double *)malloc(sys.natoms*sizeof(double));
    sys.ry=(double *)malloc(sys.natoms*sizeof(double));
    sys.rz=(double *)malloc(sys.natoms*sizeof(double));
    sys.vx=(double *)malloc(sys.natoms*sizeof(double));
    sys.vy=(double *)malloc(sys.natoms*sizeof(double));
    sys.vz=(double *)malloc(sys.natoms*sizeof(double));
    sys.fx=(double *)malloc(sys.natoms*sizeof(double));
    sys.fy=(double *)malloc(sys.natoms*sizeof(double));
    sys.fz=(double *)malloc(sys.natoms*sizeof(double));

    /* read restart */
    fp=fopen(restfile,"r");
    if(fp) {
        for (i=0; i<sys.natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.rx+i, sys.ry+i, sys.rz+i);
        }
        for (i=0; i<sys.natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.vx+i, sys.vy+i, sys.vz+i);
        }
        fclose(fp);
        azzero(sys.fx, sys.natoms);
        azzero(sys.fy, sys.natoms);
        azzero(sys.fz, sys.natoms);
    } else {
        perror("cannot read restart file");
        return 3;
    }

    /* initialize forces and energies.*/
    sys.nfi=0;
    force(&sys);
    ekin(&sys);
    
    erg=fopen(ergfile,"w");
    traj=fopen(trajfile,"w");

    printf("Starting simulation with %d atoms for %d steps.\n",sys.natoms, sys.nsteps);
    printf("     NFI            TEMP            EKIN                 EPOT              ETOT\n");
    output(&sys, erg, traj);

    /**************************************************/
    /* main MD loop */
    for(sys.nfi=1; sys.nfi <= sys.nsteps; ++sys.nfi) {

        /* write output, if requested */
        if ((sys.nfi % nprint) == 0)
            output(&sys, erg, traj);

        /* propagate system and recompute energies */
        velverlet(&sys);
        ekin(&sys);
    }
    /**************************************************/

    /* clean up: close files, free memory */
    printf("Simulation Done.\n");
    fclose(erg);
    fclose(traj);

    free(sys.rx);
    free(sys.ry);
    free(sys.rz);
    free(sys.vx);
    free(sys.vy);
    free(sys.vz);
    free(sys.fx);
    free(sys.fy);
    free(sys.fz);

    return 0;
}
Esempio n. 10
0
/* main */
int main(int argc, char **argv) 
{
    int nprint, i;
    char restfile[BLEN], trajfile[BLEN], ergfile[BLEN], line[BLEN];
    FILE *fp,*traj,*erg;
    mdsys_t sys;

#if defined(_OPENMP)
#pragma omp parallel
    {
        if(0 == omp_get_thread_num()) {
            sys.nthreads=omp_get_num_threads();
            printf("Running OpenMP version using %d threads\n", sys.nthreads);
        }
    }
#else
    sys.nthreads=1;
#endif

    /* read input file */
    if(get_a_line(stdin,line)) return 1;
    sys.natoms=atoi(line);
    if(get_a_line(stdin,line)) return 1;
    sys.mass=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.epsilon=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.sigma=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.rcut=atof(line);
    if(get_a_line(stdin,line)) return 1;
    sys.box=atof(line);
    if(get_a_line(stdin,restfile)) return 1;
    if(get_a_line(stdin,trajfile)) return 1;
    if(get_a_line(stdin,ergfile)) return 1;
    if(get_a_line(stdin,line)) return 1;
    sys.nsteps=atoi(line);
    if(get_a_line(stdin,line)) return 1;
    sys.dt=atof(line);
    if(get_a_line(stdin,line)) return 1;
    nprint=atoi(line);

    /* allocate memory */
    sys.pos=(double *)malloc(3*sys.natoms*sizeof(double));
    sys.vel=(double *)malloc(3*sys.natoms*sizeof(double));
    sys.frc=(double *)malloc(sys.nthreads*3*sys.natoms*sizeof(double));

    /* read restart */
    fp=fopen(restfile,"r");
    if(fp) {
        int natoms;
        natoms=sys.natoms;
        
        for (i=0; i<natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.pos+i, sys.pos+natoms+i, sys.pos+2*natoms+i);
        }
        for (i=0; i<natoms; ++i) {
            fscanf(fp,"%lf%lf%lf",sys.vel+i, sys.vel+natoms+i, sys.vel+2*natoms+i);
        }
        fclose(fp);
        azzero(sys.frc, 3*sys.nthreads*sys.natoms);
    } else {
        perror("cannot read restart file");
        return 3;
    }

    /* initialize forces and energies.*/
    sys.nfi=0;
    sys.clist=NULL;
    sys.plist=NULL;
    updcells(&sys);
    force(&sys);
    ekin(&sys);
    
    erg=fopen(ergfile,"w");
    traj=fopen(trajfile,"w");

    printf("Starting simulation with %d atoms for %d steps.\n",sys.natoms, sys.nsteps);
    printf("     NFI            TEMP            EKIN                 EPOT              ETOT\n");
    output(&sys, erg, traj);

    /**************************************************/
    /* main MD loop */
    for(sys.nfi=1; sys.nfi <= sys.nsteps; ++sys.nfi) {

        /* write output, if requested */
        if ((sys.nfi % nprint) == 0) 
            output(&sys, erg, traj);

        /* propagate system and recompute energies */
        velverlet(&sys);
        ekin(&sys);

        /* update cell list */
        if ((sys.nfi % cellfreq) == 0) 
            updcells(&sys);
    }
    /**************************************************/

    /* clean up: close files, free memory */
    printf("Simulation Done.\n");
    fclose(erg);
    fclose(traj);
    free(sys.pos);
    free(sys.vel);
    free(sys.frc);
    free_cell_list(&sys);

    return 0;
}
Esempio n. 11
0
/* compute forces */
static void force(mdsys_t *sys) 
{
    double epot;

    epot = 0.0;
    
#if defined(_OPENMP)
#pragma omp parallel reduction(+:epot)
#endif
    {
        double c12,c6,boxby2,rcsq;
        double *fx, *fy, *fz;
        const double *rx, *ry, *rz;
        int i, tid, fromidx, toidx, natoms;

        /* precompute some constants */
        c12 = 4.0*sys->epsilon*pow(sys->sigma,12.0);
        c6  = 4.0*sys->epsilon*pow(sys->sigma, 6.0);
        rcsq= sys->rcut * sys->rcut;
        boxby2 = 0.5*sys->box;
        natoms = sys->natoms;
        epot = 0.0;
        
        /* let each thread operate on a different
           part of the enlarged force array */
#if defined(_OPENMP)
        tid=omp_get_thread_num();
#else
        tid=0;
#endif
        fx=sys->frc + (3*tid*natoms);
        azzero(fx,3*natoms);
        fy=sys->frc + ((3*tid+1)*natoms);
        fz=sys->frc + ((3*tid+2)*natoms);
        rx=sys->pos;
        ry=sys->pos + natoms;
        rz=sys->pos + 2*natoms;

        /* self interaction of atoms in cell */
        for(i=0; i < sys->ncell; i += sys->nthreads) {
            int j;
            const cell_t *c1;

            j = i + tid;
            if (j >= (sys->ncell)) break;
            c1=sys->clist + j;

            for (j=0; j < c1->natoms-1; ++j) {
                int ii,k;
                double rx1, ry1, rz1;

                ii=c1->idxlist[j];
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=j+1; k < c1->natoms; ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;

                    jj=c1->idxlist[k];

                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, sys->box);
                    ry2=pbc(ry1 - ry[jj], boxby2, sys->box);
                    rz2=pbc(rz1 - rz[jj], boxby2, sys->box);
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }    

        /* interaction of atoms in different cells */
        for(i=0; i < sys->npair; i += sys->nthreads) {
            int j;
            const cell_t *c1, *c2;

            j = i + tid;
            if (j >= (sys->npair)) break;
            c1=sys->clist + sys->plist[2*j];
            c2=sys->clist + sys->plist[2*j+1];
        
            for (j=0; j < c1->natoms; ++j) {
                int ii, k;
                double rx1, ry1, rz1;

                ii=c1->idxlist[j];
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=0; k < c2->natoms; ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;
                
                    jj=c2->idxlist[k];
                
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, sys->box);
                    ry2=pbc(ry1 - ry[jj], boxby2, sys->box);
                    rz2=pbc(rz1 - rz[jj], boxby2, sys->box);
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;
                
                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }

        /* before reducing the forces, we have to make sure 
           that all threads are done adding to them. */
#if defined (_OPENMP)
#pragma omp barrier
#endif
        /* set equal chunks of index ranges */
        i = 1 + (3*natoms / sys->nthreads);
        fromidx = tid * i;
        toidx = fromidx + i;
        if (toidx > 3*natoms) toidx = 3*natoms;

        /* reduce forces from threads with tid != 0 into
           the storage of the first thread. since we have
           threads already spawned, we do this in parallel. */
        for (i=1; i < sys->nthreads; ++i) {
            int offs, j;

            offs = 3*i*natoms;

            for (j=fromidx; j < toidx; ++j) {
                sys->frc[j] += sys->frc[offs+j];
            }
        }
    }
    sys->epot = epot;
}
Esempio n. 12
0
void Pair_LJ::ComputeForce(Atoms *atom) 
{
    double epot;
    
#if defined(_OPENMP)
#pragma omp parallel reduction(+:epot)
#endif
    {
        double c12,c6,boxby2,rcsq;
        double *fx, *fy, *fz;
        double *rx, *ry, *rz;
        int i, tid, fromidx, toidx, natoms, nthreads;

        /* precompute some constants */
        c12 = 4.0*epsilon*pow(sigma,12.0);
        c6  = 4.0*epsilon*pow(sigma, 6.0);
        rcsq= atom->GetRadCut() * atom->GetRadCut();
        boxby2 = 0.5*atom->GetBoxSize();
        natoms = atom->GetNAtoms();
        epot = 0.0;
        
        /* let each thread operate on a different
           part of the enlarged force array */
#if defined(_OPENMP)
	nthreads=omp_get_num_threads();
        tid=omp_get_thread_num();
#else
	nthreads=1;
        tid=0;
#endif
        fx=atom->GetForce() + (3*tid*natoms);
        azzero(fx,3*natoms);
        fy=atom->GetForce() + ((3*tid+1)*natoms);
        fz=atom->GetForce() + ((3*tid+2)*natoms);
        rx=atom->GetPosition();
        ry=atom->GetPosition() + natoms;
        rz=atom->GetPosition() + 2*natoms;
	int x;
        /* self interaction of atoms in cell */
        for(i=0; i < atom->GetNCells(); i += nthreads) {
            int j;
	    //            cell_t *c1;
            
            j = x = i + tid;
            if (j >= (atom->GetNCells())) break;
//            c1=atom->clist + j;
//            afc=getlist(j) 
            for (j=0; j < atom->GetCellNAtoms(x)-1; ++j) {
//	    for (j=0; j < GetCellData()-1; ++j) {  
                int ii,k;
                double rx1, ry1, rz1;		
 //               ii=c1->idxlist[j];
		ii=atom->GetCellIndex(x,j);
		
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=j+1; k < atom->GetCellNAtoms(x); ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;

		    jj=atom->GetCellIndex(x,k); 
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, atom->GetBoxSize());
                    ry2=pbc(ry1 - ry[jj], boxby2, atom->GetBoxSize());
                    rz2=pbc(rz1 - rz[jj], boxby2, atom->GetBoxSize());
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }    

        /* interaction of atoms in different cells */
        for(i=0; i < atom->GetNPairs(); i += nthreads) {
            int j;
	    //            const cell_t *c1, *c2;

            j = x = i + tid;
            if (x >= (atom->GetNPairs())) break;
	  
        //    c1=atom->clist + atom->plist[2*x];
        //    c2=atom->clist + atom->plist[2*x+1];
        
            for (j=0; j < atom->GetCellNAtoms(atom->GetPairItem(2*x)); ++j) {
                int ii, k;
                double rx1, ry1, rz1;

                ii=atom->GetCellIndex(atom->GetPairItem(2*x),j);
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=0; k < atom->GetCellNAtoms(atom->GetPairItem(2*x+1)); ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;
                
                   // jj=c2->idxlist[k];
		    
		    jj = atom->GetCellIndex(atom->GetPairItem(2*x+1),k);
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, atom->GetBoxSize());
                    ry2=pbc(ry1 - ry[jj], boxby2, atom->GetBoxSize());
                    rz2=pbc(rz1 - rz[jj], boxby2, atom->GetBoxSize());
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;

                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }

        /* before reducing the forces, we have to make sure 
           that all threads are done adding to them. */
#if defined (_OPENMP)
#pragma omp barrier
#endif
        /* set equal chunks of index ranges */
        i = 1 + (3*natoms / nthreads);
        fromidx = tid * i;
        toidx = fromidx + i;
        if (toidx > 3*natoms) toidx = 3*natoms;

        /* reduce forces from threads with tid != 0 into
           the storage of the first thread. since we have
           threads already spawned, we do this in parallel. */
        for (i=1; i < nthreads; ++i) {
            int offs, j;

            offs = 3*i*natoms;

            for (j=fromidx; j < toidx; ++j) {
  //              atom->frc[j] += atom->frc[offs+j];
	      atom->SetForce(j,atom->GetForce(j)+atom->GetForce(offs+j));

            }
        }
    }
    atom->SetPotEnergy(epot);
}