kim-api  2.3.0+v2.3.0.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 // KIM-API: An API for interatomic models
3 // Copyright (c) 2013--2022, Regents of the University of Minnesota.
4 // All rights reserved.
5 //
6 // Contributors:
7 // Ryan S. Elliott
8 // Stephen M. Whalen
9 //
10 // SPDX-License-Identifier: LGPL-2.1-or-later
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with this library; if not, write to the Free Software Foundation,
24 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 //
26 
27 
28 #include "KIM_SimulatorHeaders.hpp"
30 #include <cmath>
31 #include <iomanip>
32 #include <iostream>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string>
36 
37 #define NAMESTRLEN 128
38 
39 #define FCCSPACING 5.260
40 #define DIM 3
41 #define NCELLSPERSIDE 2
42 #define NCLUSTERPARTS \
43  (4 * (NCELLSPERSIDE * NCELLSPERSIDE * NCELLSPERSIDE) \
44  + 6 * (NCELLSPERSIDE * NCELLSPERSIDE) + 3 * (NCELLSPERSIDE) + 1)
45 
46 #define MY_ERROR(message) \
47  { \
48  std::cout << "* Error : \"" << message << "\" : " << __LINE__ << ":" \
49  << __FILE__ << std::endl; \
50  exit(1); \
51  }
52 
53 #define MY_WARNING(message) \
54  { \
55  std::cout << "* Warning : \"" << message << "\" : " << __LINE__ << ":" \
56  << __FILE__ << std::endl; \
57  }
58 
59 
60 /* Define neighborlist structure */
61 typedef struct
62 {
63  double cutoff;
65  int * NNeighbors;
66  int * neighborList;
67 } NeighList;
68 
69 /* Define prototypes */
70 void fcc_cluster_neighborlist(int half,
72  double * coords,
73  double cutoff,
74  NeighList * nl);
75 
76 int get_cluster_neigh(void * const dataObject,
77  int const numberOfNeighborLists,
78  double const * const cutoffs,
79  int const neighborListIndex,
80  int const particleNumber,
81  int * const numberOfNeighbors,
82  int const ** const neighborsOfParticle);
83 
84 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords);
85 
86 void compute_loop(double const MinSpacing,
87  double const MaxSpacing,
88  double const SpacingIncr,
89  int const numberOfParticles_cluster,
90  double * const coords_cluster,
91  double const cutoff,
92  NeighList * nl,
93  KIM::Model const * const kim_cluster_model,
94  KIM::ComputeArguments const * const computeArguments,
95  double * const forces_cluster,
96  double * const energy_cluster_model);
97 
98 
99 /* Main program */
100 int main()
101 {
102  /* Local variable declarations */
103  double const MinSpacing = 0.8 * FCCSPACING;
104  double const MaxSpacing = 1.2 * FCCSPACING;
105  double const SpacingIncr = 0.025 * FCCSPACING;
106  int i;
107  int error;
108 
109 
110  /* model inputs */
111  int numberOfParticles_cluster = NCLUSTERPARTS;
112  int particleSpecies_cluster_model[NCLUSTERPARTS];
113  int particleContributing_cluster_model[NCLUSTERPARTS];
114  double coords_cluster[NCLUSTERPARTS][DIM];
115  NeighList nl_cluster_model;
116  /* model outputs */
117  double influence_distance_cluster_model;
118  int number_of_neighbor_lists;
119  double const * cutoff_cluster_model;
120  double energy_cluster_model;
121  double forces_cluster[NCLUSTERPARTS * DIM];
122 
123  std::string modelname;
124 
125  /* Get KIM Model names */
126  printf("Please enter valid KIM Model name: \n");
127  std::cin >> modelname;
128 
129 
130  /* initialize the model */
131  KIM::Model * kim_cluster_model;
132  int requestedUnitsAccepted;
139  modelname,
140  &requestedUnitsAccepted,
141  &kim_cluster_model);
142  if (error) { MY_ERROR("KIM::Model::Create()"); }
143 
144  // Check for compatibility with the model
145  if (!requestedUnitsAccepted) { MY_ERROR("Must Adapt to model units"); }
146 
147  // Check that we know about all required routines
148  int numberOfModelRoutineNames;
150  &numberOfModelRoutineNames);
151  for (int i = 0; i < numberOfModelRoutineNames; ++i)
152  {
153  KIM::ModelRoutineName modelRoutineName;
154  int error
155  = KIM::MODEL_ROUTINE_NAME::GetModelRoutineName(i, &modelRoutineName);
156  if (error) { MY_ERROR("Unable to get ModelRoutineName."); }
157  int present;
158  int required;
159  error = kim_cluster_model->IsRoutinePresent(
160  modelRoutineName, &present, &required);
161  if (error) { MY_ERROR("Unable to get routine present/required."); }
162 
163  std::cout << "Model routine name \"" << modelRoutineName.ToString()
164  << "\" has present = " << present
165  << " and required = " << required << "." << std::endl;
166 
167  if ((present == true) && (required == true))
168  {
169  using namespace KIM::MODEL_ROUTINE_NAME;
170  if (!((modelRoutineName == Create)
171  || (modelRoutineName == ComputeArgumentsCreate)
172  || (modelRoutineName == Compute) || (modelRoutineName == Refresh)
173  || (modelRoutineName == ComputeArgumentsDestroy)
174  || (modelRoutineName == Destroy)))
175  {
176  MY_ERROR("Unknown Routine \"" + modelRoutineName.ToString()
177  + "\" is required by model.");
178  }
179  }
180  }
181 
182  // print model units
183  KIM::LengthUnit lengthUnit;
184  KIM::EnergyUnit energyUnit;
185  KIM::ChargeUnit chargeUnit;
186  KIM::TemperatureUnit temperatureUnit;
187  KIM::TimeUnit timeUnit;
188 
189  kim_cluster_model->GetUnits(
190  &lengthUnit, &energyUnit, &chargeUnit, &temperatureUnit, &timeUnit);
191 
192  std::cout << "LengthUnit is \"" << lengthUnit.ToString() << "\"" << std::endl
193  << "EnergyUnit is \"" << energyUnit.ToString() << "\"" << std::endl
194  << "ChargeUnit is \"" << chargeUnit.ToString() << "\"" << std::endl
195  << "TemperatureUnit is \"" << temperatureUnit.ToString() << "\""
196  << std::endl
197  << "TimeUnit is \"" << timeUnit.ToString() << "\"" << std::endl;
198 
199  // check species
200  int speciesIsSupported;
201  int modelArCode;
202  error = kim_cluster_model->GetSpeciesSupportAndCode(
203  KIM::SPECIES_NAME::Ar, &speciesIsSupported, &modelArCode);
204  if ((error) || (!speciesIsSupported))
205  {
206  MY_ERROR("Species Ar not supported");
207  }
208 
209  KIM::ComputeArguments * computeArguments;
210  error = kim_cluster_model->ComputeArgumentsCreate(&computeArguments);
211  if (error) { MY_ERROR("Unable to create a ComputeArguments object."); }
212 
213  // check compute arguments
214  int numberOfComputeArgumentNames;
216  &numberOfComputeArgumentNames);
217  for (int i = 0; i < numberOfComputeArgumentNames; ++i)
218  {
219  KIM::ComputeArgumentName computeArgumentName;
220  KIM::SupportStatus supportStatus;
222  KIM::DataType dataType;
224  &dataType);
225  error = computeArguments->GetArgumentSupportStatus(computeArgumentName,
226  &supportStatus);
227  if (error) MY_ERROR("unable to get ComputeArgument SupportStatus");
228 
229  std::cout << "ComputeArgument Name \"" << computeArgumentName.ToString()
230  << "\""
231  << " is of type \"" << dataType.ToString() << "\""
232  << " and has supportStatus \"" << supportStatus.ToString() << "\""
233  << std::endl;
234 
235  // can only handle energy and force as a required arg
236  if (supportStatus == KIM::SUPPORT_STATUS::required)
237  {
238  if ((computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
239  && (computeArgumentName != KIM::COMPUTE_ARGUMENT_NAME::partialForces))
240  {
241  MY_ERROR("unsupported required ComputeArgument");
242  }
243  }
244 
245  // must have energy and forces
246  if ((computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialEnergy)
247  || (computeArgumentName == KIM::COMPUTE_ARGUMENT_NAME::partialForces))
248  {
249  if (!((supportStatus == KIM::SUPPORT_STATUS::required)
250  || (supportStatus == KIM::SUPPORT_STATUS::optional)))
251  {
252  MY_ERROR("energy or forces not available");
253  }
254  }
255  }
256 
257  // check compute callbacks
258  int numberOfComputeCallbackNames;
260  &numberOfComputeCallbackNames);
261  for (int i = 0; i < numberOfComputeCallbackNames; ++i)
262  {
263  KIM::ComputeCallbackName computeCallbackName;
265  KIM::SupportStatus supportStatus;
266  computeArguments->GetCallbackSupportStatus(computeCallbackName,
267  &supportStatus);
268 
269  std::cout << "ComputeCallback Name \"" << computeCallbackName.ToString()
270  << "\""
271  << " has supportStatus \"" << supportStatus.ToString() << "\""
272  << std::endl;
273 
274  // cannot handle any "required" callbacks
275  if (supportStatus == KIM::SUPPORT_STATUS::required)
276  {
277  MY_ERROR("unsupported required ComputeCallback");
278  }
279  }
280 
281  int numberOfParameters;
282  kim_cluster_model->GetNumberOfParameters(&numberOfParameters);
283  for (int i = 0; i < numberOfParameters; ++i)
284  {
285  KIM::DataType dataType;
286  std::string const * strName;
287  std::string const * strDesc;
288  int extent;
289  kim_cluster_model->GetParameterMetadata(
290  i, &dataType, &extent, &strName, &strDesc);
291  std::cout << "Parameter No. " << i << " has" << std::endl
292  << " data type : \"" << dataType.ToString() << "\"" << std::endl
293  << " extent : " << extent << std::endl
294  << " name : " << *strName << std::endl
295  << " description : " << *strDesc << std::endl;
296  }
297 
298  // Check supported extensions, if any
299  int present;
300  error = kim_cluster_model->IsRoutinePresent(
301  KIM::MODEL_ROUTINE_NAME::Extension, &present, NULL);
302  if (error) { MY_ERROR("Unable to get Extension present/required."); }
303  if (present)
304  {
305  KIM::SupportedExtensions supportedExtensions;
306  error = kim_cluster_model->Extension(KIM_SUPPORTED_EXTENSIONS_ID,
307  &supportedExtensions);
308  if (error) { MY_ERROR("Error returned from KIM::Model::Extension()."); }
309  std::cout << "Model Supports "
310  << supportedExtensions.numberOfSupportedExtensions
311  << " Extensions:" << std::endl;
312  for (int i = 0; i < supportedExtensions.numberOfSupportedExtensions; ++i)
313  {
314  std::cout << " spportedExtensionID[" << std::setw(2) << i << "] = \""
315  << supportedExtensions.supportedExtensionID[i] << "\" "
316  << "which has required = "
317  << supportedExtensions.supportedExtensionRequired[i] << "."
318  << std::endl;
319  }
320  }
321 
322  // We're compatible with the model. Let's do it.
323 
324  error
325  = computeArguments->SetArgumentPointer(
327  (int *) &numberOfParticles_cluster)
328  || computeArguments->SetArgumentPointer(
330  particleSpecies_cluster_model)
331  || computeArguments->SetArgumentPointer(
333  particleContributing_cluster_model)
334  || computeArguments->SetArgumentPointer(
335  KIM::COMPUTE_ARGUMENT_NAME::coordinates, (double *) coords_cluster)
336  || computeArguments->SetArgumentPointer(
337  KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, &energy_cluster_model)
338  || computeArguments->SetArgumentPointer(
340  (double *) forces_cluster);
341  if (error) MY_ERROR("KIM_API_set_data");
342  error = computeArguments->SetCallbackPointer(
346  &nl_cluster_model);
347  if (error) MY_ERROR("set_call_back");
348 
349  kim_cluster_model->GetInfluenceDistance(&influence_distance_cluster_model);
350  int const * modelWillNotRequestNeighborsOfNoncontributingParticles;
351  kim_cluster_model->GetNeighborListPointers(
352  &number_of_neighbor_lists,
353  &cutoff_cluster_model,
354  &modelWillNotRequestNeighborsOfNoncontributingParticles);
355  std::cout << "Model has influence distance of : "
356  << influence_distance_cluster_model << std::endl;
357  std::cout << "Model has numberOfNeighborLists : " << number_of_neighbor_lists
358  << std::endl;
359  for (int i = 0; i < number_of_neighbor_lists; ++i)
360  {
361  std::cout << "\t"
362  << "Neighbor list " << i << " has cutoff "
363  << cutoff_cluster_model[i]
364  << " with "
365  "modelWillNotRequestNeighborsOfNoncontributingParticles "
366  << modelWillNotRequestNeighborsOfNoncontributingParticles[i]
367  << std::endl;
368  }
369  // ignoring hints from here on...
370  if (number_of_neighbor_lists != 1) MY_ERROR("too many neighbor lists");
371 
372  /* setup particleSpecies */
373  int isSpeciesSupported;
374  error = kim_cluster_model->GetSpeciesSupportAndCode(
376  &isSpeciesSupported,
377  &(particleSpecies_cluster_model[0]));
378  if (error) MY_ERROR("get_species_code");
379  for (i = 1; i < NCLUSTERPARTS; ++i)
380  particleSpecies_cluster_model[i] = particleSpecies_cluster_model[0];
381  /* setup particleContributing */
382  for (i = 0; i < NCLUSTERPARTS; ++i)
383  particleContributing_cluster_model[i] = 1; /* every particle contributes */
384 
385  /* setup neighbor lists */
386  /* allocate memory for list */
387  nl_cluster_model.numberOfParticles = NCLUSTERPARTS;
388  nl_cluster_model.NNeighbors = new int[NCLUSTERPARTS];
389  if (NULL == nl_cluster_model.NNeighbors) MY_ERROR("new unsuccessful");
390 
391  nl_cluster_model.neighborList = new int[NCLUSTERPARTS * NCLUSTERPARTS];
392  if (NULL == nl_cluster_model.neighborList) MY_ERROR("new unsuccessful");
393 
394  /* ready to compute */
395  std::ios oldState(NULL);
396  oldState.copyfmt(std::cout);
397  std::cout << std::setiosflags(std::ios::scientific) << std::setprecision(10);
398  std::cout << "This is Test : ex_test_Ar_fcc_cluster_cpp\n";
399  std::cout << "---------------------------------------------------------------"
400  "-----------------\n";
401  std::cout << "Results for KIM Model : " << modelname << std::endl;
402 
403  compute_loop(MinSpacing,
404  MaxSpacing,
405  SpacingIncr,
406  numberOfParticles_cluster,
407  &(coords_cluster[0][0]),
408  *cutoff_cluster_model,
409  &nl_cluster_model,
410  kim_cluster_model,
411  computeArguments,
412  forces_cluster,
413  &energy_cluster_model);
414 
415  if (numberOfParameters > 0)
416  {
417  int index = numberOfParameters / 2;
418  KIM::DataType dataType;
419  std::string const * name;
420  double value;
421  error = kim_cluster_model->GetParameterMetadata(
422  index, &dataType, NULL, &name, NULL);
423  if (error) { MY_ERROR("Cannot get parameter metadata."); }
424  if (dataType != KIM::DATA_TYPE::Double)
425  {
426  MY_WARNING("Can't change an integer.");
427  }
428  else
429  {
430  error = kim_cluster_model->GetParameter(index, 0, &value);
431  if (error) { MY_ERROR("Cannot get parameter value."); }
432  value *= 1.5;
433  error = kim_cluster_model->SetParameter(index, 0, value);
434  if (error) { MY_ERROR("Cannot set parameter value."); }
435  error = kim_cluster_model->ClearThenRefresh();
436  if (error) { MY_ERROR("Model ClearThenRefresh returned error."); }
437 
438  std::cout << std::endl
439  << "Updated parameter \"" << *name << "\" to value " << value
440  << "." << std::endl;
441 
442  kim_cluster_model->GetInfluenceDistance(
443  &influence_distance_cluster_model);
444  kim_cluster_model->GetNeighborListPointers(
445  &number_of_neighbor_lists,
446  &cutoff_cluster_model,
447  &modelWillNotRequestNeighborsOfNoncontributingParticles);
448 
449  compute_loop(MinSpacing,
450  MaxSpacing,
451  SpacingIncr,
452  numberOfParticles_cluster,
453  &(coords_cluster[0][0]),
454  *cutoff_cluster_model,
455  &nl_cluster_model,
456  kim_cluster_model,
457  computeArguments,
458  forces_cluster,
459  &energy_cluster_model);
460  }
461 
462  int present;
463  kim_cluster_model->IsRoutinePresent(
465  if (present == true)
466  {
467  error = kim_cluster_model->WriteParameterizedModel(
468  ".", "This_IsTheNewModelName");
469  if (error) { MY_ERROR("WriteParameterizedModel returned an error."); }
470  }
471  }
472 
473  /* call compute arguments destroy */
474  error = kim_cluster_model->ComputeArgumentsDestroy(&computeArguments);
475  if (error) { MY_ERROR("Unable to destroy compute arguments"); }
476 
477  /* call model destroy */
478  KIM::Model::Destroy(&kim_cluster_model);
479 
480  /* free memory of neighbor lists */
481  delete[] nl_cluster_model.NNeighbors;
482  delete[] nl_cluster_model.neighborList;
483 
484  /* everything is great */
485  std::cout.copyfmt(oldState);
486  return 0;
487 }
488 
489 void compute_loop(double const MinSpacing,
490  double const MaxSpacing,
491  double const SpacingIncr,
492  int const numberOfParticles_cluster,
493  double * const coords_cluster,
494  double const cutoff,
495  NeighList * nl,
496  KIM::Model const * const kim_cluster_model,
497  KIM::ComputeArguments const * const computeArguments,
498  double * const forces_cluster,
499  double * const energy_cluster_model)
500 {
501  double const cutpad = 0.75; /* Angstroms */
502 
503  std::cout << std::setw(20) << "Energy" << std::setw(20) << "Force Norm"
504  << std::setw(20) << "Lattice Spacing" << std::endl;
505  for (double CurrentSpacing = MinSpacing; CurrentSpacing < MaxSpacing;
506  CurrentSpacing += SpacingIncr)
507  {
508  /* update coordinates for cluster */
509  create_FCC_cluster(CurrentSpacing, NCELLSPERSIDE, coords_cluster);
510  /* compute neighbor lists */
512  0, NCLUSTERPARTS, coords_cluster, (cutoff + cutpad), nl);
513 
514  /* call compute functions */
515  int error = kim_cluster_model->Compute(computeArguments);
516  if (error) MY_ERROR("compute");
517 
518  /* compute force norm */
519  double force_norm = 0.0;
520  for (int i = 0; i < DIM * numberOfParticles_cluster; ++i)
521  {
522  force_norm += forces_cluster[i] * forces_cluster[i];
523  }
524  force_norm = sqrt(force_norm);
525 
526  /* print the results */
527  std::cout << std::setw(20) << *energy_cluster_model << std::setw(20)
528  << force_norm << std::setw(20) << CurrentSpacing << std::endl;
529  }
530 }
531 
532 void create_FCC_cluster(double FCCspacing, int nCellsPerSide, double * coords)
533 {
534  /* local variables */
535  double FCCshifts[4][DIM];
536  double latVec[DIM];
537  int a;
538  int i;
539  int j;
540  int k;
541  int m;
542  int n;
543 
544  /* create a cubic FCC cluster of parts */
545  FCCshifts[0][0] = 0.0;
546  FCCshifts[0][1] = 0.0;
547  FCCshifts[0][2] = 0.0;
548  FCCshifts[1][0] = 0.5 * FCCspacing;
549  FCCshifts[1][1] = 0.5 * FCCspacing;
550  FCCshifts[1][2] = 0.0;
551  FCCshifts[2][0] = 0.5 * FCCspacing;
552  FCCshifts[2][1] = 0.0;
553  FCCshifts[2][2] = 0.5 * FCCspacing;
554  FCCshifts[3][0] = 0.0;
555  FCCshifts[3][1] = 0.5 * FCCspacing;
556  FCCshifts[3][2] = 0.5 * FCCspacing;
557 
558  a = 0;
559  for (i = 0; i < nCellsPerSide; ++i)
560  {
561  latVec[0] = ((double) i) * FCCspacing;
562  for (j = 0; j < nCellsPerSide; ++j)
563  {
564  latVec[1] = ((double) j) * FCCspacing;
565  for (k = 0; k < nCellsPerSide; ++k)
566  {
567  latVec[2] = ((double) k) * FCCspacing;
568  for (m = 0; m < 4; ++m)
569  {
570  for (n = 0; n < DIM; ++n)
571  {
572  coords[a * DIM + n] = latVec[n] + FCCshifts[m][n];
573  }
574  a++;
575  }
576  }
577  /* add in the remaining three faces */
578  /* pos-x face */
579  latVec[0] = NCELLSPERSIDE * FCCspacing;
580  latVec[1] = ((double) i) * 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  {
586  coords[a * DIM + n] = latVec[n] + FCCshifts[3][n];
587  }
588  a++;
589  /* pos-y face */
590  latVec[0] = ((double) i) * FCCspacing;
591  latVec[1] = NCELLSPERSIDE * FCCspacing;
592  latVec[2] = ((double) j) * FCCspacing;
593  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
594  a++;
595  for (n = 0; n < DIM; ++n)
596  {
597  coords[a * DIM + n] = latVec[n] + FCCshifts[2][n];
598  }
599  a++;
600  /* pos-z face */
601  latVec[0] = ((double) i) * FCCspacing;
602  latVec[1] = ((double) j) * FCCspacing;
603  latVec[2] = NCELLSPERSIDE * FCCspacing;
604  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
605  a++;
606  for (n = 0; n < DIM; ++n)
607  {
608  coords[a * DIM + n] = latVec[n] + FCCshifts[1][n];
609  }
610  a++;
611  }
612  /* add in the remaining three edges */
613  latVec[0] = ((double) i) * FCCspacing;
614  latVec[1] = NCELLSPERSIDE * FCCspacing;
615  latVec[2] = NCELLSPERSIDE * FCCspacing;
616  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
617  a++;
618  latVec[0] = NCELLSPERSIDE * FCCspacing;
619  latVec[1] = ((double) i) * 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] = NCELLSPERSIDE * FCCspacing;
625  latVec[2] = ((double) i) * FCCspacing;
626  for (n = 0; n < DIM; ++n) { coords[a * DIM + n] = latVec[n]; }
627  a++;
628  }
629  /* add in the remaining corner */
630  for (n = 0; n < DIM; ++n)
631  {
632  coords[a * DIM + n] = NCELLSPERSIDE * FCCspacing;
633  }
634  a++;
635 
636  return;
637 }
638 
639 
641  int numberOfParticles,
642  double * coords,
643  double cutoff,
644  NeighList * nl)
645 {
646  /* local variables */
647  int i;
648  int j;
649  int k;
650  int a;
651 
652  double dx[DIM];
653  double r2;
654  double cutoff2;
655 
656  nl->cutoff = cutoff;
657 
658  cutoff2 = cutoff * cutoff;
659 
660  for (i = 0; i < numberOfParticles; ++i)
661  {
662  a = 0;
663  for (j = 0; j < numberOfParticles; ++j)
664  {
665  r2 = 0.0;
666  for (k = 0; k < DIM; ++k)
667  {
668  dx[k] = coords[j * DIM + k] - coords[i * DIM + k];
669  r2 += dx[k] * dx[k];
670  }
671 
672  if (r2 < cutoff2)
673  {
674  if ((half && i < j) || (!half && i != j))
675  {
676  /* part j is a neighbor of part i */
677  (*nl).neighborList[i * NCLUSTERPARTS + a] = j;
678  a++;
679  }
680  }
681  }
682  /* part i has `a' neighbors */
683  (*nl).NNeighbors[i] = a;
684  }
685 
686  return;
687 }
688 
689 int get_cluster_neigh(void * const dataObject,
690  int const numberOfNeighborLists,
691  double const * const cutoffs,
692  int const neighborListIndex,
693  int const particleNumber,
694  int * const numberOfNeighbors,
695  int const ** const neighborsOfParticle)
696 {
697  /* local variables */
698  int error = true;
699  NeighList * nl = (NeighList *) dataObject;
701 
702  if ((numberOfNeighborLists != 1) || (cutoffs[0] > nl->cutoff)) return error;
703 
704  if (neighborListIndex != 0) return error;
705 
706  /* initialize numNeigh */
707  *numberOfNeighbors = 0;
708 
709  if ((particleNumber >= numberOfParticles)
710  || (particleNumber < 0)) /* invalid id */
711  {
712  MY_WARNING("Invalid part ID in get_cluster_neigh");
713  return true;
714  }
715 
716  /* set the returned number of neighbors for the returned part */
717  *numberOfNeighbors = (*nl).NNeighbors[particleNumber];
718 
719  /* set the location for the returned neighbor list */
720  *neighborsOfParticle
721  = &((*nl).neighborList[(particleNumber) *numberOfParticles]);
722 
723  return false;
724 }
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:58
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.