kim-api  2.1.2+v2.1.2.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::ios oldState(NULL);
393  oldState.copyfmt(std::cout);
394  std::cout << std::setiosflags(std::ios::scientific) << std::setprecision(10);
395  std::cout << "This is Test : ex_test_Ar_fcc_cluster_cpp\n";
396  std::cout << "---------------------------------------------------------------"
397  "-----------------\n";
398  std::cout << "Results for KIM Model : " << modelname << std::endl;
399 
400  compute_loop(MinSpacing,
401  MaxSpacing,
402  SpacingIncr,
403  numberOfParticles_cluster,
404  &(coords_cluster[0][0]),
405  *cutoff_cluster_model,
406  &nl_cluster_model,
407  kim_cluster_model,
408  computeArguments,
409  forces_cluster,
410  &energy_cluster_model);
411 
412  if (numberOfParameters > 0)
413  {
414  int index = numberOfParameters / 2;
415  KIM::DataType dataType;
416  std::string const * name;
417  double value;
418  error = kim_cluster_model->GetParameterMetadata(
419  index, &dataType, NULL, &name, NULL);
420  if (error) { MY_ERROR("Cannot get parameter metadata."); }
421  if (dataType != KIM::DATA_TYPE::Double)
422  { MY_WARNING("Can't change an integer."); }
423  else
424  {
425  error = kim_cluster_model->GetParameter(index, 0, &value);
426  if (error) { MY_ERROR("Cannot get parameter value."); }
427  value *= 1.5;
428  error = kim_cluster_model->SetParameter(index, 0, value);
429  if (error) { MY_ERROR("Cannot set parameter value."); }
430  error = kim_cluster_model->ClearThenRefresh();
431  if (error) { MY_ERROR("Model ClearThenRefresh returned error."); }
432 
433  std::cout << std::endl
434  << "Updated parameter \"" << *name << "\" to value " << value
435  << "." << std::endl;
436 
437  kim_cluster_model->GetInfluenceDistance(
438  &influence_distance_cluster_model);
439  kim_cluster_model->GetNeighborListPointers(
440  &number_of_neighbor_lists,
441  &cutoff_cluster_model,
442  &modelWillNotRequestNeighborsOfNoncontributingParticles);
443 
444  compute_loop(MinSpacing,
445  MaxSpacing,
446  SpacingIncr,
447  numberOfParticles_cluster,
448  &(coords_cluster[0][0]),
449  *cutoff_cluster_model,
450  &nl_cluster_model,
451  kim_cluster_model,
452  computeArguments,
453  forces_cluster,
454  &energy_cluster_model);
455  }
456 
457  int present;
458  kim_cluster_model->IsRoutinePresent(
460  if (present == true)
461  {
462  error = kim_cluster_model->WriteParameterizedModel(
463  ".", "This_IsTheNewModelName");
464  if (error) { MY_ERROR("WriteParameterizedModel returned an error."); }
465  }
466  }
467 
468  /* call compute arguments destroy */
469  error = kim_cluster_model->ComputeArgumentsDestroy(&computeArguments);
470  if (error) { MY_ERROR("Unable to destroy compute arguments"); }
471 
472  /* call model destroy */
473  KIM::Model::Destroy(&kim_cluster_model);
474 
475  /* free memory of neighbor lists */
476  delete[] nl_cluster_model.NNeighbors;
477  delete[] nl_cluster_model.neighborList;
478 
479  /* everything is great */
480  std::cout.copyfmt(oldState);
481  return 0;
482 }
483 
484 void compute_loop(double const MinSpacing,
485  double const MaxSpacing,
486  double const SpacingIncr,
487  int const numberOfParticles_cluster,
488  double * const coords_cluster,
489  double const cutoff,
490  NeighList * nl,
491  KIM::Model const * const kim_cluster_model,
492  KIM::ComputeArguments const * const computeArguments,
493  double * const forces_cluster,
494  double * const energy_cluster_model)
495 {
496  double const cutpad = 0.75; /* Angstroms */
497 
498  std::cout << std::setw(20) << "Energy" << std::setw(20) << "Force Norm"
499  << std::setw(20) << "Lattice Spacing" << std::endl;
500  for (double CurrentSpacing = MinSpacing; CurrentSpacing < MaxSpacing;
501  CurrentSpacing += SpacingIncr)
502  {
503  /* update coordinates for cluster */
504  create_FCC_cluster(CurrentSpacing, NCELLSPERSIDE, coords_cluster);
505  /* compute neighbor lists */
507  0, NCLUSTERPARTS, coords_cluster, (cutoff + cutpad), nl);
508 
509  /* call compute functions */
510  int error = kim_cluster_model->Compute(computeArguments);
511  if (error) MY_ERROR("compute");
512 
513  /* compute force norm */
514  double force_norm = 0.0;
515  for (int i = 0; i < DIM * numberOfParticles_cluster; ++i)
516  { force_norm += forces_cluster[i] * forces_cluster[i]; }
517  force_norm = sqrt(force_norm);
518 
519  /* print the results */
520  std::cout << std::setw(20) << *energy_cluster_model << std::setw(20)
521  << force_norm << std::setw(20) << CurrentSpacing << std::endl;
522  }
523 }
524 
525 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords)
526 {
527  /* local variables */
528  double FCCshifts[4][DIM];
529  double latVec[DIM];
530  int a;
531  int i;
532  int j;
533  int k;
534  int m;
535  int n;
536 
537  /* create a cubic FCC cluster of parts */
538  FCCshifts[0][0] = 0.0;
539  FCCshifts[0][1] = 0.0;
540  FCCshifts[0][2] = 0.0;
541  FCCshifts[1][0] = 0.5 * FCCspacing;
542  FCCshifts[1][1] = 0.5 * FCCspacing;
543  FCCshifts[1][2] = 0.0;
544  FCCshifts[2][0] = 0.5 * FCCspacing;
545  FCCshifts[2][1] = 0.0;
546  FCCshifts[2][2] = 0.5 * FCCspacing;
547  FCCshifts[3][0] = 0.0;
548  FCCshifts[3][1] = 0.5 * FCCspacing;
549  FCCshifts[3][2] = 0.5 * FCCspacing;
550 
551  a = 0;
552  for (i = 0; i < nCellsPerSide; ++i)
553  {
554  latVec[0] = ((double) i) * FCCspacing;
555  for (j = 0; j < nCellsPerSide; ++j)
556  {
557  latVec[1] = ((double) j) * FCCspacing;
558  for (k = 0; k < nCellsPerSide; ++k)
559  {
560  latVec[2] = ((double) k) * FCCspacing;
561  for (m = 0; m < 4; ++m)
562  {
563  for (n = 0; n < DIM; ++n)
564  { coords[a * DIM + n] = latVec[n] + FCCshifts[m][n]; }
565  a++;
566  }
567  }
568  /* add in the remaining three faces */
569  /* pos-x face */
570  latVec[0] = NCELLSPERSIDE * FCCspacing;
571  latVec[1] = ((double) i) * FCCspacing;
572  latVec[2] = ((double) j) * FCCspacing;
573  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
574  a++;
575  for (n = 0; n < DIM; ++n)
576  { coords[a * DIM + n] = latVec[n] + FCCshifts[3][n]; }
577  a++;
578  /* pos-y face */
579  latVec[0] = ((double) i) * FCCspacing;
580  latVec[1] = NCELLSPERSIDE * FCCspacing;
581  latVec[2] = ((double) j) * FCCspacing;
582  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
583  a++;
584  for (n = 0; n < DIM; ++n)
585  { coords[a * DIM + n] = latVec[n] + FCCshifts[2][n]; }
586  a++;
587  /* pos-z face */
588  latVec[0] = ((double) i) * FCCspacing;
589  latVec[1] = ((double) j) * FCCspacing;
590  latVec[2] = NCELLSPERSIDE * FCCspacing;
591  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
592  a++;
593  for (n = 0; n < DIM; ++n)
594  { coords[a * DIM + n] = latVec[n] + FCCshifts[1][n]; }
595  a++;
596  }
597  /* add in the remaining three edges */
598  latVec[0] = ((double) i) * FCCspacing;
599  latVec[1] = NCELLSPERSIDE * FCCspacing;
600  latVec[2] = NCELLSPERSIDE * FCCspacing;
601  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
602  a++;
603  latVec[0] = NCELLSPERSIDE * FCCspacing;
604  latVec[1] = ((double) i) * FCCspacing;
605  latVec[2] = NCELLSPERSIDE * FCCspacing;
606  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
607  a++;
608  latVec[0] = NCELLSPERSIDE * FCCspacing;
609  latVec[1] = NCELLSPERSIDE * FCCspacing;
610  latVec[2] = ((double) i) * FCCspacing;
611  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
612  a++;
613  }
614  /* add in the remaining corner */
615  for (n = 0; n < DIM; ++n)
616  { coords[a * DIM + n] = NCELLSPERSIDE * FCCspacing; }
617  a++;
618 
619  return;
620 }
621 
622 
624  int numberOfParticles,
625  double * coords,
626  double cutoff,
627  NeighList * nl)
628 {
629  /* local variables */
630  int i;
631  int j;
632  int k;
633  int a;
634 
635  double dx[DIM];
636  double r2;
637  double cutoff2;
638 
639  nl->cutoff = cutoff;
640 
641  cutoff2 = cutoff * cutoff;
642 
643  for (i = 0; i < numberOfParticles; ++i)
644  {
645  a = 0;
646  for (j = 0; j < numberOfParticles; ++j)
647  {
648  r2 = 0.0;
649  for (k = 0; k < DIM; ++k)
650  {
651  dx[k] = coords[j * DIM + k] - coords[i * DIM + k];
652  r2 += dx[k] * dx[k];
653  }
654 
655  if (r2 < cutoff2)
656  {
657  if ((half && i < j) || (!half && i != j))
658  {
659  /* part j is a neighbor of part i */
660  (*nl).neighborList[i * NCLUSTERPARTS + a] = j;
661  a++;
662  }
663  }
664  }
665  /* part i has `a' neighbors */
666  (*nl).NNeighbors[i] = a;
667  }
668 
669  return;
670 }
671 
672 int get_cluster_neigh(void * const dataObject,
673  int const numberOfNeighborLists,
674  double const * const cutoffs,
675  int const neighborListIndex,
676  int const particleNumber,
677  int * const numberOfNeighbors,
678  int const ** const neighborsOfParticle)
679 {
680  /* local variables */
681  int error = true;
682  NeighList * nl = (NeighList *) dataObject;
684 
685  if ((numberOfNeighborLists != 1) || (cutoffs[0] > nl->cutoff)) return error;
686 
687  if (neighborListIndex != 0) return error;
688 
689  /* initialize numNeigh */
690  *numberOfNeighbors = 0;
691 
692  if ((particleNumber >= numberOfParticles)
693  || (particleNumber < 0)) /* invalid id */
694  {
695  MY_WARNING("Invalid part ID in get_cluster_neigh");
696  return true;
697  }
698 
699  /* set the returned number of neighbors for the returned part */
700  *numberOfNeighbors = (*nl).NNeighbors[particleNumber];
701 
702  /* set the location for the returned neighbor list */
703  *neighborsOfParticle
704  = &((*nl).neighborList[(particleNumber) *numberOfParticles]);
705 
706  return false;
707 }
int SetArgumentPointer(ComputeArgumentName const computeArgumentName, int const *const ptr)
Set the data pointer for a ComputeArgumentName.
ModelRoutineName const WriteParameterizedModel
The standard WriteParameterizedModel routine.
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 TemperatureUnit&#39;s supported by the KIM API.
SpeciesName const Ar
The standard Argon species.
An Extensible Enumeration for the TimeUnit&#39;s supported by the KIM API.
int WriteParameterizedModel(std::string const &path, std::string const &modelName) const
Call the Model&#39;s MODEL_ROUTINE_NAME::WriteParameterizedModel routine.
An Extensible Enumeration for the ModelRoutineName&#39;s supported by the KIM API.
int GetComputeCallbackName(int const index, ComputeCallbackName *const computeCallbackName)
Get the identity of each defined standard ComputeCallbackName.
std::string const & ToString() const
Converts the object to a string.
Contains the enumeration constants and the discovery routines for the ModelRoutineName Extensible Enu...
TimeUnit const ps
The standard picosecond unit of time.
ModelRoutineName const Extension
The standard Extension routine.
ModelRoutineName const Create
The standard Create routine.
#define FCCSPACING
#define KIM_SUPPORTED_EXTENSIONS_ID
ComputeArgumentName const coordinates
The standard coordinates argument.
void GetNumberOfComputeCallbackNames(int *const numberOfComputeCallbackNames)
Get the number of standard ComputeCallbackName&#39;s defined by the KIM API.
ModelRoutineName const Destroy
The standard Destroy routine.
char supportedExtensionID[KIM_MAX_NUMBER_OF_EXTENSIONS][KIM_MAX_EXTENSION_ID_LENGTH]
The unique extension ID&#39;s of each supported extension.
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.
ChargeUnit const e
The standard electron unit of charge.
void GetNumberOfComputeArgumentNames(int *const numberOfComputeArgumentNames)
Get the number of standard ComputeArgumentName&#39;s defined by the KIM API.
void GetNeighborListPointers(int *const numberOfNeighborLists, double const **const cutoffs, int const **const modelWillNotRequestNeighborsOfNoncontributingParticles) const
Get the Model&#39;s neighbor list information.
std::string const & ToString() const
Converts the object to a string.
An Extensible Enumeration for the DataType&#39;s supported by the KIM API.
int ComputeArgumentsCreate(ComputeArguments **const computeArguments) const
Create a new ComputeArguments object for the Model object.
ComputeCallbackName const GetNeighborList
The standard GetNeighborList callback.
An Extensible Enumeration for the ComputeCallbackName&#39;s supported by the KIM API. ...
SupportStatus const required
The standard required status.
An Extensible Enumeration for the LengthUnit&#39;s supported by the KIM API.
int Compute(ComputeArguments const *const computeArguments) const
Call the Model&#39;s MODEL_ROUTINE_NAME::Compute routine.
void() Function(void)
Generic function type.
int SetParameter(int const parameterIndex, int const arrayIndex, int const parameterValue)
Set a parameter value for the Model.
void GetInfluenceDistance(double *const influenceDistance) const
Get the Model&#39;s influence distance.
int Extension(std::string const &extensionID, void *const extensionStructure)
Call the Model&#39;s MODEL_ROUTINE_NAME::Extension routine.
An Extensible Enumeration for the SupportStatus&#39;s supported by the KIM API.
ComputeArgumentName const particleContributing
The standard particleContributing argument.
int GetCallbackSupportStatus(ComputeCallbackName const computeCallbackName, SupportStatus *const supportStatus) const
Get the SupportStatus of a ComputeCallbackName.
ComputeArgumentName const partialEnergy
The standard partialEnergy argument.
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)
ModelRoutineName const Refresh
The standard Refresh routine.
Provides the primary interface to a KIM API Model object and is meant to be used by simulators...
Definition: KIM_Model.hpp:61
std::string const & ToString() const
Converts the object to a string.
std::string const & ToString() const
Converts the object to a string.
void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double *coords)
ModelRoutineName const ComputeArgumentsCreate
The standard ComputeArgumentsCreate routine.
ModelRoutineName const ComputeArgumentsDestroy
The standard ComputeArgumentsDestroy routine.
LengthUnit const m
The standard meter unit of length.
static void Destroy(Model **const model)
Destroy a previously Model::Create&#39;d object.
std::string const & ToString() const
Converts the object to a string.
An Extensible Enumeration for the EnergyUnit&#39;s supported by the KIM API.
LanguageName const cpp
The standard cpp language.
ModelRoutineName const Compute
The standard Compute routine.
int numberOfSupportedExtensions
The number of extensions supported by the Model.
int GetArgumentSupportStatus(ComputeArgumentName const computeArgumentName, SupportStatus *const supportStatus) const
Get the SupportStatus of a ComputeArgumentName.
int supportedExtensionRequired[KIM_MAX_NUMBER_OF_EXTENSIONS]
LengthUnit const A
The standard angstrom unit of length.
DataType const Double
The standard Double data type.
The only standard extension defined by the KIM API.
ComputeArgumentName const partialForces
The standard partialForces argument.
std::string const & ToString() const
Converts the object to a string.
#define NCELLSPERSIDE
std::string const & ToString() const
Converts the object to a string.
An Extensible Enumeration for the ComputeArgumentName&#39;s supported by the KIM API. ...
Provides the primary interface to a KIM API ComputeArguments object and is meant to be used by simula...
void GetNumberOfParameters(int *const numberOfParameters) const
Get the number of parameter arrays provided by the Model.
#define NCLUSTERPARTS
EnergyUnit const eV
The standard electronvolt unit of energy.
ComputeArgumentName const particleSpeciesCodes
The standard particleSpeciesCodes argument.
An Extensible Enumeration for the ChargeUnit&#39;s supported by the KIM API.
ComputeArgumentName const numberOfParticles
The standard numberOfParticles argument.
int GetParameter(int const parameterIndex, int const arrayIndex, int *const parameterValue) const
Get a parameter value from the Model.
int GetModelRoutineName(int const index, ModelRoutineName *const modelRoutineName)
Get the identity of each defined standard 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.
int ComputeArgumentsDestroy(ComputeArguments **const computeArguments) const
Destroy a previously Model::ComputeArgumentsCreate&#39;d object.
#define MY_WARNING(message)
int SetCallbackPointer(ComputeCallbackName const computeCallbackName, LanguageName const languageName, Function *const fptr, void *const dataObject)
Set the function pointer for a ComputeCallbackName.
int IsRoutinePresent(ModelRoutineName const modelRoutineName, int *const present, int *const required) const
Determine presence and required status of the given ModelRoutineName.
#define MY_ERROR(message)
Numbering const zeroBased
The standard zeroBased numbering.
std::string const & ToString() const
Converts the object to a string.
std::string const & ToString() const
Converts the object to a string.
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)
int GetComputeArgumentDataType(ComputeArgumentName const computeArgumentName, DataType *const dataType)
Get the DataType of each defined standard ComputeArgumentName.
int GetComputeArgumentName(int const index, ComputeArgumentName *const computeArgumentName)
Get the identity of each defined standard ComputeArgumentName.
LogVerbosity const error
The standard error verbosity.
void GetNumberOfModelRoutineNames(int *const numberOfModelRoutineNames)
Get the number of standard ModelRoutineName&#39;s defined by the KIM API.
int ClearThenRefresh()
Clear influence distance and neighbor list pointers and refresh Model object after parameter changes...
void fcc_cluster_neighborlist(int half, int numberOfParticles, double *coords, double cutoff, NeighList *nl)
SupportStatus const optional
The standard optional status.
TemperatureUnit const K
The standard Kelvin unit of temperature.