kim-api  2.2.1+v2.2.1.GNU.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--2020, 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  {
211  MY_ERROR("Species Ar not supported");
212  }
213 
214  KIM::ComputeArguments * computeArguments;
215  error = kim_cluster_model->ComputeArgumentsCreate(&computeArguments);
216  if (error) { MY_ERROR("Unable to create a ComputeArguments object."); }
217 
218  // check compute arguments
219  int numberOfComputeArgumentNames;
221  &numberOfComputeArgumentNames);
222  for (int i = 0; i < numberOfComputeArgumentNames; ++i)
223  {
224  KIM::ComputeArgumentName computeArgumentName;
225  KIM::SupportStatus supportStatus;
227  KIM::DataType dataType;
229  &dataType);
230  error = computeArguments->GetArgumentSupportStatus(computeArgumentName,
231  &supportStatus);
232  if (error) MY_ERROR("unable to get ComputeArgument SupportStatus");
233 
234  std::cout << "ComputeArgument Name \"" << computeArgumentName.ToString()
235  << "\""
236  << " is of type \"" << dataType.ToString() << "\""
237  << " and has supportStatus \"" << supportStatus.ToString() << "\""
238  << std::endl;
239 
240  // can only handle energy and force as a required arg
241  if (supportStatus == KIM::SUPPORT_STATUS::required)
242  {
243  if ((computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
244  && (computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialForces))
245  {
246  MY_ERROR("unsupported required ComputeArgument");
247  }
248  }
249 
250  // must have energy and forces
251  if ((computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
252  || (computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialForces))
253  {
254  if (!((supportStatus == KIM::SUPPORT_STATUS::required)
255  || (supportStatus == KIM::SUPPORT_STATUS::optional)))
256  {
257  MY_ERROR("energy or forces not available");
258  }
259  }
260  }
261 
262  // check compute callbacks
263  int numberOfComputeCallbackNames;
265  &numberOfComputeCallbackNames);
266  for (int i = 0; i < numberOfComputeCallbackNames; ++i)
267  {
268  KIM::ComputeCallbackName computeCallbackName;
270  KIM::SupportStatus supportStatus;
271  computeArguments->GetCallbackSupportStatus(computeCallbackName,
272  &supportStatus);
273 
274  std::cout << "ComputeCallback Name \"" << computeCallbackName.ToString()
275  << "\""
276  << " has supportStatus \"" << supportStatus.ToString() << "\""
277  << std::endl;
278 
279  // cannot handle any "required" callbacks
280  if (supportStatus == KIM::SUPPORT_STATUS::required)
281  {
282  MY_ERROR("unsupported required ComputeCallback");
283  }
284  }
285 
286  int numberOfParameters;
287  kim_cluster_model->GetNumberOfParameters(&numberOfParameters);
288  for (int i = 0; i < numberOfParameters; ++i)
289  {
290  KIM::DataType dataType;
291  std::string const * strName;
292  std::string const * strDesc;
293  int extent;
294  kim_cluster_model->GetParameterMetadata(
295  i, &dataType, &extent, &strName, &strDesc);
296  std::cout << "Parameter No. " << i << " has" << std::endl
297  << " data type : \"" << dataType.ToString() << "\"" << std::endl
298  << " extent : " << extent << std::endl
299  << " name : " << *strName << std::endl
300  << " description : " << *strDesc << std::endl;
301  }
302 
303  // Check supported extensions, if any
304  int present;
305  error = kim_cluster_model->IsRoutinePresent(
306  KIM::MODEL_ROUTINE_NAME::Extension, &present, NULL);
307  if (error) { MY_ERROR("Unable to get Extension present/required."); }
308  if (present)
309  {
310  KIM::SupportedExtensions supportedExtensions;
311  error = kim_cluster_model->Extension(KIM_SUPPORTED_EXTENSIONS_ID,
312  &supportedExtensions);
313  if (error) { MY_ERROR("Error returned from KIM::Model::Extension()."); }
314  std::cout << "Model Supports "
315  << supportedExtensions.numberOfSupportedExtensions
316  << " Extensions:" << std::endl;
317  for (int i = 0; i < supportedExtensions.numberOfSupportedExtensions; ++i)
318  {
319  std::cout << " spportedExtensionID[" << std::setw(2) << i << "] = \""
320  << supportedExtensions.supportedExtensionID[i] << "\" "
321  << "which has required = "
322  << supportedExtensions.supportedExtensionRequired[i] << "."
323  << std::endl;
324  }
325  }
326 
327  // We're compatible with the model. Let's do it.
328 
329  error
330  = computeArguments->SetArgumentPointer(
332  (int *) &numberOfParticles_cluster)
333  || computeArguments->SetArgumentPointer(
335  particleSpecies_cluster_model)
336  || computeArguments->SetArgumentPointer(
338  particleContributing_cluster_model)
339  || computeArguments->SetArgumentPointer(
340  KIM::COMPUTE_ARGUMENT_NAME::coordinates, (double *) coords_cluster)
341  || computeArguments->SetArgumentPointer(
342  KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, &energy_cluster_model)
343  || computeArguments->SetArgumentPointer(
345  (double *) forces_cluster);
346  if (error) MY_ERROR("KIM_API_set_data");
347  error = computeArguments->SetCallbackPointer(
351  &nl_cluster_model);
352  if (error) MY_ERROR("set_call_back");
353 
354  kim_cluster_model->GetInfluenceDistance(&influence_distance_cluster_model);
355  int const * modelWillNotRequestNeighborsOfNoncontributingParticles;
356  kim_cluster_model->GetNeighborListPointers(
357  &number_of_neighbor_lists,
358  &cutoff_cluster_model,
359  &modelWillNotRequestNeighborsOfNoncontributingParticles);
360  std::cout << "Model has influence distance of : "
361  << influence_distance_cluster_model << std::endl;
362  std::cout << "Model has numberOfNeighborLists : " << number_of_neighbor_lists
363  << std::endl;
364  for (int i = 0; i < number_of_neighbor_lists; ++i)
365  {
366  std::cout << "\t"
367  << "Neighbor list " << i << " has cutoff "
368  << cutoff_cluster_model[i]
369  << " with "
370  "modelWillNotRequestNeighborsOfNoncontributingParticles "
371  << modelWillNotRequestNeighborsOfNoncontributingParticles[i]
372  << std::endl;
373  }
374  // ignoring hints from here on...
375  if (number_of_neighbor_lists != 1) MY_ERROR("too many neighbor lists");
376 
377  /* setup particleSpecies */
378  int isSpeciesSupported;
379  error = kim_cluster_model->GetSpeciesSupportAndCode(
381  &isSpeciesSupported,
382  &(particleSpecies_cluster_model[0]));
383  if (error) MY_ERROR("get_species_code");
384  for (i = 1; i < NCLUSTERPARTS; ++i)
385  particleSpecies_cluster_model[i] = particleSpecies_cluster_model[0];
386  /* setup particleContributing */
387  for (i = 0; i < NCLUSTERPARTS; ++i)
388  particleContributing_cluster_model[i] = 1; /* every particle contributes */
389 
390  /* setup neighbor lists */
391  /* allocate memory for list */
392  nl_cluster_model.numberOfParticles = NCLUSTERPARTS;
393  nl_cluster_model.NNeighbors = new int[NCLUSTERPARTS];
394  if (NULL == nl_cluster_model.NNeighbors) MY_ERROR("new unsuccessful");
395 
396  nl_cluster_model.neighborList = new int[NCLUSTERPARTS * NCLUSTERPARTS];
397  if (NULL == nl_cluster_model.neighborList) MY_ERROR("new unsuccessful");
398 
399  /* ready to compute */
400  std::ios oldState(NULL);
401  oldState.copyfmt(std::cout);
402  std::cout << std::setiosflags(std::ios::scientific) << std::setprecision(10);
403  std::cout << "This is Test : ex_test_Ar_fcc_cluster_cpp\n";
404  std::cout << "---------------------------------------------------------------"
405  "-----------------\n";
406  std::cout << "Results for KIM Model : " << modelname << std::endl;
407 
408  compute_loop(MinSpacing,
409  MaxSpacing,
410  SpacingIncr,
411  numberOfParticles_cluster,
412  &(coords_cluster[0][0]),
413  *cutoff_cluster_model,
414  &nl_cluster_model,
415  kim_cluster_model,
416  computeArguments,
417  forces_cluster,
418  &energy_cluster_model);
419 
420  if (numberOfParameters > 0)
421  {
422  int index = numberOfParameters / 2;
423  KIM::DataType dataType;
424  std::string const * name;
425  double value;
426  error = kim_cluster_model->GetParameterMetadata(
427  index, &dataType, NULL, &name, NULL);
428  if (error) { MY_ERROR("Cannot get parameter metadata."); }
429  if (dataType != KIM::DATA_TYPE::Double)
430  {
431  MY_WARNING("Can't change an integer.");
432  }
433  else
434  {
435  error = kim_cluster_model->GetParameter(index, 0, &value);
436  if (error) { MY_ERROR("Cannot get parameter value."); }
437  value *= 1.5;
438  error = kim_cluster_model->SetParameter(index, 0, value);
439  if (error) { MY_ERROR("Cannot set parameter value."); }
440  error = kim_cluster_model->ClearThenRefresh();
441  if (error) { MY_ERROR("Model ClearThenRefresh returned error."); }
442 
443  std::cout << std::endl
444  << "Updated parameter \"" << *name << "\" to value " << value
445  << "." << std::endl;
446 
447  kim_cluster_model->GetInfluenceDistance(
448  &influence_distance_cluster_model);
449  kim_cluster_model->GetNeighborListPointers(
450  &number_of_neighbor_lists,
451  &cutoff_cluster_model,
452  &modelWillNotRequestNeighborsOfNoncontributingParticles);
453 
454  compute_loop(MinSpacing,
455  MaxSpacing,
456  SpacingIncr,
457  numberOfParticles_cluster,
458  &(coords_cluster[0][0]),
459  *cutoff_cluster_model,
460  &nl_cluster_model,
461  kim_cluster_model,
462  computeArguments,
463  forces_cluster,
464  &energy_cluster_model);
465  }
466 
467  int present;
468  kim_cluster_model->IsRoutinePresent(
470  if (present == true)
471  {
472  error = kim_cluster_model->WriteParameterizedModel(
473  ".", "This_IsTheNewModelName");
474  if (error) { MY_ERROR("WriteParameterizedModel returned an error."); }
475  }
476  }
477 
478  /* call compute arguments destroy */
479  error = kim_cluster_model->ComputeArgumentsDestroy(&computeArguments);
480  if (error) { MY_ERROR("Unable to destroy compute arguments"); }
481 
482  /* call model destroy */
483  KIM::Model::Destroy(&kim_cluster_model);
484 
485  /* free memory of neighbor lists */
486  delete[] nl_cluster_model.NNeighbors;
487  delete[] nl_cluster_model.neighborList;
488 
489  /* everything is great */
490  std::cout.copyfmt(oldState);
491  return 0;
492 }
493 
494 void compute_loop(double const MinSpacing,
495  double const MaxSpacing,
496  double const SpacingIncr,
497  int const numberOfParticles_cluster,
498  double * const coords_cluster,
499  double const cutoff,
500  NeighList * nl,
501  KIM::Model const * const kim_cluster_model,
502  KIM::ComputeArguments const * const computeArguments,
503  double * const forces_cluster,
504  double * const energy_cluster_model)
505 {
506  double const cutpad = 0.75; /* Angstroms */
507 
508  std::cout << std::setw(20) << "Energy" << std::setw(20) << "Force Norm"
509  << std::setw(20) << "Lattice Spacing" << std::endl;
510  for (double CurrentSpacing = MinSpacing; CurrentSpacing < MaxSpacing;
511  CurrentSpacing += SpacingIncr)
512  {
513  /* update coordinates for cluster */
514  create_FCC_cluster(CurrentSpacing, NCELLSPERSIDE, coords_cluster);
515  /* compute neighbor lists */
517  0, NCLUSTERPARTS, coords_cluster, (cutoff + cutpad), nl);
518 
519  /* call compute functions */
520  int error = kim_cluster_model->Compute(computeArguments);
521  if (error) MY_ERROR("compute");
522 
523  /* compute force norm */
524  double force_norm = 0.0;
525  for (int i = 0; i < DIM * numberOfParticles_cluster; ++i)
526  {
527  force_norm += forces_cluster[i] * forces_cluster[i];
528  }
529  force_norm = sqrt(force_norm);
530 
531  /* print the results */
532  std::cout << std::setw(20) << *energy_cluster_model << std::setw(20)
533  << force_norm << std::setw(20) << CurrentSpacing << std::endl;
534  }
535 }
536 
537 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords)
538 {
539  /* local variables */
540  double FCCshifts[4][DIM];
541  double latVec[DIM];
542  int a;
543  int i;
544  int j;
545  int k;
546  int m;
547  int n;
548 
549  /* create a cubic FCC cluster of parts */
550  FCCshifts[0][0] = 0.0;
551  FCCshifts[0][1] = 0.0;
552  FCCshifts[0][2] = 0.0;
553  FCCshifts[1][0] = 0.5 * FCCspacing;
554  FCCshifts[1][1] = 0.5 * FCCspacing;
555  FCCshifts[1][2] = 0.0;
556  FCCshifts[2][0] = 0.5 * FCCspacing;
557  FCCshifts[2][1] = 0.0;
558  FCCshifts[2][2] = 0.5 * FCCspacing;
559  FCCshifts[3][0] = 0.0;
560  FCCshifts[3][1] = 0.5 * FCCspacing;
561  FCCshifts[3][2] = 0.5 * FCCspacing;
562 
563  a = 0;
564  for (i = 0; i < nCellsPerSide; ++i)
565  {
566  latVec[0] = ((double) i) * FCCspacing;
567  for (j = 0; j < nCellsPerSide; ++j)
568  {
569  latVec[1] = ((double) j) * FCCspacing;
570  for (k = 0; k < nCellsPerSide; ++k)
571  {
572  latVec[2] = ((double) k) * FCCspacing;
573  for (m = 0; m < 4; ++m)
574  {
575  for (n = 0; n < DIM; ++n)
576  {
577  coords[a * DIM + n] = latVec[n] + FCCshifts[m][n];
578  }
579  a++;
580  }
581  }
582  /* add in the remaining three faces */
583  /* pos-x face */
584  latVec[0] = NCELLSPERSIDE * FCCspacing;
585  latVec[1] = ((double) i) * FCCspacing;
586  latVec[2] = ((double) j) * FCCspacing;
587  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
588  a++;
589  for (n = 0; n < DIM; ++n)
590  {
591  coords[a * DIM + n] = latVec[n] + FCCshifts[3][n];
592  }
593  a++;
594  /* pos-y face */
595  latVec[0] = ((double) i) * FCCspacing;
596  latVec[1] = NCELLSPERSIDE * FCCspacing;
597  latVec[2] = ((double) j) * FCCspacing;
598  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
599  a++;
600  for (n = 0; n < DIM; ++n)
601  {
602  coords[a * DIM + n] = latVec[n] + FCCshifts[2][n];
603  }
604  a++;
605  /* pos-z face */
606  latVec[0] = ((double) i) * FCCspacing;
607  latVec[1] = ((double) j) * FCCspacing;
608  latVec[2] = NCELLSPERSIDE * FCCspacing;
609  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
610  a++;
611  for (n = 0; n < DIM; ++n)
612  {
613  coords[a * DIM + n] = latVec[n] + FCCshifts[1][n];
614  }
615  a++;
616  }
617  /* add in the remaining three edges */
618  latVec[0] = ((double) i) * FCCspacing;
619  latVec[1] = NCELLSPERSIDE * FCCspacing;
620  latVec[2] = NCELLSPERSIDE * FCCspacing;
621  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
622  a++;
623  latVec[0] = NCELLSPERSIDE * FCCspacing;
624  latVec[1] = ((double) i) * FCCspacing;
625  latVec[2] = NCELLSPERSIDE * FCCspacing;
626  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
627  a++;
628  latVec[0] = NCELLSPERSIDE * FCCspacing;
629  latVec[1] = NCELLSPERSIDE * FCCspacing;
630  latVec[2] = ((double) i) * FCCspacing;
631  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
632  a++;
633  }
634  /* add in the remaining corner */
635  for (n = 0; n < DIM; ++n)
636  {
637  coords[a * DIM + n] = NCELLSPERSIDE * FCCspacing;
638  }
639  a++;
640 
641  return;
642 }
643 
644 
646  int numberOfParticles,
647  double * coords,
648  double cutoff,
649  NeighList * nl)
650 {
651  /* local variables */
652  int i;
653  int j;
654  int k;
655  int a;
656 
657  double dx[DIM];
658  double r2;
659  double cutoff2;
660 
661  nl->cutoff = cutoff;
662 
663  cutoff2 = cutoff * cutoff;
664 
665  for (i = 0; i < numberOfParticles; ++i)
666  {
667  a = 0;
668  for (j = 0; j < numberOfParticles; ++j)
669  {
670  r2 = 0.0;
671  for (k = 0; k < DIM; ++k)
672  {
673  dx[k] = coords[j * DIM + k] - coords[i * DIM + k];
674  r2 += dx[k] * dx[k];
675  }
676 
677  if (r2 < cutoff2)
678  {
679  if ((half && i < j) || (!half && i != j))
680  {
681  /* part j is a neighbor of part i */
682  (*nl).neighborList[i * NCLUSTERPARTS + a] = j;
683  a++;
684  }
685  }
686  }
687  /* part i has `a' neighbors */
688  (*nl).NNeighbors[i] = a;
689  }
690 
691  return;
692 }
693 
694 int get_cluster_neigh(void * const dataObject,
695  int const numberOfNeighborLists,
696  double const * const cutoffs,
697  int const neighborListIndex,
698  int const particleNumber,
699  int * const numberOfNeighbors,
700  int const ** const neighborsOfParticle)
701 {
702  /* local variables */
703  int error = true;
704  NeighList * nl = (NeighList *) dataObject;
706 
707  if ((numberOfNeighborLists != 1) || (cutoffs[0] > nl->cutoff)) return error;
708 
709  if (neighborListIndex != 0) return error;
710 
711  /* initialize numNeigh */
712  *numberOfNeighbors = 0;
713 
714  if ((particleNumber >= numberOfParticles)
715  || (particleNumber < 0)) /* invalid id */
716  {
717  MY_WARNING("Invalid part ID in get_cluster_neigh");
718  return true;
719  }
720 
721  /* set the returned number of neighbors for the returned part */
722  *numberOfNeighbors = (*nl).NNeighbors[particleNumber];
723 
724  /* set the location for the returned neighbor list */
725  *neighborsOfParticle
726  = &((*nl).neighborList[(particleNumber) *numberOfParticles]);
727 
728  return false;
729 }
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.