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; }
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; }
/******************************************************************************* * * 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; }
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; }
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; }
/****************************************************************************** * 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; }
/* 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; }
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; }
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; }
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; }
/* 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; }
/*************************************************************************** * * 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; }
/*************************************************************************** * * 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, ¤tPart, &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, ¤tPart, &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, ¤tPart, &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; }
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")
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); } } }
/* 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; }
/* 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; }
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); } }
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; }
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; }
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; }
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; }
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; }