예제 #1
0
int get_KIM_model_has_flags()
{
  void* pkim;
  int status;

  /* get KIM API object representing the KIM Model only */
  status = KIM_API_model_info(&pkim, g_kim.kim_model_name);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_info", status);
    return(status);
  }

  /* determine if the KIM Model can compute the total energy */
  KIM_API_get_index(pkim, (char*) "energy", &status);
  g_kim.kim_model_has_energy = (status == KIM_STATUS_OK);

  /* determine if the KIM Model can compute the forces */
  KIM_API_get_index(pkim, (char*) "forces", &status);
  g_kim.kim_model_has_forces = (status == KIM_STATUS_OK);

  /* determine if the KIM Model can compute the virial */
  KIM_API_get_index(pkim, (char*) "virial", &status);
  g_kim.kim_model_has_virial = (status == KIM_STATUS_OK);
  KIM_API_get_index(pkim, (char*) "process_dEdr", &status);
  g_kim.kim_model_has_virial = g_kim.kim_model_has_virial || (status == KIM_STATUS_OK);

  /* tear down KIM API object */
  KIM_API_free(&pkim, &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_free", status);
    return(status);
  }

  return KIM_STATUS_OK;
}
예제 #2
0
int setup_KIM_API_object(void** pkim, int Natoms, int Nspecies, char* modelname)
{
  /* local vars */
  int status;

  /* initialize KIM API object */
  status = KIM_API_file_init(pkim, "descriptor.kim", modelname);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_file_init", status);
    return(status);
  }

  /* Allocate memory for each data argument of initialized KIM object */
  KIM_API_allocate(*pkim, Natoms, Nspecies, &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_allocate", status);
    return(status);
  }

  /* call Model's init routine */
  status = KIM_API_model_init(*pkim);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_init", status);
    return(status);
  }
  return KIM_STATUS_OK;
}
예제 #3
0
/*******************************************************************************
*
*  Get NBC, is_half_neighbors and the computation flags of model
*
*******************************************************************************/
void get_compute_const(void* pkim)
{
  /* local variables */
  int status;
  const char* NBCstr;

  /* NBC */
  status = KIM_API_get_NBC_method(pkim, &NBCstr);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_NBC_method",status);
    exit(1);
  }
  strcpy(g_kim.NBC_method, NBCstr);
  printf("KIM NBC: %s.\n", g_kim.NBC_method);

  /* use half or full neighbor list?  1 = half, 0 =full; this will be used
   * in config.c to build up the neighbor list */
  g_kim.is_half_neighbors = KIM_API_is_half_neighbors(pkim, &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_is_half_neighbors",status);
    exit(1);
  }

  /* model ability flag */
  get_KIM_model_has_flags();

  return;
}
예제 #4
0
int calc_force_KIM(void* pkim, double** energy, double** force, double** virial,
              int useforce, int usestress)
{
  /* local variables */
   int status;

  /* get data */
  KIM_API_getm_data(pkim, &status, 3*3,
                    "energy", energy, 1,
                    "forces", force,  useforce,
                    "virial", virial, usestress);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", status);
    return status;
  }

  /* Call model compute */
  status = KIM_API_model_compute(pkim);
  if (KIM_STATUS_OK > status)
  {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_compute", status);
    return status;
  }

  return KIM_STATUS_OK;
}
/* Initialization function */
int model_init(void *km)
{
   /* Local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double* model_cutoff;
   int ier;

   /* store pointer to compute function in KIM object */
   ier = KIM_API_set_method(pkim, "compute", 1, (func_ptr) &compute);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_set_method", ier);
      return ier;
   }

   /* store model cutoff in KIM object */
   model_cutoff = (double*) KIM_API_get_data(pkim, "cutoff", &ier);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_data", ier);
      return ier;
   }
   *model_cutoff = MODEL_CUTOFF; /* cutoff distance in angstroms */

   ier = KIM_STATUS_OK;
   return ier;
}
예제 #6
0
int setup_neighborlist_KIM_access(void* pkim, NeighObjectType* NeighObject)
{
  /* local variables */
  int status;
  /* register for neighObject */
  KIM_API_setm_data(pkim, &status, 1*4, "neighObject", 1, NeighObject, 1);
  if (KIM_STATUS_OK > status) {
   KIM_API_report_error(__LINE__, __FILE__,"KIM_API_setm_data",status);
    return(status);
   }

  /* register for get_neigh */
  status = KIM_API_set_method(pkim, "get_neigh", 1, (func_ptr) &get_neigh);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__,"KIM_API_set_method",status);
    return(status);
  }
  return KIM_STATUS_OK;
}
예제 #7
0
/******************************************************************************
 * free KIM model and object
 ******************************************************************************/
