kim-api 2.3.0+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
73 = LennardJones_Ar::ComputeArgumentsCreate;
74 KIM::ModelComputeFunction * compute = LennardJones_Ar::Compute;
76 = LennardJones_Ar::ComputeArgumentsDestroy;
77 KIM::ModelDestroyFunction * destroy = LennardJones_Ar::Destroy;
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
230 {
231 dEidrByR = 0.5 * dphiByR;
232 }
233
234 xdf = dEidrByR * xrij;
235 ydf = dEidrByR * yrij;
236 zdf = dEidrByR * zrij;
237 partialForces[i * DIMENSION + 0] += xdf;
238 partialForces[i * DIMENSION + 1] += ydf;
239 partialForces[i * DIMENSION + 2] += zdf;
240 partialForces[j * DIMENSION + 0] -= xdf;
241 partialForces[j * DIMENSION + 1] -= ydf;
242 partialForces[j * DIMENSION + 2] -= zdf;
243 } // if (rij2 < cutoffSq_)
244 } // if (i < j)
245 } // for jj
246 } // if (particleContributing[i])
247 } // for i
248
249 // everything is good
250 return false;
251 };
252
253 //****************************************************************************
255 KIM::ModelCompute const * const /* modelCompute */,
256 KIM::ModelComputeArgumentsCreate * const modelComputeArgumentsCreate)
257 {
258 // register arguments
259 int error = modelComputeArgumentsCreate->SetArgumentSupportStatus(
262 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
265
266 // register callbacks
267 //
268 // none
269
270 return error;
271 }
272
273 //****************************************************************************
274 static int
275 ComputeArgumentsDestroy(KIM::ModelCompute const * const /* modelCompute */,
277 /* modelComputeArgumentsDestroy */)
278 {
279 // nothing further to do
280
281 return false;
282 }
283
284 private:
285 //****************************************************************************
286 // Member variables
287 double epsilon_;
288 double sigma_;
289 double influenceDistance_;
290 double cutoff_;
291 double cutoffSq_;
292 int const modelWillNotRequestNeighborsOfNoncontributingParticles_;
293
294 //****************************************************************************
295#undef KIM_LOGGER_OBJECT_NAME
296#define KIM_LOGGER_OBJECT_NAME modelCreate
297 //
298 int ConvertUnits(KIM::ModelCreate * const modelCreate,
299 KIM::LengthUnit const requestedLengthUnit,
300 KIM::EnergyUnit const requestedEnergyUnit,
301 KIM::ChargeUnit const requestedChargeUnit,
302 KIM::TemperatureUnit const requestedTemperatureUnit,
303 KIM::TimeUnit const requestedTimeUnit)
304 {
305 int ier;
306
307 // define default base units
313
314 // changing units of cutoffs and sigmas
315 double convertLength = 1.0;
316 ier = KIM::ModelCreate::ConvertUnit(fromLength,
317 fromEnergy,
318 fromCharge,
319 fromTemperature,
320 fromTime,
321 requestedLengthUnit,
322 requestedEnergyUnit,
323 requestedChargeUnit,
324 requestedTemperatureUnit,
325 requestedTimeUnit,
326 1.0,
327 0.0,
328 0.0,
329 0.0,
330 0.0,
331 &convertLength);
332 if (ier)
333 {
334 LOG_ERROR("Unable to convert length unit");
335 return ier;
336 }
337 influenceDistance_ *= convertLength; // convert to active units
338 cutoff_ = influenceDistance_;
339 cutoffSq_ = cutoff_ * cutoff_;
340 sigma_ *= convertLength; // convert to active units
341
342 // changing units of epsilons
343 double convertEnergy = 1.0;
344 ier = KIM::ModelCreate::ConvertUnit(fromLength,
345 fromEnergy,
346 fromCharge,
347 fromTemperature,
348 fromTime,
349 requestedLengthUnit,
350 requestedEnergyUnit,
351 requestedChargeUnit,
352 requestedTemperatureUnit,
353 requestedTimeUnit,
354 0.0,
355 1.0,
356 0.0,
357 0.0,
358 0.0,
359 &convertEnergy);
360 if (ier)
361 {
362 LOG_ERROR("Unable to convert energy unit");
363 return ier;
364 }
365 epsilon_ *= convertEnergy; // convert to active units
366
367 // register units
368 ier = modelCreate->SetUnits(requestedLengthUnit,
369 requestedEnergyUnit,
373 if (ier)
374 {
375 LOG_ERROR("Unable to set units to requested values");
376 return ier;
377 }
378
379 // everything is good
380 ier = false;
381 return ier;
382 }
383};
384
385} // namespace
386
387extern "C" {
388//******************************************************************************
389int model_create(KIM::ModelCreate * const modelCreate,
390 KIM::LengthUnit const requestedLengthUnit,
391 KIM::EnergyUnit const requestedEnergyUnit,
392 KIM::ChargeUnit const requestedChargeUnit,
393 KIM::TemperatureUnit const requestedTemperatureUnit,
394 KIM::TimeUnit const requestedTimeUnit)
395{
396 int error;
397
398 LennardJones_Ar * const model = new LennardJones_Ar(modelCreate,
399 requestedLengthUnit,
400 requestedEnergyUnit,
401 requestedChargeUnit,
402 requestedTemperatureUnit,
403 requestedTimeUnit,
404 &error);
405 if (error)
406 {
407 // constructor already reported the error
408 delete model;
409 return error;
410 }
411
412 // register pointer to LennardJones_Ar object in moedelCreate object
413 modelCreate->SetModelBufferPointer(reinterpret_cast<void *>(model));
414
415 // everything is good
416 return false;
417}
418} // 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.
int ModelDestroyFunction(ModelDestroy *const modelDestroy)
Prototype for MODEL_ROUTINE_NAME::Destroy routine.
void() Function(void)
Generic function type.
int ModelComputeArgumentsDestroyFunction(ModelCompute const *const modelCompute, ModelComputeArgumentsDestroy *const modelComputeArgumentsDestroy)
Prototype for MODEL_ROUTINE_NAME::ComputeArgumentsDestroy routine.