kim-api-v2  2.0.0+912e79a.GNU
An Application Programming Interface (API) for the Knowledgebase of Interatomic Models (KIM).
ex_test_Ar_fcc_cluster_cpp.cpp
Go to the documentation of this file.
1 //
2 //
3 // CDDL HEADER START
4 //
5 // The contents of this file are subject to the terms of the Common Development
6 // and Distribution License Version 1.0 (the "License").
7 //
8 // You can obtain a copy of the license at
9 // http://www.opensource.org/licenses/CDDL-1.0. See the License for the
10 // specific language governing permissions and limitations under the License.
11 //
12 // When distributing Covered Code, include this CDDL HEADER in each file and
13 // include the License file in a prominent location with the name LICENSE.CDDL.
14 // If applicable, add the following below this CDDL HEADER, with the fields
15 // enclosed by brackets "[]" replaced with your own identifying information:
16 //
17 // Portions Copyright (c) [yyyy] [name of copyright owner]. All rights reserved.
18 //
19 // CDDL HEADER END
20 //
21 //
22 //
23 // Copyright (c) 2013--2019, Regents of the University of Minnesota.
24 // All rights reserved.
25 //
26 // Contributors:
27 // Ryan S. Elliott
28 // Stephen M. Whalen
29 //
30 //
31 
32 
33 #include "KIM_SimulatorHeaders.hpp"
35 #include <cmath>
36 #include <iomanip>
37 #include <iostream>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string>
41 
42 #define NAMESTRLEN 128
43 
44 #define FCCSPACING 5.260
45 #define DIM 3
46 #define NCELLSPERSIDE 2
47 #define NCLUSTERPARTS \
48  (4 * (NCELLSPERSIDE * NCELLSPERSIDE * NCELLSPERSIDE) \
49  + 6 * (NCELLSPERSIDE * NCELLSPERSIDE) + 3 * (NCELLSPERSIDE) + 1)
50 
51 #define MY_ERROR(message) \
52  { \
53  std::cout << "* Error : \"" << message << "\" : " << __LINE__ << ":" \
54  << __FILE__ << std::endl; \
55  exit(1); \
56  }
57 
58 #define MY_WARNING(message) \
59  { \
60  std::cout << "* Warning : \"" << message << "\" : " << __LINE__ << ":" \
61  << __FILE__ << std::endl; \
62  }
63 
64 
65 /* Define neighborlist structure */
66 typedef struct
67 {
68  double cutoff;
70  int * NNeighbors;
71  int * neighborList;
72 } NeighList;
73 
74 /* Define prototypes */
75 void fcc_cluster_neighborlist(int half,
77  double * coords,
78  double cutoff,
79  NeighList * nl);
80 
81 int get_cluster_neigh(void * const dataObject,
82  int const numberOfNeighborLists,
83  double const * const cutoffs,
84  int const neighborListIndex,
85  int const particleNumber,
86  int * const numberOfNeighbors,
87  int const ** const neighborsOfParticle);
88 
89 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords);
90 
91 void compute_loop(double const MinSpacing,
92  double const MaxSpacing,
93  double const SpacingIncr,
94  int const numberOfParticles_cluster,
95  double * const coords_cluster,
96  double const cutoff,
97  NeighList * nl,
98  KIM::Model const * const kim_cluster_model,
99  KIM::ComputeArguments const * const computeArguments,
100  double * const forces_cluster,
101  double * const energy_cluster_model);
102 
103 
104 /* Main program */
105 int main()
106 {
107  /* Local variable declarations */
108  double const MinSpacing = 0.8 * FCCSPACING;
109  double const MaxSpacing = 1.2 * FCCSPACING;
110  double const SpacingIncr = 0.025 * FCCSPACING;
111  int i;
112  int error;
113 
114 
115  /* model inputs */
116  int numberOfParticles_cluster = NCLUSTERPARTS;
117  int particleSpecies_cluster_model[NCLUSTERPARTS];
118  int particleContributing_cluster_model[NCLUSTERPARTS];
119  double coords_cluster[NCLUSTERPARTS][DIM];
120  NeighList nl_cluster_model;
121  /* model outputs */
122  double influence_distance_cluster_model;
123  int number_of_neighbor_lists;
124  double const * cutoff_cluster_model;
125  double energy_cluster_model;
126  double forces_cluster[NCLUSTERPARTS * DIM];
127 
128  std::string modelname;
129 
130  /* Get KIM Model names */
131  printf("Please enter valid KIM Model name: \n");
132  std::cin >> modelname;
133 
134 
135  /* initialize the model */
136  KIM::Model * kim_cluster_model;
137  int requestedUnitsAccepted;
144  modelname,
145  &requestedUnitsAccepted,
146  &kim_cluster_model);
147  if (error) { MY_ERROR("KIM::Model::Create()"); }
148 
149  // Check for compatibility with the model
150  if (!requestedUnitsAccepted) { MY_ERROR("Must Adapt to model units"); }
151 
152  // Check that we know about all required routines
153  int numberOfModelRoutineNames;
155  &numberOfModelRoutineNames);
156  for (int i = 0; i < numberOfModelRoutineNames; ++i)
157  {
158  KIM::ModelRoutineName modelRoutineName;
159  int error
160  = KIM::MODEL_ROUTINE_NAME::GetModelRoutineName(i, &modelRoutineName);
161  if (error) { MY_ERROR("Unable to get ModelRoutineName."); }
162  int present;
163  int required;
164  error = kim_cluster_model->IsRoutinePresent(
165  modelRoutineName, &present, &required);
166  if (error) { MY_ERROR("Unable to get routine present/required."); }
167 
168  std::cout << "Model routine name \"" << modelRoutineName.ToString()
169  << "\" has present = " << present
170  << " and required = " << required << "." << std::endl;
171 
172  if ((present == true) && (required == true))
173  {
174  using namespace KIM::MODEL_ROUTINE_NAME;
175  if (!((modelRoutineName == Create)
176  || (modelRoutineName == ComputeArgumentsCreate)
177  || (modelRoutineName == Compute) || (modelRoutineName == Refresh)
178  || (modelRoutineName == ComputeArgumentsDestroy)
179  || (modelRoutineName == Destroy)))
180  {
181  MY_ERROR("Unknown Routine \"" + modelRoutineName.ToString()
182  + "\" is required by model.");
183  }
184  }
185  }
186 
187  // print model units
188  KIM::LengthUnit lengthUnit;
189  KIM::EnergyUnit energyUnit;
190  KIM::ChargeUnit chargeUnit;
191  KIM::TemperatureUnit temperatureUnit;
192  KIM::TimeUnit timeUnit;
193 
194  kim_cluster_model->GetUnits(
195  &lengthUnit, &energyUnit, &chargeUnit, &temperatureUnit, &timeUnit);
196 
197  std::cout << "LengthUnit is \"" << lengthUnit.ToString() << "\"" << std::endl
198  << "EnergyUnit is \"" << energyUnit.ToString() << "\"" << std::endl
199  << "ChargeUnit is \"" << chargeUnit.ToString() << "\"" << std::endl
200  << "TemperatureUnit is \"" << temperatureUnit.ToString() << "\""
201  << std::endl
202  << "TimeUnit is \"" << timeUnit.ToString() << "\"" << std::endl;
203 
204  // check species
205  int speciesIsSupported;
206  int modelArCode;
207  error = kim_cluster_model->GetSpeciesSupportAndCode(
208  KIM::SPECIES_NAME::Ar, &speciesIsSupported, &modelArCode);
209  if ((error) || (!speciesIsSupported))
210  { MY_ERROR("Species Ar not supported"); }
211 
212  KIM::ComputeArguments * computeArguments;
213  error = kim_cluster_model->ComputeArgumentsCreate(&computeArguments);
214  if (error) { MY_ERROR("Unable to create a ComputeArguments object."); }
215 
216  // check compute arguments
217  int numberOfComputeArgumentNames;
219  &numberOfComputeArgumentNames);
220  for (int i = 0; i < numberOfComputeArgumentNames; ++i)
221  {
222  KIM::ComputeArgumentName computeArgumentName;
223  KIM::SupportStatus supportStatus;
225  KIM::DataType dataType;
227  &dataType);
228  error = computeArguments->GetArgumentSupportStatus(computeArgumentName,
229  &supportStatus);
230  if (error) MY_ERROR("unable to get ComputeArgument SupportStatus");
231 
232  std::cout << "ComputeArgument Name \"" << computeArgumentName.ToString()
233  << "\""
234  << " is of type \"" << dataType.ToString() << "\""
235  << " and has supportStatus \"" << supportStatus.ToString() << "\""
236  << std::endl;
237 
238  // can only handle energy and force as a required arg
239  if (supportStatus == KIM::SUPPORT_STATUS::required)
240  {
241  if ((computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
242  && (computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialForces))
243  { MY_ERROR("unsupported required ComputeArgument"); }
244  }
245 
246  // must have energy and forces
247  if ((computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
248  || (computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialForces))
249  {
250  if (!((supportStatus == KIM::SUPPORT_STATUS::required)
251  || (supportStatus == KIM::SUPPORT_STATUS::optional)))
252  { MY_ERROR("energy or forces not available"); }
253  }
254  }
255 
256  // check compute callbacks
257  int numberOfComputeCallbackNames;
259  &numberOfComputeCallbackNames);
260  for (int i = 0; i < numberOfComputeCallbackNames; ++i)
261  {
262  KIM::ComputeCallbackName computeCallbackName;
264  KIM::SupportStatus supportStatus;
265  computeArguments->GetCallbackSupportStatus(computeCallbackName,
266  &supportStatus);
267 
268  std::cout << "ComputeCallback Name \"" << computeCallbackName.ToString()
269  << "\""
270  << " has supportStatus \"" << supportStatus.ToString() << "\""
271  << std::endl;
272 
273  // cannot handle any "required" callbacks
274  if (supportStatus == KIM::SUPPORT_STATUS::required)
275  { MY_ERROR("unsupported required ComputeCallback"); }
276  }
277 
278  int numberOfParameters;
279  kim_cluster_model->GetNumberOfParameters(&numberOfParameters);
280  for (int i = 0; i < numberOfParameters; ++i)
281  {
282  KIM::DataType dataType;
283  std::string const * strName;
284  std::string const * strDesc;
285  int extent;
286  kim_cluster_model->GetParameterMetadata(
287  i, &dataType, &extent, &strName, &strDesc);
288  std::cout << "Parameter No. " << i << " has" << std::endl
289  << " data type : \"" << dataType.ToString() << "\"" << std::endl
290  << " extent : " << extent << std::endl
291  << " name : " << *strName << std::endl
292  << " description : " << *strDesc << std::endl;
293  }
294 
295  // Check supported extensions, if any
296  int present;
297  error = kim_cluster_model->IsRoutinePresent(
298  KIM::MODEL_ROUTINE_NAME::Extension, &present, NULL);
299  if (error) { MY_ERROR("Unable to get Extension present/required."); }
300  if (present)
301  {
302  KIM::SupportedExtensions supportedExtensions;
303  error = kim_cluster_model->Extension(KIM_SUPPORTED_EXTENSIONS_ID,
304  &supportedExtensions);
305  if (error) { MY_ERROR("Error returned from KIM::Model::Extension()."); }
306  std::cout << "Model Supports "
307  << supportedExtensions.numberOfSupportedExtensions
308  << " Extensions:" << std::endl;
309  for (int i = 0; i < supportedExtensions.numberOfSupportedExtensions; ++i)
310  {
311  std::cout << " spportedExtensionID[" << std::setw(2) << i << "] = \""
312  << supportedExtensions.supportedExtensionID[i] << "\" "
313  << "which has required = "
314  << supportedExtensions.supportedExtensionRequired[i] << "."
315  << std::endl;
316  }
317  }
318 
319  // We're compatible with the model. Let's do it.
320 
321  error
322  = computeArguments->SetArgumentPointer(
324  (int *) &numberOfParticles_cluster)
325  || computeArguments->SetArgumentPointer(
327  particleSpecies_cluster_model)
328  || computeArguments->SetArgumentPointer(
330  particleContributing_cluster_model)
331  || computeArguments->SetArgumentPointer(
332  KIM::COMPUTE_ARGUMENT_NAME::coordinates, (double *) coords_cluster)
333  || computeArguments->SetArgumentPointer(
334  KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, &energy_cluster_model)
335  || computeArguments->SetArgumentPointer(
337  (double *) forces_cluster);
338  if (error) MY_ERROR("KIM_API_set_data");
339  error = computeArguments->SetCallbackPointer(
343  &nl_cluster_model);
344  if (error) MY_ERROR("set_call_back");
345 
346  kim_cluster_model->GetInfluenceDistance(&influence_distance_cluster_model);
347  int const * modelWillNotRequestNeighborsOfNoncontributingParticles;
348  kim_cluster_model->GetNeighborListPointers(
349  &number_of_neighbor_lists,
350  &cutoff_cluster_model,
351  &modelWillNotRequestNeighborsOfNoncontributingParticles);
352  std::cout << "Model has influence distance of : "
353  << influence_distance_cluster_model << std::endl;
354  std::cout << "Model has numberOfNeighborLists : " << number_of_neighbor_lists
355  << std::endl;
356  for (int i = 0; i < number_of_neighbor_lists; ++i)
357  {
358  std::cout << "\t"
359  << "Neighbor list " << i << " has cutoff "
360  << cutoff_cluster_model[i]
361  << " with "
362  "modelWillNotRequestNeighborsOfNoncontributingParticles "
363  << modelWillNotRequestNeighborsOfNoncontributingParticles[i]
364  << std::endl;
365  }
366  // ignoring hints from here on...
367  if (number_of_neighbor_lists != 1) MY_ERROR("too many neighbor lists");
368 
369  /* setup particleSpecies */
370  int isSpeciesSupported;
371  error = kim_cluster_model->GetSpeciesSupportAndCode(
373  &isSpeciesSupported,
374  &(particleSpecies_cluster_model[0]));
375  if (error) MY_ERROR("get_species_code");
376  for (i = 1; i < NCLUSTERPARTS; ++i)
377  particleSpecies_cluster_model[i] = particleSpecies_cluster_model[0];
378  /* setup particleContributing */
379  for (i = 0; i < NCLUSTERPARTS; ++i)
380  particleContributing_cluster_model[i] = 1; /* every particle contributes */
381 
382  /* setup neighbor lists */
383  /* allocate memory for list */
384  nl_cluster_model.numberOfParticles = NCLUSTERPARTS;
385  nl_cluster_model.NNeighbors = new int[NCLUSTERPARTS];
386  if (NULL == nl_cluster_model.NNeighbors) MY_ERROR("new unsuccessful");
387 
388  nl_cluster_model.neighborList = new int[NCLUSTERPARTS * NCLUSTERPARTS];
389  if (NULL == nl_cluster_model.neighborList) MY_ERROR("new unsuccessful");
390 
391  /* ready to compute */
392  std::cout << std::setiosflags(std::ios::scientific) << std::setprecision(10);
393  std::cout << "This is Test : ex_test_Ar_fcc_cluster_cpp\n";
394  std::cout << "---------------------------------------------------------------"
395  "-----------------\n";
396  std::cout << "Results for KIM Model : " << modelname << std::endl;
397 
398  compute_loop(MinSpacing,
399  MaxSpacing,
400  SpacingIncr,
401  numberOfParticles_cluster,
402  &(coords_cluster[0][0]),
403  *cutoff_cluster_model,
404  &nl_cluster_model,
405  kim_cluster_model,
406  computeArguments,
407  forces_cluster,
408  &energy_cluster_model);
409 
410  if (numberOfParameters > 0)
411  {
412  int index = numberOfParameters / 2;
413  KIM::DataType dataType;
414  std::string const * name;
415  double value;
416  error = kim_cluster_model->GetParameterMetadata(
417  index, &dataType, NULL, &name, NULL);
418  if (error) { MY_ERROR("Cannot get parameter metadata."); }
419  if (dataType != KIM::DATA_TYPE::Double)
420  { MY_WARNING("Can't change an integer."); }
421  else
422  {
423  error = kim_cluster_model->GetParameter(index, 0, &value);
424  if (error) { MY_ERROR("Cannot get parameter value."); }
425  value *= 1.5;
426  error = kim_cluster_model->SetParameter(index, 0, value);
427  if (error) { MY_ERROR("Cannot set parameter value."); }
428  error = kim_cluster_model->ClearThenRefresh();
429  if (error) { MY_ERROR("Model ClearThenRefresh returned error."); }
430 
431  std::cout << std::endl
432  << "Updated parameter \"" << *name << "\" to value " << value
433  << "." << std::endl;
434 
435  kim_cluster_model->GetInfluenceDistance(
436  &influence_distance_cluster_model);
437  kim_cluster_model->GetNeighborListPointers(
438  &number_of_neighbor_lists,
439  &cutoff_cluster_model,
440  &modelWillNotRequestNeighborsOfNoncontributingParticles);
441 
442  compute_loop(MinSpacing,
443  MaxSpacing,
444  SpacingIncr,
445  numberOfParticles_cluster,
446  &(coords_cluster[0][0]),
447  *cutoff_cluster_model,
448  &nl_cluster_model,
449  kim_cluster_model,
450  computeArguments,
451  forces_cluster,
452  &energy_cluster_model);
453  }
454 
455  int present;
456  kim_cluster_model->IsRoutinePresent(
458  if (present == true)
459  {
460  error = kim_cluster_model->WriteParameterizedModel(
461  ".", "This_IsTheNewModelName");
462  if (error) { MY_ERROR("WriteParameterizedModel returned an error."); }
463  }
464  }
465 
466  /* call compute arguments destroy */
467  error = kim_cluster_model->ComputeArgumentsDestroy(&computeArguments);
468  if (error) { MY_ERROR("Unable to destroy compute arguments"); }
469 
470  /* call model destroy */
471  KIM::Model::Destroy(&kim_cluster_model);
472 
473  /* free memory of neighbor lists */
474  delete[] nl_cluster_model.NNeighbors;
475  delete[] nl_cluster_model.neighborList;
476 
477  /* everything is great */
478  return 0;
479 }
480 
481 void compute_loop(double const MinSpacing,
482  double const MaxSpacing,
483  double const SpacingIncr,
484  int const numberOfParticles_cluster,
485  double * const coords_cluster,
486  double const cutoff,
487  NeighList * nl,
488  KIM::Model const * const kim_cluster_model,
489  KIM::ComputeArguments const * const computeArguments,
490  double * const forces_cluster,
491  double * const energy_cluster_model)
492 {
493  double const cutpad = 0.75; /* Angstroms */
494 
495  std::cout << std::setw(20) << "Energy" << std::setw(20) << "Force Norm"
496  << std::setw(20) << "Lattice Spacing" << std::endl;
497  for (double CurrentSpacing = MinSpacing; CurrentSpacing < MaxSpacing;
498  CurrentSpacing += SpacingIncr)
499  {
500  /* update coordinates for cluster */
501  create_FCC_cluster(CurrentSpacing, NCELLSPERSIDE, coords_cluster);
502  /* compute neighbor lists */
504  0, NCLUSTERPARTS, coords_cluster, (cutoff + cutpad), nl);
505 
506  /* call compute functions */
507  int error = kim_cluster_model->Compute(computeArguments);
508  if (error) MY_ERROR("compute");
509 
510  /* compute force norm */
511  double force_norm = 0.0;
512  for (int i = 0; i < DIM * numberOfParticles_cluster; ++i)
513  { force_norm += forces_cluster[i] * forces_cluster[i]; }
514  force_norm = sqrt(force_norm);
515 
516  /* print the results */
517  std::cout << std::setw(20) << *energy_cluster_model << std::setw(20)
518  << force_norm << std::setw(20) << CurrentSpacing << std::endl;
519  }
520 }
521 
522 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords)
523 {
524  /* local variables */
525  double FCCshifts[4][DIM];
526  double latVec[DIM];
527  int a;
528  int i;
529  int j;
530  int k;
531  int m;
532  int n;
533 
534  /* create a cubic FCC cluster of parts */
535  FCCshifts[0][0] = 0.0;
536  FCCshifts[0][1] = 0.0;
537  FCCshifts[0][2] = 0.0;
538  FCCshifts[1][0] = 0.5 * FCCspacing;
539  FCCshifts[1][1] = 0.5 * FCCspacing;
540  FCCshifts[1][2] = 0.0;
541  FCCshifts[2][0] = 0.5 * FCCspacing;
542  FCCshifts[2][1] = 0.0;
543  FCCshifts[2][2] = 0.5 * FCCspacing;
544  FCCshifts[3][0] = 0.0;
545  FCCshifts[3][1] = 0.5 * FCCspacing;
546  FCCshifts[3][2] = 0.5 * FCCspacing;
547 
548  a = 0;
549  for (i = 0; i < nCellsPerSide; ++i)
550  {
551  latVec[0] = ((double) i) * FCCspacing;
552  for (j = 0; j < nCellsPerSide; ++j)
553  {
554  latVec[1] = ((double) j) * FCCspacing;
555  for (k = 0; k < nCellsPerSide; ++k)
556  {
557  latVec[2] = ((double) k) * FCCspacing;
558  for (m = 0; m < 4; ++m)
559  {
560  for (n = 0; n < DIM; ++n)
561  { coords[a * DIM + n] = latVec[n] + FCCshifts[m][n]; }
562  a++;
563  }
564  }
565  /* add in the remaining three faces */
566  /* pos-x face */
567  latVec[0] = NCELLSPERSIDE * FCCspacing;
568  latVec[1] = ((double) i) * FCCspacing;
569  latVec[2] = ((double) j) * FCCspacing;
570  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
571  a++;
572  for (n = 0; n < DIM; ++n)
573  { coords[a * DIM + n] = latVec[n] + FCCshifts[3][n]; }
574  a++;
575  /* pos-y face */
576  latVec[0] = ((double) i) * FCCspacing;
577  latVec[1] = NCELLSPERSIDE * FCCspacing;
578  latVec[2] = ((double) j) * FCCspacing;
579  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
580  a++;
581  for (n = 0; n < DIM; ++n)
582  { coords[a * DIM + n] = latVec[n] + FCCshifts[2][n]; }
583  a++;
584  /* pos-z face */
585  latVec[0] = ((double) i) * FCCspacing;
586  latVec[1] = ((double) j) * FCCspacing;
587  latVec[2] = NCELLSPERSIDE * FCCspacing;
588  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
589  a++;
590  for (n = 0; n < DIM; ++n)
591  { coords[a * DIM + n] = latVec[n] + FCCshifts[1][n]; }
592  a++;
593  }
594  /* add in the remaining three edges */
595  latVec[0] = ((double) i) * FCCspacing;
596  latVec[1] = NCELLSPERSIDE * FCCspacing;
597  latVec[2] = NCELLSPERSIDE * FCCspacing;
598  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
599  a++;
600  latVec[0] = NCELLSPERSIDE * FCCspacing;
601  latVec[1] = ((double) i) * FCCspacing;
602  latVec[2] = NCELLSPERSIDE * FCCspacing;
603  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
604  a++;
605  latVec[0] = NCELLSPERSIDE * FCCspacing;
606  latVec[1] = NCELLSPERSIDE * FCCspacing;
607  latVec[2] = ((double) i) * FCCspacing;
608  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
609  a++;
610  }
611  /* add in the remaining corner */
612  for (n = 0; n < DIM; ++n)
613  { coords[a * DIM + n] = NCELLSPERSIDE * FCCspacing; }
614  a++;
615 
616  return;
617 }
618 
619 
621  int numberOfParticles,
622  double * coords,
623  double cutoff,
624  NeighList * nl)
625 {
626  /* local variables */
627  int i;
628  int j;
629  int k;
630  int a;
631 
632  double dx[DIM];
633  double r2;
634  double cutoff2;
635 
636  nl->cutoff = cutoff;
637 
638  cutoff2 = cutoff * cutoff;
639 
640  for (i = 0; i < numberOfParticles; ++i)
641  {
642  a = 0;
643  for (j = 0; j < numberOfParticles; ++j)
644  {
645  r2 = 0.0;
646  for (k = 0; k < DIM; ++k)
647  {
648  dx[k] = coords[j * DIM + k] - coords[i * DIM + k];
649  r2 += dx[k] * dx[k];
650  }
651 
652  if (r2 < cutoff2)
653  {
654  if ((half && i < j) || (!half && i != j))
655  {
656  /* part j is a neighbor of part i */
657  (*nl).neighborList[i * NCLUSTERPARTS + a] = j;
658  a++;
659  }
660  }
661  }
662  /* part i has `a' neighbors */
663  (*nl).NNeighbors[i] = a;
664  }
665 
666  return;
667 }
668 
669 int get_cluster_neigh(void * const dataObject,
670  int const numberOfNeighborLists,
671  double const * const cutoffs,
672  int const neighborListIndex,
673  int const particleNumber,
674  int * const numberOfNeighbors,
675  int const ** const neighborsOfParticle)
676 {
677  /* local variables */
678  int error = true;
679  NeighList * nl = (NeighList *) dataObject;
681 
682  if ((numberOfNeighborLists != 1) || (cutoffs[0] > nl->cutoff)) return error;
683 
684  if (neighborListIndex != 0) return error;
685 
686  /* initialize numNeigh */
687  *numberOfNeighbors = 0;
688 
689  if ((particleNumber >= numberOfParticles)
690  || (particleNumber < 0)) /* invalid id */
691  {
692  MY_WARNING("Invalid part ID in get_cluster_neigh");
693  return true;
694  }
695 
696  /* set the returned number of neighbors for the returned part */
697  *numberOfNeighbors = (*nl).NNeighbors[particleNumber];
698 
699  /* set the location for the returned neighbor list */
700  *neighborsOfParticle
701  = &((*nl).neighborList[(particleNumber) *numberOfParticles]);
702 
703  return false;
704 }
void GetNumberOfComputeCallbackNames(int *const numberOfComputeCallbackNames)
Get the number of standard ComputeCallbackName&#39;s defined by the KIM API.
Numbering const zeroBased
The standard zeroBased numbering.
Provides the primary interface to a KIM API ComputeArguments object and is meant to be used by simula...
Contains the enumeration constants and the discovery routines for the ModelRoutineName Extensible Enu...
std::string const & ToString() const
Converts the object to a string.
void() Function(void)
Generic function type.
TimeUnit const ps
The standard picosecond unit of time.
int numberOfSupportedExtensions
The number of extensions supported by the Model.
EnergyUnit const eV
The standard electronvolt unit of energy.
ComputeCallbackName const GetNeighborList
The standard GetNeighborList callback.
int ClearThenRefresh()
Clear influence distance and neighbor list pointers and refresh Model object after parameter changes...
static int Create(Numbering const numbering, LengthUnit const requestedLengthUnit, EnergyUnit const requestedEnergyUnit, ChargeUnit const requestedChargeUnit, TemperatureUnit const requestedTemperatureUnit, TimeUnit const requestedTimeUnit, std::string const &modelName, int *const requestedUnitsAccepted, Model **const model)
Create a new KIM API Model object.
void GetUnits(LengthUnit *const lengthUnit, EnergyUnit *const energyUnit, ChargeUnit *const chargeUnit, TemperatureUnit *const temperatureUnit, TimeUnit *const timeUnit) const
Get the Model&#39;s base unit values.
An Extensible Enumeration for the ComputeArgumentName&#39;s supported by the KIM API. ...
void GetInfluenceDistance(double *const influenceDistance) const
Get the Model&#39;s influence distance.
std::string const & ToString() const
Converts the object to a string.
int ComputeArgumentsCreate(ComputeArguments **const computeArguments) const
Create a new ComputeArguments object for the Model object.
void GetNeighborListPointers(int *const numberOfNeighborLists, double const **const cutoffs, int const **const modelWillNotRequestNeighborsOfNoncontributingParticles) const
Get the Model&#39;s neighbor list information.
An Extensible Enumeration for the ChargeUnit&#39;s supported by the KIM API.
An Extensible Enumeration for the LengthUnit&#39;s supported by the KIM API.
SupportStatus const optional
The standard optional status.
void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double *coords)
TemperatureUnit const K
The standard Kelvin unit of temperature.
std::string const & ToString() const
Converts the object to a string.
int GetCallbackSupportStatus(ComputeCallbackName const computeCallbackName, SupportStatus *const supportStatus) const
Get the SupportStatus of a ComputeCallbackName.
The only standard extension defined by the KIM API.
int get_cluster_neigh(void *const dataObject, int const numberOfNeighborLists, double const *const cutoffs, int const neighborListIndex, int const particleNumber, int *const numberOfNeighbors, int const **const neighborsOfParticle)
An Extensible Enumeration for the EnergyUnit&#39;s supported by the KIM API.
#define MY_WARNING(message)
An Extensible Enumeration for the SupportStatus&#39;s supported by the KIM API.
int GetArgumentSupportStatus(ComputeArgumentName const computeArgumentName, SupportStatus *const supportStatus) const
Get the SupportStatus of a ComputeArgumentName.
int WriteParameterizedModel(std::string const &path, std::string const &modelName) const
Call the Model&#39;s MODEL_ROUTINE_NAME::WriteParameterizedModel routine.
int SetArgumentPointer(ComputeArgumentName const computeArgumentName, int const *const ptr)
Set the data pointer for a ComputeArgumentName.
SpeciesName const Ar
The standard Argon species.
int GetParameter(int const parameterIndex, int const arrayIndex, int *const parameterValue) const
Get a parameter value from the Model.
ModelRoutineName const Destroy
The standard Destroy routine.
#define NCLUSTERPARTS
void GetNumberOfModelRoutineNames(int *const numberOfModelRoutineNames)
Get the number of standard ModelRoutineName&#39;s defined by the KIM API.
std::string const & ToString() const
Converts the object to a string.
ModelRoutineName const Create
The standard Create routine.
LengthUnit const m
The standard meter unit of length.
void compute_loop(double const MinSpacing, double const MaxSpacing, double const SpacingIncr, int const numberOfParticles_cluster, double *const coords_cluster, double const cutoff, NeighList *nl, KIM::Model const *const kim_cluster_model, KIM::ComputeArguments const *const computeArguments, double *const forces_cluster, double *const energy_cluster_model)
ModelRoutineName const Extension
The standard Extension routine.
An Extensible Enumeration for the ComputeCallbackName&#39;s supported by the KIM API. ...
std::string const & ToString() const
Converts the object to a string.
#define NCELLSPERSIDE
An Extensible Enumeration for the ModelRoutineName&#39;s supported by the KIM API.
int ComputeArgumentsDestroy(ComputeArguments **const computeArguments) const
Destroy a previously Model::ComputeArgumentsCreate&#39;d object.
static void Destroy(Model **const model)
Destroy a previously Model::Create&#39;d object.
int GetModelRoutineName(int const index, ModelRoutineName *const modelRoutineName)
Get the identity of each defined standard ModelRoutineName.
An Extensible Enumeration for the TimeUnit&#39;s supported by the KIM API.
ModelRoutineName const Refresh
The standard Refresh routine.
DataType const Double
The standard Double data type.
ModelRoutineName const ComputeArgumentsDestroy
The standard ComputeArgumentsDestroy routine.
ModelRoutineName const ComputeArgumentsCreate
The standard ComputeArgumentsCreate routine.
void GetNumberOfComputeArgumentNames(int *const numberOfComputeArgumentNames)
Get the number of standard ComputeArgumentName&#39;s defined by the KIM API.
ComputeArgumentName const coordinates
The standard coordinates argument.
int GetComputeArgumentName(int const index, ComputeArgumentName *const computeArgumentName)
Get the identity of each defined standard ComputeArgumentName.
LengthUnit const A
The standard angstrom unit of length.
ComputeArgumentName const partialEnergy
The standard partialEnergy argument.
char supportedExtensionID[KIM_MAX_NUMBER_OF_EXTENSIONS][KIM_MAX_EXTENSION_ID_LENGTH]
The unique extension ID&#39;s of each supported extension.
ModelRoutineName const Compute
The standard Compute routine.
int SetParameter(int const parameterIndex, int const arrayIndex, int const parameterValue)
Set a parameter value for the Model.
ComputeArgumentName const particleSpeciesCodes
The standard particleSpeciesCodes argument.
ComputeArgumentName const numberOfParticles
The standard numberOfParticles argument.
#define FCCSPACING
#define KIM_SUPPORTED_EXTENSIONS_ID
void fcc_cluster_neighborlist(int half, int numberOfParticles, double *coords, double cutoff, NeighList *nl)
void GetNumberOfParameters(int *const numberOfParameters) const
Get the number of parameter arrays provided by the Model.
ModelRoutineName const WriteParameterizedModel
The standard WriteParameterizedModel routine.
Provides the primary interface to a KIM API Model object and is meant to be used by simulators...
Definition: KIM_Model.hpp:61
LanguageName const cpp
The standard cpp language.
std::string const & ToString() const
Converts the object to a string.
SupportStatus const required
The standard required status.
std::string const & ToString() const
Converts the object to a string.
int supportedExtensionRequired[KIM_MAX_NUMBER_OF_EXTENSIONS]
An Extensible Enumeration for the TemperatureUnit&#39;s supported by the KIM API.
LogVerbosity const error
The standard error verbosity.
int GetComputeArgumentDataType(ComputeArgumentName const computeArgumentName, DataType *const dataType)
Get the DataType of each defined standard ComputeArgumentName.
std::string const & ToString() const
Converts the object to a string.
std::string const & ToString() const
Converts the object to a string.
ChargeUnit const e
The standard electron unit of charge.
int GetComputeCallbackName(int const index, ComputeCallbackName *const computeCallbackName)
Get the identity of each defined standard ComputeCallbackName.
An Extensible Enumeration for the DataType&#39;s supported by the KIM API.
int GetParameterMetadata(int const parameterIndex, DataType *const dataType, int *const extent, std::string const **const name, std::string const **const description) const
Get the metadata associated with one of the Model&#39;s parameter arrays.
int IsRoutinePresent(ModelRoutineName const modelRoutineName, int *const present, int *const required) const
Determine presence and required status of the given ModelRoutineName.
int GetSpeciesSupportAndCode(SpeciesName const speciesName, int *const speciesIsSupported, int *const code) const
Get the Model&#39;s support and code for the requested SpeciesName.
ComputeArgumentName const particleContributing
The standard particleContributing argument.
int Extension(std::string const &extensionID, void *const extensionStructure)
Call the Model&#39;s MODEL_ROUTINE_NAME::Extension routine.
ComputeArgumentName const partialForces
The standard partialForces argument.
#define MY_ERROR(message)
int SetCallbackPointer(ComputeCallbackName const computeCallbackName, LanguageName const languageName, Function *const fptr, void *const dataObject)
Set the function pointer for a ComputeCallbackName.
int Compute(ComputeArguments const *const computeArguments) const
Call the Model&#39;s MODEL_ROUTINE_NAME::Compute routine.