int free_model_object(void** pkim)
{
	/* local variables */
	int status;

	/* call model destroy */
	status = KIM_API_model_destroy(*pkim);
	if (KIM_STATUS_OK > status) {
		KIM_API_report_error(__LINE__, __FILE__,"KIM_API_model_destroy", status);
		return status;
	}
	/* free KIM objects */
	KIM_API_free(pkim, &status);
	if (KIM_STATUS_OK > status) {
		KIM_API_report_error(__LINE__, __FILE__,"KIM_API_free", status);
		return status;
	}
	return KIM_STATUS_OK;
}
예제 #8
0
/* Reinitialization function */
static int reinit(void *km)
{
   /* Local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double* model_cutoff;
   double* model_epsilon;
   double* model_sigma;
   double* model_cutnorm;
   double* model_Pcutoff;
   double* model_A;
   double* model_B;
   double* model_C;
   double* model_sigmasq;
   double* model_cutsq;
   int ier;

   /* get parameters from KIM object */
   KIM_API_getm_data(pkim, &ier, 10*3,
                     "cutoff",              &model_cutoff,  1,
                     "PARAM_FREE_sigma",    &model_sigma,   1,
                     "PARAM_FREE_epsilon",  &model_epsilon, 1,
                     "PARAM_FREE_cutoff",   &model_Pcutoff, 1,
                     "PARAM_FIXED_cutnorm", &model_cutnorm, 1,
                     "PARAM_FIXED_A",       &model_A,       1,
                     "PARAM_FIXED_B",       &model_B,       1,
                     "PARAM_FIXED_C",       &model_C,       1,
                     "PARAM_FIXED_sigmasq", &model_sigmasq, 1,
                     "PARAM_FIXED_cutsq",   &model_cutsq,   1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
   }

   /* set value of cutoff in KIM object */
   *model_cutoff = *model_Pcutoff;
   /* set value of parameter cutnorm */
   *model_cutnorm = (*model_sigma)/(*model_cutoff);
   /* set value of parameter A */
   *model_A = 12.0*(*model_epsilon)*(-26.0 + 7.0*pow(*model_cutnorm,6))/
      (pow(*model_cutnorm,14)*(*model_sigma)*(*model_sigma));
   /* set value of parameter B */
   *model_B = 96.0*(*model_epsilon)*(7.0 - 2.0*pow(*model_cutnorm,6))/
               (pow(*model_cutnorm,13)*(*model_sigma));
   /* set value of parameter C */
   *model_C = 28.0*(*model_epsilon)*(-13.0 + 4.0*pow(*model_cutnorm,6))/
               pow(*model_cutnorm,12);
   /* set value of parameter sigmasq */
   *model_sigmasq = (*model_sigma)*(*model_sigma);
   /* set value of parameter cutsq */
   *model_cutsq = (*model_cutoff)*(*model_cutoff);

   ier = KIM_STATUS_OK;
   return ier;
}
예제 #9
0
int write_temporary_descriptor_file(char* modelname)
{
	/* local variables */
	void* pkim;
	const char* species[1];
	int status;
	int Nspecies = 1;

  /* create a temporary object*/
  status = KIM_API_model_info(&pkim, modelname);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_info", status);
    return(status);
  }

  /* get the first species supported by the model */
  status = KIM_API_get_model_species(pkim, 0, species);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_model_species", status);
    return(status);
  }

  /* write a temporary `descriptor.kim' file, used only to query model info */
  /* we'll write `descriptor.kim' file with the species reading from potfit later. */
  status = write_descriptor_file(Nspecies, species, 0, 0, 0);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "write_descriptor_file", status);
    return(status);
  }

  /* free the temporary object */
  KIM_API_free(&pkim, &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_free", status);
    return(status);
  }

	return KIM_STATUS_OK;
}
예제 #10
0
int AsapKimPotential::compute_static(void* km)
{
  int ier;
  assert(km != NULL);
  intptr_t* pkim = *((intptr_t**) km);
  assert(pkim != NULL);
  AsapKimPotential *model = (AsapKimPotential *) KIM_API_get_model_buffer(pkim, &ier);
  if (KIM_STATUS_OK > ier)
    {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_model_buffer", ier);
      return ier;
    }
  assert(model != NULL);
  ier = model->compute(km);
  return ier;
}
예제 #11
0
int write_final_descriptor_file(int u_f, int u_s)
{
  int compute_energy;
  int compute_forces;
  int compute_virial;
  int status;

  /* set_compute flag */
  if (!g_kim.kim_model_has_energy) {
    compute_energy = 0;
    error(1,"KIM Model does not provide `energy'.\n");
  } else {
    compute_energy = 1;
  }

  if (u_f) {
    if (g_kim.kim_model_has_forces) {
      compute_forces = 1;
    } else {
      compute_forces = 0;
      error(1,"KIM Model does not provide `forces'.\n");
    }
  }else {
    compute_forces = 0;
  }

  if (u_s) {
    if (g_kim.kim_model_has_virial) {
      compute_virial = 1;
    } else {
      compute_virial = 0;
      error(1,"KIM Model does not provide `virial'.\n");
    }
  }else {
    compute_virial = 0;
  }

  /* write the `descritor.kim' file for this test */
  status = write_descriptor_file(g_param.ntypes, (const char**) g_config.elements,
                              compute_energy, compute_forces, compute_virial);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "write_descriptor_file", status);
    return(status);
  }

  return KIM_STATUS_OK;
}
예제 #12
0
/* destroy function */
static int destroy(void *km)
{
   /* Local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double* model_epsilon;
   double* model_sigma;
   double* model_Pcutoff;
   double* model_cutnorm;
   double* model_A;
   double* model_B;
   double* model_C;
   double* model_sigmasq;
   double* model_cutsq;
   int ier;


   /* get parameters from KIM object */
   KIM_API_getm_data(pkim, &ier, 9*3,
                     "PARAM_FREE_sigma",    &model_sigma,   1,
                     "PARAM_FREE_epsilon",  &model_epsilon, 1,
                     "PARAM_FREE_cutoff",   &model_Pcutoff, 1,
                     "PARAM_FIXED_cutnorm", &model_cutnorm, 1,
                     "PARAM_FIXED_A",       &model_A,       1,
                     "PARAM_FIXED_B",       &model_B,       1,
                     "PARAM_FIXED_C",       &model_C,       1,
                     "PARAM_FIXED_sigmasq", &model_sigmasq, 1,
                     "PARAM_FIXED_cutsq",   &model_cutsq,   1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
   }

   /*free memory for the parameters */
   free(model_sigma);
   free(model_epsilon);
   free(model_Pcutoff);
   free(model_cutnorm);
   free(model_A);
   free(model_B);
   free(model_C);
   free(model_sigmasq);
   free(model_cutsq);

   ier = KIM_STATUS_OK;
   return ier;
}
예제 #13
0
/***************************************************************************
*
* publish KIM parameter
*
* transferred varialbes:
* PotTable: potential table where the potential paramenters are stored
*
***************************************************************************/
int publish_param(void* pkim, FreeParamType* FreeParam, double* PotTable)
{
  /*local variables*/
  int status;
  int i;

  /*publish parameters */
  for (i = 0; i < FreeParam->Nnestedvalue; i++) {
    *FreeParam->nestedvalue[i] = PotTable[i];
  }

  /* reinit KIM model */
  status = KIM_API_model_reinit(pkim);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_reinit", status);
    return status;
  }

  return KIM_STATUS_OK;
}
예제 #14
0
/***************************************************************************
*
* publsih cutoff
*
***************************************************************************/
int publish_cutoff(void* pkim, double cutoff)
{
  /* local variable */
  int status;
  double* pcutoff;

  /* update cutoff */
  pcutoff = KIM_API_get_data(pkim, "PARAM_FREE_cutoff", &status);
  if (KIM_STATUS_OK != status) {
  warning("Publish cutoff to KIM failed. The cutoff in the KIM Model is used.\n"
          "Possibly the KIM Model has no 'PARAM_FREE_cutoff'.\n\n");
  } else {
    *pcutoff = cutoff;
    /* reinit KIM model */
    status = KIM_API_model_reinit(pkim);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_model_reinit", status);
      return status;
    }
  }

  return KIM_STATUS_OK;
}
/* compute function */
static int compute(void* km)
{
   /* local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double R;
   double Rsqij;
   double phi;
   double dphi;
   double dEidr = 0.0;
   double Rij[DIM];
   int ier;
   int i;
   int j;
   int jj;
   int k;
   int numOfPartNeigh;
   int currentPart;
   int comp_energy;
   int comp_force;
   int comp_particleEnergy;
   int comp_virial;
   int IterOrLoca;
   int HalfOrFull;
   int NBC;
   const char* NBCstr;
   int numberContrib;

   int* nParts;
   int* particleSpecies;
   double* Rij_list;
   double* coords;
   double* energy;
   double* force;
   double* particleEnergy;
   double* virial;
   int* neighListOfCurrentPart;
   double* boxSideLengths;
   int* numContrib;


   /* Determine neighbor list boundary condition (NBC) */
   /* and half versus full mode: */
   /*****************************
    * HalfOrFull = 1 -- Half
    *            = 2 -- Full
    *****************************/
   ier = KIM_API_get_NBC_method(pkim, &NBCstr);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_NBC_method", ier);
      return ier;
   }
   if (!strcmp("NEIGH_RVEC_H",NBCstr))
   {
      NBC = 0;
      HalfOrFull = 1;
   }
   else if (!strcmp("NEIGH_PURE_H",NBCstr))
   {
      NBC = 1;
      HalfOrFull = 1;
   }
   else if (!strcmp("NEIGH_RVEC_F",NBCstr))
   {
      NBC = 0;
      HalfOrFull = 2;
   }
   else if (!strcmp("NEIGH_PURE_F",NBCstr))
   {
      NBC = 1;
      HalfOrFull = 2;
   }
   else if (!strcmp("MI_OPBC_H",NBCstr))
   {
      NBC = 2;
      HalfOrFull = 1;
   }
   else if (!strcmp("MI_OPBC_F",NBCstr))
   {
      NBC = 2;
      HalfOrFull = 2;
   }
   else if (!strcmp("CLUSTER",NBCstr))
   {
      NBC = 3;
      HalfOrFull = 1;
   }
   else
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "Unknown NBC method", ier);
      return ier;
   }

   /* determine neighbor list handling mode */
   if (NBC != 3)
   {
      /*****************************
       * IterOrLoca = 1 -- Iterator
       *            = 2 -- Locator
       *****************************/
      IterOrLoca = KIM_API_get_neigh_mode(pkim, &ier);
      if (KIM_STATUS_OK > ier)
      {
         KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_neigh_mode", ier);
         return ier;
      }
      if ((IterOrLoca != 1) && (IterOrLoca != 2))
      {
         printf("* ERROR: Unsupported IterOrLoca mode = %i\n", IterOrLoca);
         return KIM_STATUS_FAIL;
      }
   }
   else
   {
      IterOrLoca = 2;   /* for CLUSTER NBC */
   }

   /* check to see if we have been asked to compute the forces, particleEnergy, energy and virial */
   KIM_API_getm_compute(pkim, &ier, 4*3,
                        "energy",         &comp_energy,         1,
                        "forces",         &comp_force,          1,
                        "particleEnergy", &comp_particleEnergy, 1,
                        "virial",         &comp_virial,         1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_compute", ier);
      return ier;
   }

   /* unpack data from KIM object */
   KIM_API_getm_data(pkim, &ier, 9*3,
                     "numberOfParticles",           &nParts,         1,
                     "particleSpecies",             &particleSpecies,1,
                     "coordinates",                 &coords,         1,
                     "numberContributingParticles", &numContrib,     (HalfOrFull==1),
                     "boxSideLengths",              &boxSideLengths, (NBC==2),
                     "energy",                      &energy,         (comp_energy==1),
                     "forces",                      &force,          (comp_force==1),
                     "particleEnergy",              &particleEnergy, (comp_particleEnergy==1),
                     "virial",                      &virial,         (comp_virial==1));
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
   }

   if (HalfOrFull == 1)
   {
      if (3 != NBC) /* non-CLUSTER cases */
      {
         numberContrib = *numContrib;
      }
      else
      {
         numberContrib = *nParts;
      }
   }
   else
   { /* provide initialization even if not used */
      numberContrib = *nParts;
   }

   /* Check to be sure that the species are correct */
   /**/
   ier = KIM_STATUS_FAIL; /* assume an error */
   for (i = 0; i < *nParts; ++i)
   {
      if ( SPECCODE != particleSpecies[i])
      {
         KIM_API_report_error(__LINE__, __FILE__, "Unexpected species detected", ier);
         return ier;
      }
   }
   ier = KIM_STATUS_OK; /* everything is ok */

   /* initialize potential energies, forces, and virial term */
   if (comp_particleEnergy)
   {
      for (i = 0; i < *nParts; ++i)
      {
         particleEnergy[i] = 0.0;
      }
   }
   if (comp_energy)
   {
      *energy = 0.0;
   }

   if (comp_force)
   {
      for (i = 0; i < *nParts; ++i)
      {
         for (k = 0; k < DIM; ++k)
         {
            force[i*DIM + k] = 0.0;
         }
      }
   }

   if (comp_virial)
   {
      for (i = 0; i < 6; ++i)
      {
         virial[i] = 0.0;
      }
   }

   /* Initialize neighbor handling for CLUSTER NBC */
   if (3 == NBC) /* CLUSTER */
   {
      neighListOfCurrentPart = (int *) malloc((*nParts)*sizeof(int));
   }

   /* Initialize neighbor handling for Iterator mode */

   if (1 == IterOrLoca)
   {
      ier = KIM_API_get_neigh(pkim, 0, 0, &currentPart, &numOfPartNeigh,
                               &neighListOfCurrentPart, &Rij_list);
      /* check for successful initialization */
      if (KIM_STATUS_NEIGH_ITER_INIT_OK != ier)
      {
         KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_neigh", ier);
         ier = KIM_STATUS_FAIL;
         return ier;
      }
   }

   /* Compute energy and forces */

   /* loop over particles and compute enregy and forces */
   i = -1;
   while( 1 )
   {

      /* Set up neighbor list for next particle for all NBC methods */
      if (1 == IterOrLoca) /* ITERATOR mode */
      {
         ier = KIM_API_get_neigh(pkim, 0, 1, &currentPart, &numOfPartNeigh,
                                  &neighListOfCurrentPart, &Rij_list);
         if (KIM_STATUS_NEIGH_ITER_PAST_END == ier) /* the end of the list, terminate loop */
         {
            break;
         }
         if (KIM_STATUS_OK > ier) /* some sort of problem, return */
         {
            KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_neigh", ier);
            return ier;
         }

         i = currentPart;
      }
      else
      {
         i++;
         if (*nParts <= i) /* incremented past end of list, terminate loop */
         {
            break;
         }

         if (3 == NBC)     /* CLUSTER NBC method */
         {
            numOfPartNeigh = *nParts - (i + 1);
            for (k = 0; k < numOfPartNeigh; ++k)
            {
               neighListOfCurrentPart[k] = i + k + 1;
            }
            ier = KIM_STATUS_OK;
         }
         else              /* All other NBCs */
         {
            ier = KIM_API_get_neigh(pkim, 1, i, &currentPart, &numOfPartNeigh,
                                     &neighListOfCurrentPart, &Rij_list);
            if (KIM_STATUS_OK != ier) /* some sort of problem, return */
            {
            KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_neigh", ier);
            ier = KIM_STATUS_FAIL;
            return ier;
            }
         }
      }

      /* loop over the neighbors of particle i */
      for (jj = 0; jj < numOfPartNeigh; ++ jj)
      {

         j = neighListOfCurrentPart[jj]; /* get neighbor ID */

         /* compute relative position vector and squared distance */
         Rsqij = 0.0;
         for (k = 0; k < DIM; ++k)
         {
            if (0 != NBC) /* all methods except NEIGH_RVEC */
            {
               Rij[k] = coords[j*DIM + k] - coords[i*DIM + k];
            }
            else          /* NEIGH_RVEC_F method */
            {
               Rij[k] = Rij_list[jj*DIM + k];
            }

            /* apply periodic boundary conditions if required */
            if (2 == NBC)
            {
               if (abs(Rij[k]) > 0.5*boxSideLengths[k])
               {
                  Rij[k] -= (Rij[k]/fabs(Rij[k]))*boxSideLengths[k];
               }
            }

            /* compute squared distance */
            Rsqij += Rij[k]*Rij[k];
         }

         /* compute energy and force */
         if (Rsqij < MODEL_CUTSQ) /* particles are interacting ? */
         {
            R = sqrt(Rsqij);
            if (comp_force || comp_virial)
            {
               /* compute pair potential and its derivative */
               calc_phi_dphi(R, &phi, &dphi);

               /* compute dEidr */
               if ((1 == HalfOrFull) && (j < numberContrib))
               {
                  /* HALF mode -- double contribution */
                  dEidr = dphi;
               }
               else
               {
                  /* FULL mode -- regular contribution */
                  dEidr = 0.5*dphi;
               }
            }
            else
            {
               /* compute just pair potential */
               calc_phi(R, &phi);
            }

            /* contribution to energy */
            if (comp_particleEnergy)
            {
               particleEnergy[i] += 0.5*phi;
               /* if half list add energy for the other particle in the pair */
               if ((1 == HalfOrFull) && (j < numberContrib)) particleEnergy[j] += 0.5*phi;
            }
            if (comp_energy)
            {
               if ((1 == HalfOrFull) && (j < numberContrib))
               {
                  /* Half mode -- add v to total energy */
                  *energy += phi;
               }
               else
               {
                  /* Full mode -- add half v to total energy */
                  *energy += 0.5*phi;
               }
            }

            /* contribution to virial tensor */
            if (comp_virial)
            {
               /* virial(i,j) = r(i)*r(j)*(dV/dr)/r */
               virial[0] += Rij[0]*Rij[0]*dEidr/R;
               virial[1] += Rij[1]*Rij[1]*dEidr/R;
               virial[2] += Rij[2]*Rij[2]*dEidr/R;
               virial[3] += Rij[1]*Rij[2]*dEidr/R;
               virial[4] += Rij[0]*Rij[2]*dEidr/R;
               virial[5] += Rij[0]*Rij[1]*dEidr/R;
            }

            /* contribution to forces */
            if (comp_force)
            {
               for (k = 0; k < DIM; ++k)
               {
                  force[i*DIM + k] += dEidr*Rij[k]/R; /* accumulate force on particle i */
                  force[j*DIM + k] -= dEidr*Rij[k]/R; /* accumulate force on particle j */
               }
            }
         }
      } /* loop on jj */
   }    /* infinite while loop (terminated by break statements above */


   /* Free temporary storage */
   if (3 == NBC)
   {
      free(neighListOfCurrentPart);
   }

   /* everything is great */
   ier = KIM_STATUS_OK;
   return ier;
}
예제 #16
0
KimParameterProvider::KimParameterProvider(const char *parameter_filename,
                                           intptr_t *pkim)
{
  DEBUGPRINT;
  // Get a list of elements in the simulation.
  int nelements;
  int strlen;
  int ier;
  ier = KIM_API_get_num_sim_species(pkim, &nelements, &strlen);
  if (ier != KIM_STATUS_OK || nelements < 1)
    {
      std::cerr << "KIM_API_get_num_sim_species failed. " << ier << " " << nelements << std::endl;
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_num_sim_species failed.", ier);
      throw AsapError("Failed to get element list from OpenKIM.");
    }
  std::set<string> elements;
  for (int i = 0; i < nelements; i++)
    {
      const char* element;
      ier = KIM_API_get_sim_species(pkim, i, &element);
      string el = string(element);
      elements.insert(el);
      // std::cerr << "Simulation needs element *" << el << "*" << std::endl;
    }

  // Prepare to convert all parameters to other units.
  double energy_conv =  KIM_API_convert_to_act_unit(pkim, "A", "eV", "e",
      "K", "ps", 0.0, 1.0, 0.0, 0.0, 0.0, &ier);
  assert(ier == KIM_STATUS_OK);  // Should not be able to fail.
  double len_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e",
      "K", "ps", 1.0, 0.0, 0.0, 0.0, 0.0, &ier);
  assert(ier == KIM_STATUS_OK);  // Should not be able to fail.
  double inv_len_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e",
      "K", "ps", -1.0, 0.0, 0.0, 0.0, 0.0, &ier);
  assert(ier == KIM_STATUS_OK);  // Should not be able to fail.
  double inv_vol_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e",
      "K", "ps", -3.0, 0.0, 0.0, 0.0, 0.0, &ier);
  assert(ier == KIM_STATUS_OK);  // Should not be able to fail.

  // Read the parameter file.
  std::fstream pstr(parameter_filename, std::fstream::in);
  int numread = -1;
  emt_parameters *p = NULL;
  while(true)
    {
      string word;
      double value;
      pstr >> word >> value;
      //std::cerr << "read(" << word << ")(" << value << ")" << std::endl;
      numread++;
      if (word == "NEWELEMENT")
        {
          string name;
          pstr >> name;
          numread = 0;
          p = new emt_parameters;
          p->Z = (int) value;
          p->gamma1 = 0.0;        // These are calculated later!
          p->gamma2 = 0.0;
          p->name = name;
        }
      else if (word == "V0")
예제 #17
0
void init_object()
{
  /* local variables */
  NeighObjectType* NeighObject;
  int status;
  int u_f;
  int u_s;
  int i;

  /* Allocate memory for KIM objects */
  g_kim.pkimObj = (void**) Malloc(g_config.nconf * sizeof(void *));

  for (i = 0; i < g_config.nconf; i++) {

    /* write descriptor file */
    u_f = g_config.useforce[i];
    u_s = 0;
#if defined(STRESS)
    u_s = g_config.usestress[i];
#endif
    status = write_final_descriptor_file(u_f, u_s);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "write_final_descriptor file", status);
      exit(1);
    }

    /* QUESTION: does each config has the same number of species? e.g. there are
     * two types of species, but a specific config may one have one species). If
     * not, then ntypes below need to be modified from config to config */
    /* Answer: actually this does not need any worry. If there is only one species in
     * the whole configuration, but we let ntypes = 2 in the following function call,
     * we just allocate more memory. But the species code for each atom would be
     * correct(see function init_KIM_API_argument). Then KIM Model would know how to
     * do the force calculation. */

    /* init KIM API object and allocate memory for data argument */
    status = setup_KIM_API_object(&g_kim.pkimObj[i], g_config.inconf[i], g_param.ntypes, g_kim.kim_model_name);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "setup_KIM_API_object", status);
      exit(1);
    }

    /* init KIM API argument values */
    init_KIM_API_argument(g_kim.pkimObj[i], g_config.inconf[i], g_param.ntypes, g_config.cnfstart[i]);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "init_KIM_API_argument", status);
      exit(1);
    }

    /* allocate memory for NeighObject */
    NeighObject = (NeighObjectType*) Malloc(sizeof(NeighObjectType));

		/* register access of neighborlist in KIM API */
    setup_neighborlist_KIM_access(g_kim.pkimObj[i], NeighObject);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "setup_neighborlist_KIM_access", status);
      exit(1);
    }

    /* initialize neighbor list */
    status = init_neighborlist(NeighObject, g_config.inconf[i], g_config.cnfstart[i]);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__,"init_nieghborlist",status);
      exit(1);
    }
  }
}
예제 #18
0
/* Initialization function */
int MODEL_NAME_LC_STR_init_(void *km)
{
   /* Local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double* model_cutoff;
   double* model_cutnorm;
   double* model_epsilon;
   double* model_sigma;
   double* model_Pcutoff;
   double* model_A;
   double* model_B;
   double* model_C;
   double* model_sigmasq;
   double* model_cutsq;
   int ier;

   /* store function pointers in KIM object */
   KIM_API_setm_data(pkim, &ier, 3*4,
                     "compute", 1, &compute, 1,
                     "reinit",  1, &reinit,  1,
                     "destroy", 1, &destroy, 1);

   /* store model cutoff in KIM object */
   model_cutoff = (double*) KIM_API_get_data(pkim, "cutoff", &ier);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_data", ier);
      return ier;
   }
   *model_cutoff = CUTOFF_VALUE_STR

   /* allocate memory */
   model_sigma = (double*) malloc(1*sizeof(double));
   if (NULL == model_sigma)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_epsilon = (double*) malloc(1*sizeof(double));
   if (NULL == model_epsilon)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_Pcutoff = (double*) malloc(1*sizeof(double));
   if (NULL == model_Pcutoff)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_cutnorm = (double*) malloc(1*sizeof(double));
   if (NULL == model_cutnorm)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_A = (double*) malloc(1*sizeof(double));
   if (NULL == model_A)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_B = (double*) malloc(1*sizeof(double));
   if (NULL == model_B)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_C = (double*) malloc(1*sizeof(double));
   if (NULL == model_C)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_sigmasq = (double*) malloc(1*sizeof(double));
   if (NULL == model_sigmasq)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }
   model_cutsq = (double*) malloc(1*sizeof(double));
   if (NULL == model_cutsq)
   {
      ier = KIM_STATUS_FAIL;
      KIM_API_report_error(__LINE__, __FILE__, "malloc", ier);
      return ier;
   }

   /* store parameters in KIM object */
   KIM_API_setm_data(pkim, &ier, 9*4,
                     "PARAM_FREE_sigma",    1, model_sigma,   1,
                     "PARAM_FREE_epsilon",  1, model_epsilon, 1,
                     "PARAM_FREE_cutoff",   1, model_Pcutoff, 1,
                     "PARAM_FIXED_cutnorm", 1, model_cutnorm, 1,
                     "PARAM_FIXED_A",       1, model_A,       1,
                     "PARAM_FIXED_B",       1, model_B,       1,
                     "PARAM_FIXED_C",       1, model_C,       1,
                     "PARAM_FIXED_sigmasq", 1, model_sigmasq, 1,
                     "PARAM_FIXED_cutsq",   1, model_cutsq,   1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_setm_data", ier);
      return ier;
   }

   /* set value of sigma */
   *model_sigma = SIGMA_VALUE_STR
   /* set value of epsilon */
   *model_epsilon = EPSILON_VALUE_STR
   /* set value of parameter cutoff */
   *model_Pcutoff = *model_cutoff;
   /* set value of parameter cutnorm */
   *model_cutnorm = (*model_cutoff)/(*model_sigma);
   /* set value of parameter A */
   *model_A = 12.0*(*model_epsilon)*(-26.0 + 7.0*pow(*model_cutnorm,6))/
      (pow(*model_cutnorm,14)*(*model_sigma)*(*model_sigma));
   /* set value of parameter B */
   *model_B = 96.0*(*model_epsilon)*(7.0 - 2.0*pow(*model_cutnorm,6))/
               (pow(*model_cutnorm,13)*(*model_sigma));
   /* set value of parameter C */
   *model_C = 28.0*(*model_epsilon)*(-13.0 + 4.0*pow(*model_cutnorm,6))/
               pow(*model_cutnorm,12);
   /* set value of parameter sigmasq */
   *model_sigmasq = (*model_sigma)*(*model_sigma);
   /* set value of parameter cutsq */
   *model_cutsq = (*model_cutoff)*(*model_cutoff);

   ier = KIM_STATUS_OK;
   return ier;
}
예제 #19
0
/* compute function */
static int compute(void* km)
{
   /* local variables */
   intptr_t* pkim = *((intptr_t**) km);
   double R;
   double Rsqij;
   double phi;
   double dphi;
   double Rij[DIM];
   int ier;
   int i;
   int j;
   int k;
   int comp_energy;
   int comp_force;
   int comp_particleEnergy;
   int comp_virial;

   int* nAtoms;
   int* particleTypes;
   double* cutoff;
   double* epsilon;
   double* sigma;
   double* A;
   double* B;
   double* C;
   double* cutsq;
   double* coords;
   double* energy;
   double* force;
   double* particleEnergy;
   double* virial;

   /* check to see if we have been asked to compute the forces, particleEnergy, and virial */
   KIM_API_getm_compute(pkim, &ier, 4*3,
                        "energy",         &comp_energy,         1,
                        "forces",         &comp_force,          1,
                        "particleEnergy", &comp_particleEnergy, 1,
                        "virial",         &comp_virial,         1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_compute", ier);
      return ier;
   }

   /* unpack data from KIM object */
   KIM_API_getm_data(pkim, &ier, 7*3,
                     "numberOfParticles", &nAtoms,         1,
                     "particleTypes",     &particleTypes,  1,
                     "energy",            &energy,         comp_energy,
                     "coordinates",       &coords,         1,
                     "forces",            &force,          comp_force,
                     "particleEnergy",    &particleEnergy, comp_particleEnergy,
                     "virial",            &virial,         comp_virial);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
   }

   /* unpack the Model's parameters stored in the KIM API object */
   KIM_API_getm_data(pkim, &ier, 7*3,
                     "cutoff",             &cutoff,  1,
                     "PARAM_FREE_epsilon", &epsilon, 1,
                     "PARAM_FREE_sigma",   &sigma,   1,
                     "PARAM_FIXED_A",      &A,       1,
                     "PARAM_FIXED_B",      &B,       1,
                     "PARAM_FIXED_C",      &C,       1,
                     "PARAM_FIXED_cutsq",  &cutsq,   1);
   if (KIM_STATUS_OK > ier)
   {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
   }

   /* Check to be sure that the atom types are correct */
   /**/
   ier = KIM_STATUS_FAIL; /* assume an error */
   for (i = 0; i < *nAtoms; ++i)
   {
      if ( SPECCODE != particleTypes[i])
      {
         KIM_API_report_error(__LINE__, __FILE__, "Unexpected species type detected", ier);
         return ier;
      }
   }
   ier = KIM_STATUS_OK; /* everything is ok */

   /* initialize potential energies, forces, and virial term */
   if (comp_particleEnergy)
   {
      for (i = 0; i < *nAtoms; ++i)
      {
         particleEnergy[i] = 0.0;
      }
   }
   if (comp_energy)
   {
      *energy = 0.0;
   }

   if (comp_force)
   {
      for (i = 0; i < *nAtoms; ++i)
      {
         for (k = 0; k < DIM; ++k)
         {
            force[i*DIM + k] = 0.0;
         }
      }
   }

   if (comp_virial)
   {
      for (i = 0; i < 6; ++i)
      {
         virial[i] = 0.0;
      }
   }

   /* Compute energy and forces */

   /* We'll use a half list approach                                  */
   /* Don't need to consider the last atom since all its interactions */
   /* are accounted for eariler in the loop                           */
   for (i = 0; i < *nAtoms-1; ++i)
   {
      for (j = i+1; j < *nAtoms; ++j)
      {
         /* compute relative position vector and squared distance */
         Rsqij = 0.0;
         for (k = 0; k < DIM; ++k)
         {
            Rij[k] = coords[j*DIM + k] - coords[i*DIM + k];

            /* compute squared distance */
            Rsqij += Rij[k]*Rij[k];
         }

         /* compute energy and force */
         if (Rsqij < *cutsq) /* particles are interacting ? */
         {
            R = sqrt(Rsqij);
            if (comp_force || comp_virial)
            {
               /* compute pair potential and its derivative */
               calc_phi_dphi(cutoff, epsilon, sigma, A, B, C, R, &phi, &dphi);
            }
            else
            {
               /* compute just pair potential */
               calc_phi(cutoff, epsilon, sigma, A, B, C, R, &phi);
            }

            /* contribution to energy */
            if (comp_particleEnergy)
            {
               particleEnergy[i] += 0.5*phi;
               particleEnergy[j] += 0.5*phi;
            }
            if (comp_energy)
            {
               *energy += phi;
            }

            /* contribution to virial tensor */
            if (comp_virial)
            {
               /* virial(i,j) = r(i)*r(j)*(dV/dr)/r */
               virial[0] += Rij[0]*Rij[0]*dphi/R;
               virial[1] += Rij[1]*Rij[1]*dphi/R;
               virial[2] += Rij[2]*Rij[2]*dphi/R;
               virial[3] += Rij[1]*Rij[2]*dphi/R;
               virial[4] += Rij[0]*Rij[2]*dphi/R;
               virial[5] += Rij[0]*Rij[1]*dphi/R;
            }

            /* contribution to forces */
            if (comp_force)
            {
               for (k = 0; k < DIM; ++k)
               {
                  force[i*DIM + k] += dphi*Rij[k]/R; /* accumulate force on atom i */
                  force[j*DIM + k] -= dphi*Rij[k]/R; /* accumulate force on atom j */
               }
            }
         }
      } /* loop on j */
   }    /* loop on i */

   /* everything is great */
   ier = KIM_STATUS_OK;
   return ier;
}
예제 #20
0
AsapKimPotential::AsapKimPotential(intptr_t *pkim, const char* paramfile_names,
                                   int nmstrlen, int numparamfiles,
                                   bool supportvirial)
{
  CONSTRUCTOR;
  int ier;

  potential = NULL;
  atoms = NULL;
  this->pkim = pkim;
  // Store the parameter file name(s) for later use by reinit.
  this->paramfile_names = new char[nmstrlen * numparamfiles];
  memcpy(this->paramfile_names, paramfile_names, nmstrlen * numparamfiles);
  this->nmstrlen = nmstrlen;
  this->numparamfiles = numparamfiles;
  this->supportvirial = supportvirial;
  // Check for the neighbor list type.
  ier = KIM_API_get_NBC_method(pkim, &NBCstr);
  if (KIM_STATUS_OK > ier)
    {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_NBC_method", ier);
      exit(1);
    }
  if (!strcmp("CLUSTER",NBCstr))
    {
      nblisttype = nbl_cluster;
      need_contrib = false;
    }
  else if (!strcmp("MI_OPBC_H",NBCstr))
    {
      nblisttype = nbl_miopbc_h;
      need_contrib = true;
    }
  else if (!strcmp("MI_OPBC_F",NBCstr))
    {
      nblisttype = nbl_miopbc_f;
      need_contrib = false;
    }
  else if (!strcmp("NEIGH_PURE_H",NBCstr))
    {
      nblisttype = nbl_pure_h;
      need_contrib = true;
    }
  else if (!strcmp("NEIGH_PURE_F",NBCstr))
    {
      nblisttype = nbl_pure_f;
      need_contrib = false;
    }
  else if (!strcmp("NEIGH_RVEC_H",NBCstr))
    {
      nblisttype = nbl_rvec_h;
      need_contrib = true;
    }
  else if (!strcmp("NEIGH_RVEC_F",NBCstr))
    {
      nblisttype = nbl_rvec_f;
      need_contrib = false;
    }
  else
    {
      KIM_API_report_error(__LINE__, __FILE__, "Unknown NBC method", KIM_STATUS_FAIL);
      exit(1);
    }
}
예제 #21
0
int AsapKimPotential::compute(void* km)
{
  int ier;

  assert(potential != NULL);
  assert(pkim = *((intptr_t**) km));   // Sanity check
  double *cutoff = NULL;
  int *nAtoms = NULL;
  int *nTotalAtoms = NULL;
  int* particleSpecies = NULL;

  // Flags indicating what we need to compute.
  int comp_energy;
  int comp_force;
  int comp_particleEnergy;
  int comp_virial = 0;
  int comp_particleVirial = 0;

  // Quantities to be computed
  double *coords = NULL;
  double *energy = NULL;
  double *forces = NULL;
  double *particleEnergy = NULL;
  double *virial = NULL;
  double *particleVirial = NULL;

  /* check to see if we have been asked to compute the forces and particleEnergy */
  /* If we support virials, also check if we should calculate them */
  KIM_API_getm_compute(pkim, &ier, 5*3,
                       "energy",         &comp_energy,         1,
                       "forces",         &comp_force,          1,
                       "particleEnergy", &comp_particleEnergy, 1,
                       "virial",         &comp_virial,         supportvirial,
                       "particleVirial", &comp_particleVirial, supportvirial
  );
  if (KIM_STATUS_OK > ier)
    {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_compute", ier);
      return ier;
    }

  KIM_API_getm_data(pkim, &ier, 10*3,
                    "cutoff",                      &cutoff,          1,
                    "numberOfParticles",           &nTotalAtoms,     1,
                    "numberContributingParticles", &nAtoms,          need_contrib,
                    "particleSpecies",             &particleSpecies, 1,
                    "coordinates",                 &coords,          1,
                    "energy",                      &energy,          comp_energy,
                    "forces",                      &forces,          comp_force,
                    "particleEnergy",              &particleEnergy,  comp_particleEnergy,
                    "virial",                      &virial,          comp_virial,
                    "particleVirial",              &particleVirial,  comp_particleVirial
                    );
  if (KIM_STATUS_OK > ier)
    {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", ier);
      return ier;
    }
  if (!need_contrib)
    nAtoms = nTotalAtoms;

  if (atoms == NULL)
    {
      // First call, create the Atoms interface object
      atoms = new KimAtoms(pkim);
      assert(atoms != NULL);
      atoms->ReInit(*nAtoms, *nTotalAtoms - *nAtoms, coords, particleSpecies);
      potential->SetAtoms(NULL, atoms);
    }
  else
    {
      atoms->ReInit(*nAtoms, *nTotalAtoms - *nAtoms, coords, particleSpecies);
    }

  // Now do the actual computation
  try
  {
      if (comp_particleEnergy)
        {
          const vector<double> &energies_v = potential->GetPotentialEnergies(NULL);
          assert(energies_v.size() == *nAtoms);
          for (int i = 0; i < *nAtoms; i++)
            particleEnergy[i] = energies_v[i];
        }
      if (comp_energy)
        *energy = potential->GetPotentialEnergy(NULL);
      if (comp_particleVirial)
        {
          const vector<SymTensor> &virials = potential->GetVirials(NULL);
          assert(virials.size() == *nTotalAtoms);
          const double *virials_ptr = (double *) &virials[0];
          for (int i = 0; i < 6*(*nTotalAtoms); i++)
            particleVirial[i] = virials_ptr[i];
        }
      if (comp_virial)
        {
          SymTensor v = potential->GetVirial(NULL);
          for (int i = 0; i < 6; i++)
            virial[i] = v[i];
        }
      if (comp_force)
        {
          const vector<Vec> &forces_v = potential->GetForces(NULL);
          assert(forces_v.size() == *nTotalAtoms);
          const double *forces_v_ptr = (double *) &forces_v[0];
          for (int i = 0; i < 3*(*nTotalAtoms); i++)
            forces[i] = forces_v_ptr[i];
        }
  }
  catch (AsapError &e)
  {
      ier = KIM_STATUS_FAIL;
      string msg = e.GetMessage();
      // Will the following line store a pointer to something inside msg? Hopefully not!
      KIM_API_report_error(__LINE__, __FILE__, (char *) msg.c_str(), ier);
      return ier;
  }
  return KIM_STATUS_OK;
}
예제 #22
0
int init_KIM_API_argument(void* pkim, int Natoms, int Nspecies, int start)
{
  /* local vars */
  /* model inputs */
  int* numberOfParticles;
  int* numberOfSpecies;
  int* particleSpecies;
  double* coords;
  int* numberContrib;
  /* other locals */
  const char* NBCstr;
  int NBC;
  int status;
  int species_code;
  int halfflag;
  int i, j;
  double* boxSideLen;
  int which_conf; /* which config we are in? */

  /* determine which neighbor list type to use */
  halfflag = KIM_API_is_half_neighbors(pkim, &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__,"is_half_neighbors", status);
    return(status);
  }

  /* unpack data from KIM object */
  KIM_API_getm_data(pkim, &status, 5*3,
                    "numberOfParticles",   &numberOfParticles,   1,
                    "numberOfSpecies",     &numberOfSpecies,     1,
                    "particleSpecies",     &particleSpecies,     1,
                    "coordinates",         &coords,              1,
           "numberContributingParticles",  &numberContrib, (1==halfflag) );
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", status);
    return status;
  }

  /* set various values */
  *numberOfParticles = Natoms;
  *numberOfSpecies   = Nspecies;
	if (1==halfflag)
		*numberContrib   = Natoms;

  /* set coords values */
  for (i = 0; i < *numberOfParticles; i++) {
    coords[DIM*i]   = g_config.atoms[start+i].pos.x;
    coords[DIM*i+1] = g_config.atoms[start+i].pos.y;
    coords[DIM*i+2] = g_config.atoms[start+i].pos.z;
  }

  /* set species types */
  for (i = 0; i < *numberOfParticles; i++) {
    j = g_config.atoms[start+i].type;
    species_code = KIM_API_get_species_code(pkim, g_config.elements[j], &status);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_species_code", status);
      return status;
    }
    particleSpecies[i] = species_code;
  }

  /* set boxSideLengths if MI_OPBC is used */
  /* determine which NBC is used */
  status = KIM_API_get_NBC_method(pkim, &NBCstr);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_NBC_method", status);
    return status;
  }
  if ((!strcmp("NEIGH_RVEC_H",NBCstr)) || (!strcmp("NEIGH_RVEC_F",NBCstr))) {
    NBC = 0;
  }
  else if ((!strcmp("NEIGH_PURE_H",NBCstr)) || (!strcmp("NEIGH_PURE_F",NBCstr))) {
    NBC = 1;
  }
  else if ((!strcmp("MI_OPBC_H",NBCstr)) || (!strcmp("MI_OPBC_F",NBCstr))) {
    NBC = 2;
  }
  else if (!strcmp("CLUSTER",NBCstr)) {
    NBC = 3;
  }
  else {
    status = KIM_STATUS_FAIL;
    KIM_API_report_error(__LINE__, __FILE__, "Unknown NBC method", status);
    return status;
  }

  if (NBC == 2) {
    which_conf = g_config.atoms[start].conf;
    /* Unpack data from KIM object */
    KIM_API_getm_data(pkim, &status, 1*3, "boxSideLengths", &boxSideLen, 1);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_getm_data", status);
      return status;
    }
    /* set values */
    boxSideLen[0] = g_kim.box_side_len[DIM*which_conf + 0];
    boxSideLen[1] = g_kim.box_side_len[DIM*which_conf + 1];
    boxSideLen[2] = g_kim.box_side_len[DIM*which_conf + 2];
  }


  return KIM_STATUS_OK;
}
예제 #23
0
int read_potential_keyword(pot_table_t* pt, char const* filename, FILE* infile)
{
	/* local variables */
  int   i, j, k, ret_val;
  char  buffer[255], name[255];
  fpos_t startpos;
  FreeParamType FreeParam;
	void* pkim;
  int status;

  /* save starting position */
  fgetpos(infile, &startpos);

  /* scan for "type" keyword */
  buffer[0] = '\0';
  name[0] = '\0';
  do {
    if (NULL == fgets(buffer, 255, infile))
      error(1, "Error while reading KIM potential keyword\n");
    sscanf(buffer, "%s", name);
  } while (strncmp(name, "type", 4) != 0 && !feof(infile));
  if (strncmp(name, "type", 4) != 0) {
    error(1, "Keyword 'type' is missing in file: %s.", filename);
  }
  if (1 > sscanf(buffer, "%*s %s", name))
    error(1, "KIM Model name missing in file: %s.", filename);

  /* copy name*/
  strcpy(g_kim.kim_model_name, name);
  printf("\nKIM Model: %s.\n", g_kim.kim_model_name);

  /* find `check_kim_opt_param' or `num_opt_param'. The two keywords are mutually
	 * exculsive, which comes first will be read, and the other one will be ignored. */
  fsetpos(infile, &startpos);

  do {
    if (NULL == fgets(buffer, 255, infile))
      error(1, "Error while reading KIM potentials\n");
    sscanf(buffer, "%s", name);
  } while (strcmp(name, "check_kim_opt_param") != 0
					 && strcmp(name, "num_opt_param") != 0
           && !feof(infile));

	/* read `check_kim_opt_param' or `num_opt_param' */
	if (strncmp(buffer,"check_kim_opt_param", 19) == 0) {

  	/* create a temporary KIM objects to query the info */
		/* write temporary descriptor file */
		write_temporary_descriptor_file(g_kim.kim_model_name);
		/* create KIM object with 1 atom and 1 species */
		status = setup_KIM_API_object(&pkim, 1, 1, g_kim.kim_model_name);
		if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "setup_KIM_API_object", status);
      exit(1);
    }
		/* initialze the data struct for the free parameters with type double */
		get_free_param_double(pkim, &FreeParam);

		printf(" - The following potential parameters are available to fit. Include the\n"
           "name(s) (and the initial value(s) and the corresponding lower and upper\n"
           "boundaries) that you want to optimize in file: %s.\n",filename);
    printf("         param name                 param extent\n");
    printf("        ############               ##############\n");
    for(k = 0; k < FreeParam.Nparam; k++ ) {
      if (strncmp(FreeParam.name[k], "PARAM_FREE_cutoff", 17) == 0){
        continue;
      }
      printf("     %-35s[ ", FreeParam.name[k]);
      for(j = 0; j < FreeParam.rank[k]; j++) {
        printf("%d ", FreeParam.shape[k][j]);
      }
      printf("]\n");
   }
    printf("\n - Note that empty parameter extent (i.e. '[ ]') indicates that the\n"
           "parameter is a scalar.\n");
    printf(" - Also KIM array parameter is row based. While listing the initial\n"
           "values for such parameter, you should ensure that the sequence is\n"
           "correct. For example, if the extent of a parameter `PARAM_FREE_A' is\n"
           "[ 2 2 ], then you should list the initial values as: A[0 0], A[0 1],\n"
           "A[1 0], A[1 1].\n");

	 /* free the temporary kim model */
	  free_model_object(&pkim);
	  exit(1);

  } else if (strncmp(buffer,"num_opt_param", 13) == 0) {
    if(1 != sscanf(buffer, "%*s%d", &g_kim.num_opt_param)) {
      error(1, "Cannot read 'num_opt_param' in file: %s.", filename);
    }
  } else {
    error(1, "Keyword 'num_opt_param' is missing in file: %s.", filename);
  }

  /* allocate memory */
  g_kim.name_opt_param = (char**)Malloc(g_kim.num_opt_param*sizeof(char*));
  g_kim.size_opt_param = (int*)Malloc(g_kim.num_opt_param*sizeof(int));
  for (i = 0; i < g_kim.num_opt_param; i++) {
    g_kim.name_opt_param[i] = (char *)Malloc(255 * sizeof(char));
  }

	/* find parameter names beginning with `PARAM_FREE_*' */
	fsetpos(infile, &startpos);
	for (j = 0; j < g_kim.num_opt_param; j++) {
		buffer[0] = '\0';
		name[0] = '\0';
		do {
			if (NULL == fgets(buffer, 255, infile))
              error(1, "Error while reading KIM potentials\n");
			ret_val = sscanf(buffer, "%s", name);
		} while (strncmp(name, "PARAM_FREE", 10) != 0 && !feof(infile));
		if (feof(infile) ) {
			error(0, "Not enough parameter(s) 'PARAM_FREE_*' in file: %s.\n", filename);
			error(1, "You listed %d parameter(s), but required are %d.\n", j, g_kim.num_opt_param);
		}
		if (ret_val == 1) {
			strcpy(g_kim.name_opt_param[j], name);
		} else {
			error(0, "parameter '%d' in file '%s' corrupted\n.", j + 1, filename);
			error(1, "Each parameter name should be in a single line.\n");
		}
	}

	return 0;
}
예제 #24
0
int get_neigh(void* kimmdl, int *mode, int *request, int* part,
                       int* numnei, int** nei1part, double** Rij)
{
   /* local variables */
  intptr_t* pkim = *((intptr_t**) kimmdl);
  int partToReturn;
  int status;
  int* numberOfParticles;
  int idx; /* index of first neighbor of each particle*/
  NeighObjectType* nl;

  /* initialize numnei */
  *numnei = 0;

  /* unpack neighbor list object */
  numberOfParticles = (int*) KIM_API_get_data(pkim, "numberOfParticles", &status);
  if (KIM_STATUS_OK > status) {
  KIM_API_report_error(__LINE__, __FILE__,"get_data", status);
  }

  nl = (NeighObjectType*) KIM_API_get_data(pkim, "neighObject", &status);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__,"get_data", status);
  }

  /* check mode and request */
  if (0 == *mode) { /* iterator mode */
    if (0 == *request) { /* reset iterator */
      (*nl).iteratorId = -1;
      return KIM_STATUS_NEIGH_ITER_INIT_OK;
    } else if (1 == *request) { /* increment iterator */
      (*nl).iteratorId++;
      if ((*nl).iteratorId >= *numberOfParticles) {
        return KIM_STATUS_NEIGH_ITER_PAST_END;
      } else {
        partToReturn = (*nl).iteratorId;
      }
    } else { /* invalid request value */
      KIM_API_report_error(__LINE__, __FILE__,"Invalid request in get_periodic_neigh",
                           KIM_STATUS_NEIGH_INVALID_REQUEST);
      return KIM_STATUS_NEIGH_INVALID_REQUEST;
    }
  } else if (1 == *mode) { /* locator mode */
    if ((*request >= *numberOfParticles) || (*request < 0)) { /* invalid id */
      KIM_API_report_error(__LINE__, __FILE__,"Invalid part ID in get_periodic_neigh",
                          KIM_STATUS_PARTICLE_INVALID_ID);
      return KIM_STATUS_PARTICLE_INVALID_ID;
    } else {
      partToReturn = *request;
    }
  } else { /* invalid mode */
    KIM_API_report_error(__LINE__, __FILE__,"Invalid mode in get_periodic_neigh",
                          KIM_STATUS_NEIGH_INVALID_MODE);
    return KIM_STATUS_NEIGH_INVALID_MODE;
  }

  /* index of the first neigh of each particle */
  idx = (*nl).BeginIdx[partToReturn];

  /* set the returned part */
  *part = partToReturn;

  /* set the returned number of neighbors for the returned part */
  *numnei = (*nl).NNeighbors[partToReturn];

  /* set the location for the returned neighbor list */
  *nei1part = &(*nl).neighborList[idx];

  /* set the pointer to Rij to appropriate value */
  *Rij = &(*nl).RijList[DIM*idx];

  return KIM_STATUS_OK;
}
예제 #25
0
int get_free_param_double(void* pkim, FreeParamType* FreeParam)
{
  /*local vars*/
  int status;
  int NumFreeParam;
  int maxStringLength;
  char* pstr;
  char buffer[128];
  char name[64];
  char type[16];
  int NumFreeParamDouble;
  int i;

  /* get the maxStringLength of free parameters */
  status = KIM_API_get_num_free_params(pkim, &NumFreeParam, &maxStringLength);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_num_free_params", status);
    return(status);
  }

  /* get the descriptor file, pointed by pstr. the type of data will be phrased from pstr*/
  status = KIM_API_get_model_kim_str(g_kim.kim_model_name, &pstr);
  if (KIM_STATUS_OK > status) {
    KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_model_kim_str", status);
    return(status);
  }

  /* infinite loop to find PARAM_FREE_* of type `double' */
  /* It's safe to do pstr = strstr(pstr+1,"PARAM_FREE") because the ``PARAM_FREE''
    will never ever occur at the beginning of the ``descriptor.kim'' file */
  FreeParam->name = NULL;
  NumFreeParamDouble = 0;
  while (1) {
    pstr = strstr(pstr+1,"PARAM_FREE");
    if (pstr == NULL) {
      break;
    } else {
      snprintf(buffer, sizeof(buffer), "%s", pstr);
      sscanf(buffer, "%s%s", name, type);
      if (strcmp(type, "double") == 0) {
        NumFreeParamDouble++;
        FreeParam->name = (char**) Realloc(FreeParam->name, (NumFreeParamDouble)*sizeof(char*));

        /*maxStringLength+1 to hold the `\0' at end*/
        FreeParam->name[NumFreeParamDouble - 1] = (char*) Malloc((maxStringLength+1)*sizeof(char));
        strcpy(FreeParam->name[NumFreeParamDouble - 1], name);
      }
    }
  }


  FreeParam->Nparam = NumFreeParamDouble;

  /* allocate memory for value */
  FreeParam->value = (double**) Malloc(FreeParam->Nparam * sizeof(double*));

  /* get the pointer to parameter */
  for(i = 0; i < FreeParam->Nparam; i++ ) {
    FreeParam->value[i] = KIM_API_get_data(pkim, FreeParam->name[i], &status);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_data", status);
      return(status);
    }
  }

  /* allocate memory for rank */
  FreeParam->rank = (int*) Malloc(FreeParam->Nparam * sizeof(int));

	/* get rank */
  for(i = 0; i < FreeParam->Nparam; i++) {
    FreeParam->rank[i] = KIM_API_get_rank(pkim, FreeParam->name[i], &status);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_rank", status);
      return(status);
    }
  }

  /* allocate memory for shape */
  FreeParam->shape = (int**) Malloc(FreeParam->Nparam * sizeof(int*));

	for (i = 0; i < FreeParam->Nparam; i++) {
    if (FreeParam->rank[i] != 0) {
      FreeParam->shape[i] = (int*) Malloc(FreeParam->rank[i] * sizeof(int));
    }
  }
  /* get shape */
  for(i = 0; i < FreeParam->Nparam; i++) {
    KIM_API_get_shape(pkim, FreeParam->name[i], FreeParam->shape[i], &status);
    if (KIM_STATUS_OK > status) {
      KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_shape", status);
      return(status);
    }
  }

  /* nestedvalue is not allocated here, give NULL pointer to it */
  FreeParam->nestedvalue = NULL;

  /* free the memory of model kim str */
  free(pstr);

  return KIM_STATUS_OK;
}