MDStressLab++
Loading...
Searching...
No Matches
kim.cpp
Go to the documentation of this file.
1/*
2 * Kim.cpp
3 *
4 * Created on: Nov 18, 2019
5 * Author: Nikhil
6 */
7
8#include <iomanip>
9#include <iostream>
10#include "kim.h"
11#include "typedef.h"
12
13Kim::Kim(const std::string& modelname) : modelname(modelname),kim_ptr(nullptr),computeArguments(nullptr)
14{
15 std::string message= "Connecting to model: " + modelname;
16 MY_HEADING(message.c_str());
17
18 int error, requestedUnitsAccepted;
19 error = KIM::Model::Create(KIM::NUMBERING::zeroBased,
20 KIM::LENGTH_UNIT::A,
21 KIM::ENERGY_UNIT::eV,
22 KIM::CHARGE_UNIT::e,
23 KIM::TEMPERATURE_UNIT::K,
24 KIM::TIME_UNIT::ps,
26 &requestedUnitsAccepted,
27 &kim_ptr);
28 if (error) { throw(std::runtime_error("KIM::Model::Create()")); }
29
30 // Check for compatibility of units with the model's units
31 if (!requestedUnitsAccepted) { MY_ERROR("Must Adapt to model units"); }
32
33 error = kim_ptr->ComputeArgumentsCreate(&computeArguments);
34 if (error) { MY_ERROR("Unable to create a ComputeArguments object."); }
35
36 kim_ptr->GetInfluenceDistance(&influenceDistance);
37 std::cout << "Influence distance = " << influenceDistance << std::endl;
38}
39
41{
42 int error = kim_ptr->ComputeArgumentsDestroy(&computeArguments);
43 if (error) { MY_ERROR("Unable to destroy compute arguments"); }
44 /* call model destroy */
45 KIM::Model::Destroy(&kim_ptr);
46}
47
48const double* Kim::getCutoffs() const
49{
50 const double* cutoffs;
51 const int* modelWillNotRequestNeighborsOfNoncontributingParticles;
52 int numberOfNeighborLists;
53 kim_ptr->GetNeighborListPointers(&numberOfNeighborLists,
54 &cutoffs,
55 &modelWillNotRequestNeighborsOfNoncontributingParticles);
56 return cutoffs;
57}
58
60{
61 const double* cutoffs;
62 const int* modelWillNotRequestNeighborsOfNoncontributingParticles;
63 int numberOfNeighborLists;
64 kim_ptr->GetNeighborListPointers(&numberOfNeighborLists,
65 &cutoffs,
66 &modelWillNotRequestNeighborsOfNoncontributingParticles);
67 return numberOfNeighborLists;
68
69}
70
72{
73 int error;
74
75 // Check that we know about all required routines
76 int numberOfModelRoutineNames;
77 KIM::MODEL_ROUTINE_NAME::GetNumberOfModelRoutineNames(
78 &numberOfModelRoutineNames);
79 for (int i = 0; i < numberOfModelRoutineNames; ++i)
80 {
81 KIM::ModelRoutineName modelRoutineName;
82 int error
83 = KIM::MODEL_ROUTINE_NAME::GetModelRoutineName(i, &modelRoutineName);
84 if (error) { MY_ERROR("Unable to get ModelRoutineName."); }
85 int present;
86 int required;
87 error = kim_ptr->IsRoutinePresent(
88 modelRoutineName, &present, &required);
89 if (error) { MY_ERROR("Unable to get routine present/required."); }
90
91 std::cout << "Model routine name \"" << modelRoutineName.ToString()
92 << "\" has present = " << present
93 << " and required = " << required << "." << std::endl;
94
95 if ((present == true) && (required == true))
96 {
97 using namespace KIM::MODEL_ROUTINE_NAME;
98 if (!((modelRoutineName == Create)
99 || (modelRoutineName == ComputeArgumentsCreate)
100 || (modelRoutineName == Compute) || (modelRoutineName == Refresh)
101 || (modelRoutineName == ComputeArgumentsDestroy)
102 || (modelRoutineName == Destroy)))
103 {
104 MY_ERROR("Unknown Routine \"" + modelRoutineName.ToString()
105 + "\" is required by model.");
106 }
107 }
108 }
109
110 // print model units
111 KIM::LengthUnit lengthUnit;
112 KIM::EnergyUnit energyUnit;
113 KIM::ChargeUnit chargeUnit;
114 KIM::TemperatureUnit temperatureUnit;
115 KIM::TimeUnit timeUnit;
116
117 kim_ptr->GetUnits(
118 &lengthUnit, &energyUnit, &chargeUnit, &temperatureUnit, &timeUnit);
119
120 std::cout << "LengthUnit is \"" << lengthUnit.ToString() << "\"" << std::endl
121 << "EnergyUnit is \"" << energyUnit.ToString() << "\"" << std::endl
122 << "ChargeUnit is \"" << chargeUnit.ToString() << "\"" << std::endl
123 << "TemperatureUnit is \"" << temperatureUnit.ToString() << "\""
124 << std::endl
125 << "TimeUnit is \"" << timeUnit.ToString() << "\"" << std::endl;
126
127 int number_of_neighbor_lists;
128 const double* cutoff_base;
129
130 // print information about neighbor lists
131 int const * modelWillNotRequestNeighborsOfNoncontributingParticles;
132 kim_ptr->GetNeighborListPointers(&number_of_neighbor_lists,
133 &cutoff_base,
134 &modelWillNotRequestNeighborsOfNoncontributingParticles);
135 std::cout << "Model has numberOfNeighborLists : " << number_of_neighbor_lists
136 << std::endl;
137 for (int i = 0; i < number_of_neighbor_lists; ++i)
138 {
139 std::cout << "\t"
140 << "Neighbor list " << i << " has cutoff "
141 << cutoff_base[i]
142 << " with "
143 "modelWillNotRequestNeighborsOfNoncontributingParticles "
144 << modelWillNotRequestNeighborsOfNoncontributingParticles[i]
145 << std::endl;
146 }
147// ignoring hints from here on...
148// if (number_of_neighbor_lists != 1) MY_ERROR("too many neighbor lists");
149
150 // check compute arguments
151 int numberOfComputeArgumentNames;
152 KIM::COMPUTE_ARGUMENT_NAME::GetNumberOfComputeArgumentNames(
153 &numberOfComputeArgumentNames);
154 for (int i = 0; i < numberOfComputeArgumentNames; ++i)
155 {
156 KIM::ComputeArgumentName computeArgumentName;
157 KIM::SupportStatus supportStatus;
158 KIM::COMPUTE_ARGUMENT_NAME::GetComputeArgumentName(i, &computeArgumentName);
159 KIM::DataType dataType;
160 KIM::COMPUTE_ARGUMENT_NAME::GetComputeArgumentDataType(computeArgumentName,
161 &dataType);
162 error = computeArguments->GetArgumentSupportStatus(computeArgumentName,
163 &supportStatus);
164 if (error) MY_ERROR("unable to get ComputeArgument SupportStatus");
165
166 std::cout << "ComputeArgument Name \"" << computeArgumentName.ToString()
167 << "\""
168 << " is of type \"" << dataType.ToString() << "\""
169 << " and has supportStatus \"" << supportStatus.ToString() << "\""
170 << std::endl;
171
172 // can only handle energy and force as a required arg
173 if (supportStatus == KIM::SUPPORT_STATUS::required)
174 {
175 if ((computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
176 && (computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialForces))
177 { MY_ERROR("unsupported required ComputeArgument"); }
178 }
179
180 // must have energy and forces
181 if ((computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
182 || (computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialForces))
183 {
184 if (!((supportStatus == KIM::SUPPORT_STATUS::required)
185 || (supportStatus == KIM::SUPPORT_STATUS::optional)))
186 { MY_ERROR("energy or forces not available"); }
187 }
188 }
189
190 // check compute callbacks
191 int numberOfComputeCallbackNames;
192 KIM::COMPUTE_CALLBACK_NAME::GetNumberOfComputeCallbackNames(
193 &numberOfComputeCallbackNames);
194 for (int i = 0; i < numberOfComputeCallbackNames; ++i)
195 {
196 KIM::ComputeCallbackName computeCallbackName;
197 KIM::COMPUTE_CALLBACK_NAME::GetComputeCallbackName(i, &computeCallbackName);
198 KIM::SupportStatus supportStatus;
199 computeArguments->GetCallbackSupportStatus(computeCallbackName,
200 &supportStatus);
201
202 std::cout << "ComputeCallback Name \"" << computeCallbackName.ToString()
203 << "\""
204 << " has supportStatus \"" << supportStatus.ToString() << "\""
205 << std::endl;
206
207 // cannot handle any "required" callbacks
208 if (supportStatus == KIM::SUPPORT_STATUS::required)
209 { MY_ERROR("unsupported required ComputeCallback"); }
210 }
211
212 int numberOfParameters;
213 kim_ptr->GetNumberOfParameters(&numberOfParameters);
214 for (int i = 0; i < numberOfParameters; ++i)
215 {
216 KIM::DataType dataType;
217 std::string const * strName;
218 std::string const * strDesc;
219 int extent;
220 kim_ptr->GetParameterMetadata(
221 i, &dataType, &extent, &strName, &strDesc);
222 std::cout << "Parameter No. " << i << " has" << std::endl
223 << " data type : \"" << dataType.ToString() << "\"" << std::endl
224 << " extent : " << extent << std::endl
225 << " name : " << *strName << std::endl
226 << " description : " << *strDesc << std::endl;
227 }
228
229 // Check supported extensions, if any
230 int present;
231 error = kim_ptr->IsRoutinePresent(
232 KIM::MODEL_ROUTINE_NAME::Extension, &present, NULL);
233 if (error) { MY_ERROR("Unable to get Extension present/required."); }
234 if (present)
235 {
236 KIM::SupportedExtensions supportedExtensions;
237 error = kim_ptr->Extension(KIM_SUPPORTED_EXTENSIONS_ID,
238 &supportedExtensions);
239 if (error) { MY_ERROR("Error returned from KIM::Model::Extension()."); }
240 std::cout << "Model Supports "
241 << supportedExtensions.numberOfSupportedExtensions
242 << " Extensions:" << std::endl;
243 for (int i = 0; i < supportedExtensions.numberOfSupportedExtensions; ++i)
244 {
245 std::cout << " spportedExtensionID[" << std::setw(2) << i << "] = \""
246 << supportedExtensions.supportedExtensionID[i] << "\" "
247 << "which has required = "
248 << supportedExtensions.supportedExtensionRequired[i] << "."
249 << std::endl;
250 }
251 }
252}
253
255 const VectorXi& particleContributing,
256 const MatrixXd* forces_ptr,
257 NeighList* nl_ptr,
258 KIM::Function* get_neigh_ptr,
259 InteratomicForces* bonds,
260 KIM::Function* processDEDr_ptr)
261{
262 int error;
263 // check species
264 this->speciesCode.resize(config_ptr->numberOfParticles);
265 int isSpeciesSupported;
266 for (int i=0; i<config_ptr->numberOfParticles; i++)
267 {
268 KIM::SpeciesName speciesNameObject(config_ptr->species[i]);
269 error = kim_ptr->GetSpeciesSupportAndCode(speciesNameObject, &isSpeciesSupported, speciesCode.data()+i);
270 if ((error) || (!isSpeciesSupported))
271 { MY_ERROR("Species " + config_ptr->species[i] + " of particle " + std::to_string(i+1) + " not supported"); }
272 }
273
274
275 error = computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, &(config_ptr->numberOfParticles))
276 ||
277 computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::particleSpeciesCodes,this->speciesCode.data())
278 ||
279 computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::particleContributing,particleContributing.data())
280 ||
281 computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::coordinates, config_ptr->coordinates.at(Current).data())
282 ||
283 (forces_ptr == nullptr ?
284 computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::partialForces,static_cast<double*>(nullptr)) :
285 computeArguments->SetArgumentPointer(KIM::COMPUTE_ARGUMENT_NAME::partialForces, (*forces_ptr).data())
286 );
287
288 if (error) MY_ERROR("KIM_API_set_data");
289 error = computeArguments->SetCallbackPointer(KIM::COMPUTE_CALLBACK_NAME::GetNeighborList,
290 KIM::LANGUAGE_NAME::cpp, get_neigh_ptr, nl_ptr)
291 ||
292
293 (processDEDr_ptr== nullptr ?
294 computeArguments->SetCallbackPointer(KIM::COMPUTE_CALLBACK_NAME::ProcessDEDrTerm,
295 KIM::LANGUAGE_NAME::cpp, nullptr, nullptr) :
296 computeArguments->SetCallbackPointer(KIM::COMPUTE_CALLBACK_NAME::ProcessDEDrTerm,
297 KIM::LANGUAGE_NAME::cpp, processDEDr_ptr, bonds));
298 //if (error) MY_ERROR("set_call_back");
299 if (error) throw(std::runtime_error("set_call_back"));
300
301}
302
304{
305 int error= kim_ptr->Compute(computeArguments);
306 //if (error) MY_ERROR("compute");
307 if (error) throw(std::runtime_error("compute"));
308}
309
Represents atomic configuration data including coordinates, velocities, and species.
std::vector< std::string > species
Species names for each particle (size equals numberOfParticles).
int numberOfParticles
Total number of particles in the configuration.
std::map< ConfigType, MatrixXd > coordinates
Map from configuration type (Reference or Current) to coordinate matrices.
const double * getCutoffs() const
Definition kim.cpp:48
std::vector< int > speciesCode
Definition kim.h:23
virtual ~Kim()
Definition kim.cpp:40
double influenceDistance
Definition kim.h:25
KIM::ComputeArguments * computeArguments
Definition kim.h:27
void queryModel()
Definition kim.cpp:71
Kim()
Definition kim.h:34
void compute()
Definition kim.cpp:303
void broadcastToModel(const Configuration *config_ptr, const VectorXi &particleContributing, const MatrixXd *forces_ptr, NeighList *nl_ptr, KIM::Function *get_neigh_ptr, InteratomicForces *bonds, KIM::Function *processDEDr_ptr)
Definition kim.cpp:254
std::string modelname
Definition kim.h:24
int getNumberOfNeighborLists() const
Definition kim.cpp:59
KIM::Model * kim_ptr
Definition kim.h:26
#define MY_ERROR(message)
Definition typedef.h:17
Eigen::Matrix< int, 1, Eigen::Dynamic, Eigen::RowMajor > VectorXi
Definition typedef.h:58
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MatrixXd
Definition typedef.h:54
@ Current
Definition typedef.h:70
#define MY_HEADING(heading)
Definition typedef.h:36