Ejemplo n.º 1
0
int PairKIM::get_neigh(void **kimmdl,int *mode,int *request,
                       int *atom, int *numnei, int **nei1atom, double **pRij)
{
   KIM_API_model *pkim = (KIM_API_model *) *kimmdl;

   int kimerror;
   PairKIM *self = (PairKIM *) pkim->get_sim_buffer(&kimerror);

   if (self->kim_model_using_Rij) {
      *pRij = &(self->Rij[0]);
   } else {
      *pRij = 0;
   }


   // subvert KIM api by using direct access to self->list
   //
   // get neighObj from KIM API obj
   // NeighList * neiobj = (NeighList * )
   // (*pkim).get_data_by_index(self->kim_ind_neighObject, &kimerror);
   NeighList * neiobj = self->list;

   // subvert KIM api by using direct acces to self->lmps_local_tot_num_atoms
   //
   //int * pnAtoms = (int *)
   // (*pkim).get_data_by_index(self->kim_ind_numberOfParticles, &kimerror);
   //int nAtoms = *pnAtoms;
   int nAtoms = self->lmps_local_tot_num_atoms;

   int j, jj, inum, *ilist, *numneigh, **firstneigh;
   inum = neiobj->inum;             //# of I atoms neighbors are stored for
   ilist = neiobj->ilist;           //local indices of I atoms
   numneigh = neiobj->numneigh;     // # of J neighbors for each I atom
   firstneigh = neiobj->firstneigh; // ptr to 1st J int value of each I atom

   if (*mode==0){ //iterator mode
      if (*request==1) { //increment iterator
         if (self->kim_iterator_position < inum) {
            *atom = ilist[self->kim_iterator_position];
            *numnei = numneigh[*atom];

            // strip off neighbor mask for molecular systems
            if (!self->lmps_using_molecular)
               *nei1atom = firstneigh[*atom];
            else
            {
               int n = *numnei;
               int *ptr = firstneigh[*atom];
               int *lmps_stripped_neigh_list = self->lmps_stripped_neigh_list;
               for (int i = 0; i < n; i++)
                  lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK;
               *nei1atom = lmps_stripped_neigh_list;
            }

            // set Rij if needed
            if (self->kim_model_using_Rij) {
               double* x = (double *)
                 (*pkim).get_data_by_index(self->kim_ind_coordinates,
                                           &kimerror);
               for (jj=0; jj < *numnei; jj++) {
                  int i = *atom;
                  j = (*nei1atom)[jj];
                  self->Rij[jj*3 +0] = -x[i*3+0] + x[j*3+0];
                  self->Rij[jj*3 +1] = -x[i*3+1] + x[j*3+1];
                  self->Rij[jj*3 +2] = -x[i*3+2] + x[j*3+2];
               }
            }

            // increment iterator
            self->kim_iterator_position++;

            return KIM_STATUS_OK; //successful increment
         } else if (self->kim_iterator_position == inum) {
            *numnei = 0;
            return KIM_STATUS_NEIGH_ITER_PAST_END; //reached end by iterator
         } else if (self->kim_iterator_position > inum || inum < 0){
            self->error->one(FLERR, "KIM neighbor iterator exceeded range");
         }
      } else if (*request == 0){ //restart iterator
         self->kim_iterator_position = 0;
         *numnei = 0;
         return KIM_STATUS_NEIGH_ITER_INIT_OK; //succsesful restart
      }
   } else if (*mode == 1){//locator mode
      //...
      if (*request < inum) {
         *atom = *request;
         *numnei = numneigh[*atom];

         // strip off neighbor mask for molecular systems
         if (!self->lmps_using_molecular)
            *nei1atom = firstneigh[*atom];
         else
         {
            int n = *numnei;
            int *ptr = firstneigh[*atom];
            int *lmps_stripped_neigh_list = self->lmps_stripped_neigh_list;
            for (int i = 0; i < n; i++)
               lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK;
            *nei1atom = lmps_stripped_neigh_list;
         }

         // set Rij if needed
         if (self->kim_model_using_Rij){
            double* x = (double *)
              (*pkim).get_data_by_index(self->kim_ind_coordinates, &kimerror);
            for(int jj=0; jj < *numnei; jj++){
               int i = *atom;
               int j = (*nei1atom)[jj];
               self->Rij[jj*3 +0] = -x[i*3+0] + x[j*3+0];
               self->Rij[jj*3 +1] = -x[i*3+1] + x[j*3+1];
               self->Rij[jj*3 +2] = -x[i*3+2] + x[j*3+2];
            }
         }
         return KIM_STATUS_OK; //successful end
      }
      else if (*request >= nAtoms || inum < 0)
         return KIM_STATUS_NEIGH_INVALID_REQUEST;
      else if (*request >= inum) {
         *atom = *request;
         *numnei = 0;
         return KIM_STATUS_OK; //successfull but no neighbors in the list
      }
   } else return KIM_STATUS_NEIGH_INVALID_MODE; //invalid mode

   return -16; //should not get here: unspecified error
}