예제 #1
0
/// \details
/// Call functions such as createFccLattice and setTemperature to set up
/// initial atom positions and momenta.
Atoms* initAtoms(LinkCell* boxes)
{
   Atoms* atoms = comdMalloc(sizeof(Atoms));

   int maxTotalAtoms = MAXATOMS*boxes->nTotalBoxes;

   atoms->gid =      (int*)   comdMalloc(maxTotalAtoms*sizeof(int));
   atoms->iSpecies = (int*)   comdMalloc(maxTotalAtoms*sizeof(int));
   atoms->r =        (real3*) comdMalloc(maxTotalAtoms*sizeof(real3));
   atoms->p =        (real3*) comdMalloc(maxTotalAtoms*sizeof(real3));
   atoms->f =        (real3*) comdMalloc(maxTotalAtoms*sizeof(real3));
   atoms->U =        (real_t*)comdMalloc(maxTotalAtoms*sizeof(real_t));

   atoms->nLocal = 0;
   atoms->nGlobal = 0;

   for (int iOff = 0; iOff < maxTotalAtoms; iOff++)
   {
      atoms->gid[iOff] = 0;
      atoms->iSpecies[iOff] = 0;
      zeroReal3(atoms->r[iOff]);
      zeroReal3(atoms->p[iOff]);
      zeroReal3(atoms->f[iOff]);
      atoms->U[iOff] = 0.;
   }

   return atoms;
}
예제 #2
0
void comd_forceStep (cncTag_t i, cncTag_t iter, BItem b1, comdCtx *ctx) {

    struct box *b = b1;
    if (i == 0)
    printf("CnC: 0 forceStep %lu, %lu\n", i, iter);

    int nbrBoxes[27];

    int nNbrBoxes = getNeighborBoxes1(b, i, nbrBoxes);

    for (int iOff=0; iOff< b->nAtoms; iOff++) {
        zeroReal3(b->atoms.f[iOff]);
        b->atoms.U[iOff] = 0.;
    }

    b->ePot = 0.0;
    b->eKin = 0.0;

//    printf("CnC: 1 forceStep %lu, %lu\n", i, iter);

    cncPrescribe_computeForcefromNeighborsStep(i, nbrBoxes[0], nbrBoxes[1],nbrBoxes[2],nbrBoxes[3],nbrBoxes[4],nbrBoxes[5],nbrBoxes[6],nbrBoxes[7],nbrBoxes[8],nbrBoxes[9],nbrBoxes[10],nbrBoxes[11],nbrBoxes[12],nbrBoxes[14],nbrBoxes[15],nbrBoxes[16],nbrBoxes[17],nbrBoxes[18],nbrBoxes[19],nbrBoxes[20],nbrBoxes[21],nbrBoxes[22],nbrBoxes[23],nbrBoxes[24],nbrBoxes[25],nbrBoxes[26], iter, ctx);

if (ctx->doeam)
      cncPrescribe_computeForcefromNeighborsStep1(i, nbrBoxes[0], nbrBoxes[1],nbrBoxes[2],nbrBoxes[3],nbrBoxes[4],nbrBoxes[5],nbrBoxes[6],nbrBoxes[7],nbrBoxes[8],nbrBoxes[9],nbrBoxes[10],nbrBoxes[11],nbrBoxes[12],nbrBoxes[14],nbrBoxes[15],nbrBoxes[16],nbrBoxes[17],nbrBoxes[18],nbrBoxes[19],nbrBoxes[20],nbrBoxes[21],nbrBoxes[22],nbrBoxes[23],nbrBoxes[24],nbrBoxes[25],nbrBoxes[26], iter, ctx);


//    printf("CnC: 2 forceStep %lu, %lu\n", i, iter);
}
예제 #3
0
/// \details
/// Call functions such as createFccLattice and setTemperature to set up
/// initial atom positions and momenta.
Atoms* initAtoms(LinkCell* boxes, comdCtx *context)
{

   Atoms *atoms;
   atoms = cncItemAlloc(sizeof(*atoms));
   cncPut_ATOMS(atoms, 1, context);

   int maxTotalAtoms = MAXATOMS*boxes->nTotalBoxes;

   atoms->gid = cncItemAlloc(sizeof(*atoms->gid) * maxTotalAtoms);
   cncPut_GID(atoms->gid, 1, context);

   atoms->iSpecies = cncItemAlloc(sizeof(*atoms->iSpecies) * maxTotalAtoms);
   cncPut_ISP(atoms->iSpecies, 1, context);

   atoms->r = cncItemAlloc(sizeof(*atoms->r) * maxTotalAtoms);
   cncPut_R(atoms->r, 1, context);

   atoms->p = cncItemAlloc(sizeof(*atoms->p) * maxTotalAtoms);
   cncPut_P(atoms->p, 1, context);

   atoms->f = cncItemAlloc(sizeof(*atoms->f) * maxTotalAtoms);
   cncPut_F(atoms->f, 1, context);

   atoms->U = cncItemAlloc(sizeof(*atoms->U) * maxTotalAtoms);
   cncPut_U(atoms->U, 1, context);

   atoms->nLocal = 0;
   atoms->nGlobal = 0;

   for (int iOff = 0; iOff < maxTotalAtoms; iOff++)
   {
      atoms->gid[iOff] = 0;
      atoms->iSpecies[iOff] = 0;
      zeroReal3(atoms->r[iOff]);
      zeroReal3(atoms->p[iOff]);
      zeroReal3(atoms->f[iOff]);
      atoms->U[iOff] = 0.;
   }

   return atoms;
}
예제 #4
0
파일: eam.c 프로젝트: kempj/CoMD-tasking
/// Calculate potential energy and forces for the EAM potential.
///
/// Three steps are required:
///
///   -# Loop over all atoms and their neighbors, compute the two-body
///   interaction and the electron density at each atom
///   -# Loop over all atoms, compute the embedding energy and its
///   derivative for each atom
///   -# Loop over all atoms and their neighbors, compute the embedding
///   energy contribution to the force and add to the two-body force
/// 
int eamForce(SimFlat* s)
{
   EamPotential* pot = (EamPotential*) s->pot;
   assert(pot);

   // set up halo exchange and internal storage on first call to forces.
   if (pot->forceExchange == NULL)
   {
      int maxTotalAtoms = MAXATOMS*s->boxes->nTotalBoxes;
      pot->dfEmbed = comdMalloc(maxTotalAtoms*sizeof(real_t));
      pot->rhobar  = comdMalloc(maxTotalAtoms*sizeof(real_t));
      pot->forceExchange = initForceHaloExchange(s->domain, s->boxes);
      pot->forceExchangeData = comdMalloc(sizeof(ForceExchangeData));
      pot->forceExchangeData->dfEmbed = pot->dfEmbed;
      pot->forceExchangeData->boxes = s->boxes;
   }
   
   real_t rCut2 = pot->cutoff*pot->cutoff;
   real_t etot = 0.;

   // zero forces / energy / rho /rhoprime
   int fsize = s->boxes->nTotalBoxes*MAXATOMS;
   //#pragma omp parallel for
   for (int ii=0; ii<fsize; ii++)
   {
      zeroReal3(s->atoms->f[ii]);
      //s->atoms->U[ii] = 0.;//never used
      pot->dfEmbed[ii] = 0.;
      pot->rhobar[ii] = 0.;
   }

   int nNbrBoxes = 27;
   // loop over local boxes
   //#pragma omp parallel for reduction(+:etot)
   for(int iBox=0; iBox<s->boxes->nLocalBoxes; iBox++){
      int nIBox = s->boxes->nAtoms[iBox];
      // loop over neighbor boxes of iBox (some may be halo boxes)
      for(int jTmp=0; jTmp<nNbrBoxes; jTmp++) {
         int jBox = s->boxes->nbrBoxes[iBox][jTmp];
         int nJBox = s->boxes->nAtoms[jBox];
         // loop over atoms in iBox
         for(int iOff=MAXATOMS*iBox; iOff<(iBox*MAXATOMS+nIBox); iOff++) {
            // loop over atoms in jBox
            for(int jOff=MAXATOMS*jBox; jOff<(jBox*MAXATOMS+nJBox); jOff++) {
               real3 dr;
               real_t r2 = 0.0;
               for(int k=0; k<3; k++) {
                  dr[k]=s->atoms->r[iOff][k]-s->atoms->r[jOff][k];
                  r2+=dr[k]*dr[k];
               }
               if(r2 <= rCut2 && r2 > 0.0) {
                  real_t r = sqrt(r2);
                  real_t phiTmp, dPhi, rhoTmp, dRho;
                  interpolate(pot->phi, r, &phiTmp, &dPhi);
                  interpolate(pot->rho, r, &rhoTmp, &dRho);
                  for(int k=0; k<3; k++) {
                     s->atoms->f[iOff][k] -= dPhi*dr[k]/r;
                  }
                  // Calculate energy contribution
                  //s->atoms->U[iOff] += 0.5*phiTmp;//never used
                  etot += 0.5*phiTmp;
                  // accumulate rhobar for each atom
                  pot->rhobar[iOff] += rhoTmp;
               }

            } // loop over atoms in jBox
         } // loop over atoms in iBox
      } // loop over neighbor boxes
   } // loop over local boxes

   // Compute Embedding Energy
   // loop over all local boxes
   //#pragma omp parallel for reduction(+:etot)
   for (int iBox=0; iBox<s->boxes->nLocalBoxes; iBox++) {
      int nIBox =  s->boxes->nAtoms[iBox];

      // loop over atoms in iBox
      for (int iOff=MAXATOMS*iBox; iOff<(MAXATOMS*iBox+nIBox); iOff++)
      {
         real_t fEmbed, dfEmbed;
         interpolate(pot->f, pot->rhobar[iOff], &fEmbed, &dfEmbed);
         pot->dfEmbed[iOff] = dfEmbed; // save derivative for halo exchange
         //s->atoms->U[iOff] += fEmbed;//never used
         etot += fEmbed;
      }
   }

   // exchange derivative of the embedding energy with repsect to rhobar
   startTimer(eamHaloTimer);
   haloExchange(pot->forceExchange, pot->forceExchangeData);
   stopTimer(eamHaloTimer);

   // third pass
   // loop over local boxes
   //#pragma omp parallel for
   for (int iBox=0; iBox<s->boxes->nLocalBoxes; iBox++)
   {
      int nIBox = s->boxes->nAtoms[iBox];

      // loop over neighbor boxes of iBox (some may be halo boxes)
      for (int jTmp=0; jTmp<nNbrBoxes; jTmp++)
      {
         int jBox = s->boxes->nbrBoxes[iBox][jTmp];
         int nJBox = s->boxes->nAtoms[jBox];

         // loop over atoms in iBox
         for (int iOff=MAXATOMS*iBox; iOff<(MAXATOMS*iBox+nIBox); iOff++)
         {
            // loop over atoms in jBox
            for (int jOff=MAXATOMS*jBox; jOff<(MAXATOMS*jBox+nJBox); jOff++)
            { 

               real_t r2 = 0.0;
               real3 dr;
               for (int k=0; k<3; k++)
               {
                  dr[k]=s->atoms->r[iOff][k]-s->atoms->r[jOff][k];
                  r2+=dr[k]*dr[k];
               }

               if(r2 <= rCut2 && r2 > 0.0)
               {

                  real_t r = sqrt(r2);

                  real_t rhoTmp, dRho;
                  interpolate(pot->rho, r, &rhoTmp, &dRho);

                  for (int k=0; k<3; k++)
                  {
                     s->atoms->f[iOff][k] -= (pot->dfEmbed[iOff]+pot->dfEmbed[jOff])*dRho*dr[k]/r;
                  }
               }

            } // loop over atoms in jBox
         } // loop over atoms in iBox
      } // loop over neighbor boxes
   } // loop over local boxes

   s->ePotential = (real_t) etot;

   return 0;
}
예제 #5
0
static int ljForce(SimFlat *s)
{
  LjPotential *pot = (LjPotential *)(s -> pot);
  real_t sigma = pot -> sigma;
  real_t epsilon = pot -> epsilon;
  real_t rCut = pot -> cutoff;
  real_t rCut2 = rCut * rCut;
// zero forces and energy
  real_t ePot = 0.0;
  s -> ePotential = 0.0;
  int fSize = s -> boxes -> nTotalBoxes * 64;
  for (int ii = 0; ii < fSize; ++ii) {
    zeroReal3(s -> atoms -> f[ii]);
    s -> atoms -> U[ii] = 0.0;
  }
  real_t s6 = sigma * sigma * sigma * sigma * sigma * sigma;
  real_t rCut6 = s6 / (rCut2 * rCut2 * rCut2);
  real_t eShift = 1.0 * rCut6 * (rCut6 - 1.0);
  int nbrBoxes[27];
// loop over local boxes
  for (int iBox = 0; iBox < s -> boxes -> nLocalBoxes; iBox++) {
    int nIBox = s -> boxes -> nAtoms[iBox];
    if (nIBox == 0) {
      continue; 
    }
    int nNbrBoxes = getNeighborBoxes(s -> boxes,iBox,nbrBoxes);
// loop over neighbors of iBox
    for (int jTmp = 0; jTmp < nNbrBoxes; jTmp++) {
      int jBox = nbrBoxes[jTmp];
      jBox >= 0?((void )0) : __assert_fail("jBox>=0","ljForce.c",159,__PRETTY_FUNCTION__);
      int nJBox = s -> boxes -> nAtoms[jBox];
      if (nJBox == 0) {
        continue; 
      }
// loop over atoms in iBox
      for (int iOff = iBox * 64, ii = 0; ii < nIBox; (ii++ , iOff++)) {
        int iId = s -> atoms -> gid[iOff];
// loop over atoms in jBox
        for (int jOff = 64 * jBox, ij = 0; ij < nJBox; (ij++ , jOff++)) {
          real_t dr[3];
          int jId = s -> atoms -> gid[jOff];
          if (jBox < s -> boxes -> nLocalBoxes && jId <= iId) {
// don't double count local-local pairs.
            continue; 
          }
          real_t r2 = 0.0;
          for (int m = 0; m < 3; m++) {
            dr[m] = s -> atoms -> r[iOff][m] - s -> atoms -> r[jOff][m];
            r2 += dr[m] * dr[m];
          }
          if (r2 > rCut2) {
            continue; 
          }
// Important note:
// from this point on r actually refers to 1.0/r
          r2 = 1.0 / r2;
          real_t r6 = s6 * (r2 * r2 * r2);
          real_t eLocal = r6 * (r6 - 1.0) - eShift;
          s -> atoms -> U[iOff] += 0.5 * eLocal;
          s -> atoms -> U[jOff] += 0.5 * eLocal;
// calculate energy contribution based on whether
// the neighbor box is local or remote
          if (jBox < s -> boxes -> nLocalBoxes) {
            ePot += eLocal;
          }
          else {
            ePot += 0.5 * eLocal;
          }
// different formulation to avoid sqrt computation
          real_t fr = -4.0 * epsilon * r6 * r2 * (12.0 * r6 - 6.0);
          for (int m = 0; m < 3; m++) {
            s -> atoms -> f[iOff][m] -= dr[m] * fr;
            s -> atoms -> f[jOff][m] += dr[m] * fr;
          }
// loop over atoms in jBox
        }
// loop over atoms in iBox
      }
// loop over neighbor boxes
    }
// loop over local boxes in system
  }
  ePot = ePot * 4.0 * epsilon;
  s -> ePotential = ePot;
  return 0;
}
예제 #6
0
파일: ljForce.c 프로젝트: 648trindade/CoMD
int ljForce(SimFlat* s)
{
   LjPotential* pot = (LjPotential *) s->pot;
   real_t sigma = pot->sigma;
   real_t epsilon = pot->epsilon;
   real_t rCut = pot->cutoff;
   real_t rCut2 = rCut*rCut;

   // zero forces and energy
   real_t ePot = 0.0;
   s->ePotential = 0.0;
   int fSize = s->boxes->nTotalBoxes*MAXATOMS;
   #pragma omp parallel for
   for (int ii=0; ii<fSize; ++ii)
   {
      zeroReal3(s->atoms->f[ii]);
      s->atoms->U[ii] = 0.;
   }
   
   real_t s6 = sigma*sigma*sigma*sigma*sigma*sigma;

   real_t rCut6 = s6 / (rCut2*rCut2*rCut2);
   real_t eShift = POT_SHIFT * rCut6 * (rCut6 - 1.0);

   int nNbrBoxes = 27;

   // loop over local boxes
   #pragma omp parallel for reduction(+:ePot)
   for (int iBox=0; iBox<s->boxes->nLocalBoxes; iBox++)
   {
      int nIBox = s->boxes->nAtoms[iBox];
   
      // loop over neighbors of iBox
      for (int jTmp=0; jTmp<nNbrBoxes; jTmp++)
      {
         int jBox = s->boxes->nbrBoxes[iBox][jTmp];
         
         assert(jBox>=0);
         
         int nJBox = s->boxes->nAtoms[jBox];
         
         // loop over atoms in iBox
         for (int iOff=MAXATOMS*iBox; iOff<(iBox*MAXATOMS+nIBox); iOff++)
         {

            // loop over atoms in jBox
            for (int jOff=jBox*MAXATOMS; jOff<(jBox*MAXATOMS+nJBox); jOff++)
            {
               real3 dr;
               real_t r2 = 0.0;
               for (int m=0; m<3; m++)
               {
                  dr[m] = s->atoms->r[iOff][m]-s->atoms->r[jOff][m];
                  r2+=dr[m]*dr[m];
               }

               if ( r2 <= rCut2 && r2 > 0.0)
               {

                  // Important note:
                  // from this point on r actually refers to 1.0/r
                  r2 = 1.0/r2;
                  real_t r6 = s6 * (r2*r2*r2);
                  real_t eLocal = r6 * (r6 - 1.0) - eShift;
                  s->atoms->U[iOff] += 0.5*eLocal;
                  ePot += 0.5*eLocal;

                  // different formulation to avoid sqrt computation
                  real_t fr = - 4.0*epsilon*r6*r2*(12.0*r6 - 6.0);
                  for (int m=0; m<3; m++)
                  {
                     s->atoms->f[iOff][m] -= dr[m]*fr;
                  }
               }
            } // loop over atoms in jBox
         } // loop over atoms in iBox
      } // loop over neighbor boxes
   } // loop over local boxes in system

   ePot = ePot*4.0*epsilon;
   s->ePotential = ePot;

   return 0;
}