kim-api 2.4.1+AppleClang.AppleClang.GNU
An Application Programming Interface (API) for the Knowledgebase of Interatomic Models (KIM).
 
Loading...
Searching...
No Matches
LennardJones_Ar.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//
9// SPDX-License-Identifier: LGPL-2.1-or-later
10//
11// This library is free software; you can redistribute it and/or
12// modify it under the terms of the GNU Lesser General Public
13// License as published by the Free Software Foundation; either
14// version 2.1 of the License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public License
22// along with this library; if not, write to the Free Software Foundation,
23// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24//
25
26
27#include "KIM_LogMacros.hpp"
28#include "KIM_ModelHeaders.hpp"
29#include <cstddef>
30#include <math.h>
31
32#define DIMENSION 3
33
34
35namespace
36{
38{
39 public:
40 //****************************************************************************
41 LennardJones_Ar(KIM::ModelCreate * const modelCreate,
42 KIM::LengthUnit const requestedLengthUnit,
43 KIM::EnergyUnit const requestedEnergyUnit,
44 KIM::ChargeUnit const requestedChargeUnit,
45 KIM::TemperatureUnit const requestedTemperatureUnit,
46 KIM::TimeUnit const requestedTimeUnit,
47 int * const error) :
48 epsilon_(0.0104),
49 sigma_(3.4000),
50 influenceDistance_(8.1500),
51 cutoff_(influenceDistance_),
52 cutoffSq_(cutoff_ * cutoff_),
53 modelWillNotRequestNeighborsOfNoncontributingParticles_(1)
54 {
55 *error = ConvertUnits(modelCreate,
56 requestedLengthUnit,
57 requestedEnergyUnit,
58 requestedChargeUnit,
59 requestedTemperatureUnit,
60 requestedTimeUnit);
61 if (*error) return;
62
64
65 modelCreate->SetInfluenceDistancePointer(&influenceDistance_);
66 modelCreate->SetNeighborListPointers(
67 1, &cutoff_, &modelWillNotRequestNeighborsOfNoncontributingParticles_);
68
70
71 // use function pointer declarations to verify prototypes
78
79 *error = modelCreate->SetRoutinePointer(
82 true,
83 reinterpret_cast<KIM::Function *>(CACreate))
84 || modelCreate->SetRoutinePointer(
87 true,
88 reinterpret_cast<KIM::Function *>(compute))
89 || modelCreate->SetRoutinePointer(
92 true,
93 reinterpret_cast<KIM::Function *>(CADestroy))
94 || modelCreate->SetRoutinePointer(
97 true,
98 reinterpret_cast<KIM::Function *>(destroy));
99 if (*error) return;
100
101 // everything is good
102 *error = false;
103 return;
104 };
105
106 //****************************************************************************
108
109 //****************************************************************************
110 // no need to make these "extern" since KIM will only access them
111 // via function pointers. "static" is required so that there is not
112 // an implicit this pointer added to the prototype by the C++ compiler
113 static int Destroy(KIM::ModelDestroy * const modelDestroy)
114 {
115 LennardJones_Ar * model;
116 modelDestroy->GetModelBufferPointer(reinterpret_cast<void **>(&model));
117
118 if (model != NULL)
119 {
120 // delete object itself
121 delete model;
122 }
123
124 // everything is good
125 return false;
126 }
127
128 //****************************************************************************
129#undef KIM_LOGGER_OBJECT_NAME
130#define KIM_LOGGER_OBJECT_NAME modelCompute
131 //
132 static int
133 Compute(KIM::ModelCompute const * const modelCompute,
134 KIM::ModelComputeArguments const * const modelComputeArguments)
135 {
136 int const * numberOfParticlesPointer;
137 int const * particleSpeciesCodes;
138 int const * particleContributing;
139 double const * coordinates;
140 double * partialEnergy;
141 double * partialForces;
142
143 LennardJones_Ar * lj;
144 modelCompute->GetModelBufferPointer(reinterpret_cast<void **>(&lj));
145 double const epsilon = lj->epsilon_;
146 double const sigma = lj->sigma_;
147 double const cutoffSq = lj->cutoffSq_;
148
149 int error = modelComputeArguments->GetArgumentPointer(
151 &numberOfParticlesPointer)
152 || modelComputeArguments->GetArgumentPointer(
154 &particleSpeciesCodes)
155 || modelComputeArguments->GetArgumentPointer(
157 &particleContributing)
158 || modelComputeArguments->GetArgumentPointer(
160 (double const **) &coordinates)
161 || modelComputeArguments->GetArgumentPointer(
163 || modelComputeArguments->GetArgumentPointer(
165 (double const **) &partialForces);
166 if (error)
167 {
168 LOG_ERROR("Unable to get argument pointers");
169 return error;
170 }
171
172 int const numberOfParticles = *numberOfParticlesPointer;
173
174 // initialize energy and forces
175 *partialEnergy = 0.0;
176 int const extent = numberOfParticles * DIMENSION;
177 for (int i = 0; i < extent; ++i) { partialForces[i] = 0.0; }
178
179 int jContributing;
180 int i, j, jj, numberOfNeighbors;
181 int const * neighbors;
182 double phi;
183 double xcoord, ycoord, zcoord;
184 double xrij, yrij, zrij;
185 double rij2;
186 double r2inv, r6inv, dphiByR, dEidrByR;
187 double xdf, ydf, zdf;
188 double const fortyEight = 48.0 * epsilon * pow(sigma, 12.0);
189 double const twentyFour = 24.0 * epsilon * pow(sigma, 6.0);
190 double const four12 = 4.0 * epsilon * pow(sigma, 12.0);
191 double const four6 = 4.0 * epsilon * pow(sigma, 6.0);
192 for (i = 0; i < numberOfParticles; ++i)
193 {
194 if (particleContributing[i])
195 {
196 xcoord = coordinates[i * DIMENSION + 0];
197 ycoord = coordinates[i * DIMENSION + 1];
198 zcoord = coordinates[i * DIMENSION + 2];
199
200 modelComputeArguments->GetNeighborList(
201 0, i, &numberOfNeighbors, &neighbors);
202
203 for (jj = 0; jj < numberOfNeighbors; ++jj)
204 {
205 j = neighbors[jj];
206 jContributing = particleContributing[j];
207
208 if (!(jContributing && (j < i)))
209 {
210 xrij = coordinates[j * DIMENSION + 0] - xcoord;
211 yrij = coordinates[j * DIMENSION + 1] - ycoord;
212 zrij = coordinates[j * DIMENSION + 2] - zcoord;
213
214 rij2 = xrij * xrij + yrij * yrij + zrij * zrij;
215
216 if (rij2 < cutoffSq)
217 {
218 r2inv = 1.0 / rij2;
219 r6inv = r2inv * r2inv * r2inv;
220 phi = 0.5 * r6inv * (four12 * r6inv - four6);
221 dphiByR = r6inv * (twentyFour - fortyEight * r6inv) * r2inv;
222
223 *partialEnergy += phi;
224 if (jContributing)
225 {
226 *partialEnergy += phi;
227 dEidrByR = dphiByR;
228 }
229 else { dEidrByR = 0.5 * dphiByR; }
230
231 xdf = dEidrByR * xrij;
232 ydf = dEidrByR * yrij;
233 zdf = dEidrByR * zrij;
234 partialForces[i * DIMENSION + 0] += xdf;
235 partialForces[i * DIMENSION + 1] += ydf;
236 partialForces[i * DIMENSION + 2] += zdf;
237 partialForces[j * DIMENSION + 0] -= xdf;
238 partialForces[j * DIMENSION + 1] -= ydf;
239 partialForces[j * DIMENSION + 2] -= zdf;
240 } // if (rij2 < cutoffSq_)
241 } // if (i < j)
242 } // for jj
243 } // if (particleContributing[i])
244 } // for i
245
246 // everything is good
247 return false;
248 };
249
250 //****************************************************************************
252 KIM::ModelCompute const * const /* modelCompute */,
253 KIM::ModelComputeArgumentsCreate * const modelComputeArgumentsCreate)
254 {
255 // register arguments
256 int error = modelComputeArgumentsCreate->SetArgumentSupportStatus(
259 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
262
263 // register callbacks
264 //
265 // none
266
267 return error;
268 }
269
270 //****************************************************************************
271 static int
272 ComputeArgumentsDestroy(KIM::ModelCompute const * const /* modelCompute */,
274 /* modelComputeArgumentsDestroy */)
275 {
276 // nothing further to do
277
278 return false;
279 }
280
281 private:
282 //****************************************************************************
283 // Member variables
284 double epsilon_;
285 double sigma_;
286 double influenceDistance_;
287 double cutoff_;
288 double cutoffSq_;
289 int const modelWillNotRequestNeighborsOfNoncontributingParticles_;
290
291 //****************************************************************************
292#undef KIM_LOGGER_OBJECT_NAME
293#define KIM_LOGGER_OBJECT_NAME modelCreate
294 //
295 int ConvertUnits(KIM::ModelCreate * const modelCreate,
296 KIM::LengthUnit const requestedLengthUnit,
297 KIM::EnergyUnit const requestedEnergyUnit,
298 KIM::ChargeUnit const requestedChargeUnit,
299 KIM::TemperatureUnit const requestedTemperatureUnit,
300 KIM::TimeUnit const requestedTimeUnit)
301 {
302 int ier;
303
304 // define default base units
310
311 // changing units of cutoffs and sigmas
312 double convertLength = 1.0;
313 ier = KIM::ModelCreate::ConvertUnit(fromLength,
314 fromEnergy,
315 fromCharge,
316 fromTemperature,
317 fromTime,
318 requestedLengthUnit,
319 requestedEnergyUnit,
320 requestedChargeUnit,
321 requestedTemperatureUnit,
322 requestedTimeUnit,
323 1.0,
324 0.0,
325 0.0,
326 0.0,
327 0.0,
328 &convertLength);
329 if (ier)
330 {
331 LOG_ERROR("Unable to convert length unit");
332 return ier;
333 }
334 influenceDistance_ *= convertLength; // convert to active units
335 cutoff_ = influenceDistance_;
336 cutoffSq_ = cutoff_ * cutoff_;
337 sigma_ *= convertLength; // convert to active units
338
339 // changing units of epsilons
340 double convertEnergy = 1.0;
341 ier = KIM::ModelCreate::ConvertUnit(fromLength,
342 fromEnergy,
343 fromCharge,
344 fromTemperature,
345 fromTime,
346 requestedLengthUnit,
347 requestedEnergyUnit,
348 requestedChargeUnit,
349 requestedTemperatureUnit,
350 requestedTimeUnit,
351 0.0,
352 1.0,
353 0.0,
354 0.0,
355 0.0,
356 &convertEnergy);
357 if (ier)
358 {
359 LOG_ERROR("Unable to convert energy unit");
360 return ier;
361 }
362 epsilon_ *= convertEnergy; // convert to active units
363
364 // register units
365 ier = modelCreate->SetUnits(requestedLengthUnit,
366 requestedEnergyUnit,
370 if (ier)
371 {
372 LOG_ERROR("Unable to set units to requested values");
373 return ier;
374 }
375
376 // everything is good
377 ier = false;
378 return ier;
379 }
380};
381
382} // namespace
383
384extern "C" {
385//******************************************************************************
386int model_create(KIM::ModelCreate * const modelCreate,
387 KIM::LengthUnit const requestedLengthUnit,
388 KIM::EnergyUnit const requestedEnergyUnit,
389 KIM::ChargeUnit const requestedChargeUnit,
390 KIM::TemperatureUnit const requestedTemperatureUnit,
391 KIM::TimeUnit const requestedTimeUnit)
392{
393 int error;
394
395 LennardJones_Ar * const model = new LennardJones_Ar(modelCreate,
396 requestedLengthUnit,
397 requestedEnergyUnit,
398 requestedChargeUnit,
399 requestedTemperatureUnit,
400 requestedTimeUnit,
401 &error);
402 if (error)
403 {
404 // constructor already reported the error
405 delete model;
406 return error;
407 }
408
409 // register pointer to LennardJones_Ar object in moedelCreate object
410 modelCreate->SetModelBufferPointer(reinterpret_cast<void *>(model));
411
412 // everything is good
413 return false;
414}
415} // extern "C"
#define LOG_ERROR(message)
Convenience macro for ERROR Log entries with compile-time optimization.
int model_create(KIM::ModelCreate *const modelCreate, KIM::LengthUnit const requestedLengthUnit, KIM::EnergyUnit const requestedEnergyUnit, KIM::ChargeUnit const requestedChargeUnit, KIM::TemperatureUnit const requestedTemperatureUnit, KIM::TimeUnit const requestedTimeUnit)
An Extensible Enumeration for the ChargeUnit's supported by the KIM API.
An Extensible Enumeration for the EnergyUnit's supported by the KIM API.
An Extensible Enumeration for the LengthUnit's supported by the KIM API.
Provides the interface to a KIM API ComputeArguments object for use by models within their MODEL_ROUT...
int SetArgumentSupportStatus(ComputeArgumentName const computeArgumentName, SupportStatus const supportStatus)
Set the SupportStatus of a ComputeArgumentName.
Provides the interface to a KIM API ComputeArguments object for use by models within their MODEL_ROUT...
Provides the interface to a KIM API ComputeArguments object for use by models within their MODEL_ROUT...
int GetNeighborList(int const neighborListIndex, int const particleNumber, int *const numberOfNeighbors, int const **const neighborsOfParticle) const
Get the neighbor list for a particle of interest corresponding to a particular neighbor list cutoff d...
int GetArgumentPointer(ComputeArgumentName const computeArgumentName, int const **const ptr) const
Get the data pointer for a ComputeArgumentName.
Provides the interface to a KIM API Model object for use by models within their MODEL_ROUTINE_NAME::C...
void GetModelBufferPointer(void **const ptr) const
Get the Model's buffer pointer within the Model object.
Provides the interface to a KIM API Model object for use by models within their MODEL_ROUTINE_NAME::C...
void SetInfluenceDistancePointer(double const *const influenceDistance)
Set the Model's influence distance data pointer.
int SetRoutinePointer(ModelRoutineName const modelRoutineName, LanguageName const languageName, int const required, Function *const fptr)
Set the function pointer for the ModelRoutineName of interest.
int SetSpeciesCode(SpeciesName const speciesName, int const code)
Set integer code for supported SpeciesName.
int SetModelNumbering(Numbering const numbering)
Set the Model's particle Numbering.
void SetNeighborListPointers(int const numberOfNeighborLists, double const *const cutoffs, int const *const modelWillNotRequestNeighborsOfNoncontributingParticles)
Set the Model's neighbor list data pointers.
void SetModelBufferPointer(void *const ptr)
Set the Model's buffer pointer within the Model object.
static int ConvertUnit(LengthUnit const fromLengthUnit, EnergyUnit const fromEnergyUnit, ChargeUnit const fromChargeUnit, TemperatureUnit const fromTemperatureUnit, TimeUnit const fromTimeUnit, LengthUnit const toLengthUnit, EnergyUnit const toEnergyUnit, ChargeUnit const toChargeUnit, TemperatureUnit const toTemperatureUnit, TimeUnit const toTimeUnit, double const lengthExponent, double const energyExponent, double const chargeExponent, double const temperatureExponent, double const timeExponent, double *const conversionFactor)
Get the multiplicative factor to convert between a derived unit represented in two different sets of ...
int SetUnits(LengthUnit const lengthUnit, EnergyUnit const energyUnit, ChargeUnit const chargeUnit, TemperatureUnit const temperatureUnit, TimeUnit const timeUnit)
Set the Model's base unit values.
Provides the interface to a KIM API Model object for use by models within their MODEL_ROUTINE_NAME::D...
void GetModelBufferPointer(void **const ptr) const
Get the Model's buffer pointer within the Model object.
An Extensible Enumeration for the TemperatureUnit's supported by the KIM API.
An Extensible Enumeration for the TimeUnit's supported by the KIM API.
LennardJones_Ar(KIM::ModelCreate *const modelCreate, KIM::LengthUnit const requestedLengthUnit, KIM::EnergyUnit const requestedEnergyUnit, KIM::ChargeUnit const requestedChargeUnit, KIM::TemperatureUnit const requestedTemperatureUnit, KIM::TimeUnit const requestedTimeUnit, int *const error)
static int Compute(KIM::ModelCompute const *const modelCompute, KIM::ModelComputeArguments const *const modelComputeArguments)
static int Destroy(KIM::ModelDestroy *const modelDestroy)
static int ComputeArgumentsDestroy(KIM::ModelCompute const *const, KIM::ModelComputeArgumentsDestroy *const)
static int ComputeArgumentsCreate(KIM::ModelCompute const *const, KIM::ModelComputeArgumentsCreate *const modelComputeArgumentsCreate)
ChargeUnit const unused
Indicates that a ChargeUnit is not used.
ComputeArgumentName const coordinates
The standard coordinates argument.
ComputeArgumentName const numberOfParticles
The standard numberOfParticles argument.
ComputeArgumentName const particleSpeciesCodes
The standard particleSpeciesCodes argument.
ComputeArgumentName const partialEnergy
The standard partialEnergy argument.
ComputeArgumentName const partialForces
The standard partialForces argument.
ComputeArgumentName const particleContributing
The standard particleContributing argument.
EnergyUnit const eV
The standard electronvolt unit of energy.
LanguageName const cpp
The standard cpp language.
LengthUnit const A
The standard angstrom unit of length.
ModelRoutineName const Destroy
The standard Destroy routine.
ModelRoutineName const Compute
The standard Compute routine.
ModelRoutineName const ComputeArgumentsDestroy
The standard ComputeArgumentsDestroy routine.
ModelRoutineName const ComputeArgumentsCreate
The standard ComputeArgumentsCreate routine.
Numbering const zeroBased
The standard zeroBased numbering.
SpeciesName const Ar
The standard Argon species.
SupportStatus const required
The standard required status.
TemperatureUnit const unused
Indicates that a TemperatureUnit is not used.
TimeUnit const unused
Indicates that a TimeUnit is not used.
int ModelComputeFunction(ModelCompute const *const modelCompute, ModelComputeArguments const *const modelComputeArgumentsCreate)
Prototype for MODEL_ROUTINE_NAME::Compute routine.
int ModelComputeArgumentsCreateFunction(ModelCompute const *const modelCompute, ModelComputeArgumentsCreate *const modelComputeArgumentsCreate)
Prototype for MODEL_ROUTINE_NAME::ComputeArgumentsCreate routine.
void Function(void)
Generic function type.
int ModelDestroyFunction(ModelDestroy *const modelDestroy)
Prototype for MODEL_ROUTINE_NAME::Destroy routine.
int ModelComputeArgumentsDestroyFunction(ModelCompute const *const modelCompute, ModelComputeArgumentsDestroy *const modelComputeArgumentsDestroy)
Prototype for MODEL_ROUTINE_NAME::ComputeArgumentsDestroy routine.