1 // -*- C++ -*-
2 //
3 // asap_emt_driver.cpp: OpenKIM Model Driver interface for EMT.
4 //
5 // Copyright (C) 2012-2013 Jakob Schiotz and the Department of Physics,
6 // Technical University of Denmark. Email: schiotz@fysik.dtu.dk
7 //
8 // This file is part of Asap version 3.
9 // Asap is released under the GNU Lesser Public License (LGPL) version 3.
10 // However, the parts of Asap distributed within the OpenKIM project
11 // (including this file) are also released under the Common Development
12 // and Distribution License (CDDL) version 1.0.
13 //
14 // This program is free software: you can redistribute it and/or
15 // modify it under the terms of the GNU Lesser General Public License
16 // version 3 as published by the Free Software Foundation. Permission
17 // to use other versions of the GNU Lesser General Public License may
18 // granted by Jakob Schiotz or the head of department of the
19 // Department of Physics, Technical University of Denmark, as
20 // described in section 14 of the GNU General Public License.
21 //
22 // This program is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // and the GNU Lesser Public License along with this program. If not,
29 // see <http://www.gnu.org/licenses/>.
30
31 #include "KIM_ModelDriverHeaders.hpp"
32 #include "KIM_LogMacros.hpp"
33 #include "Asap.h"
34 #include "Debug.h"
35 #include "asap_kim_api.h"
36 #include "asap_emt_driver.h"
37 #include "KimParameterProvider.h"
38
39 #include <stdlib.h>
40
41 static int asap_emt_driver_initmodel(AsapKimPotential *model);
42
KimEMT(AsapKimPotential * owner,EMTParameterProvider * provider)43 KimEMT::KimEMT(AsapKimPotential *owner, EMTParameterProvider *provider) : EMT(NULL, NULL, 0)
44 {
45 CONSTRUCTOR;
46 this->owner = owner;
47 nblist = NULL;
48 nblist_obj = NULL;
49 provider_obj = NULL; // Bypass EMT's Python-based memory management.
50 this->provider = provider;
51 always_fullnblist = true;
52 modelWillNotRequestNeighborsOfNoncontributingParticles = 1;
53 }
54
~KimEMT()55 KimEMT::~KimEMT()
56 {
57 DESTRUCTOR;
58 assert(provider_obj == NULL);
59 delete provider;
60 if (nblist != NULL)
61 delete nblist; // Not deleted in the real potential.
62 }
63
CreateNeighborList()64 void KimEMT::CreateNeighborList()
65 {
66 PyAsap_NeighborLocatorObject *nbl = owner->CreateNeighborList(atoms, rNbCut, driftfactor);
67 nblist = nbl->cobj;
68 nblist_obj = (PyObject *) nbl;
69 nblist->UpdateNeighborList();
70 }
71
ComputeArgumentsCreate(KIM::ModelComputeArgumentsCreate * const modelComputeArgumentsCreate) const72 int KimEMT::ComputeArgumentsCreate(KIM::ModelComputeArgumentsCreate * const modelComputeArgumentsCreate) const
73 {
74 int error =
75 modelComputeArgumentsCreate->SetArgumentSupportStatus(
76 KIM::COMPUTE_ARGUMENT_NAME::partialEnergy,
77 KIM::SUPPORT_STATUS::optional)
78 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
79 KIM::COMPUTE_ARGUMENT_NAME::partialForces,
80 KIM::SUPPORT_STATUS::optional)
81 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
82 KIM::COMPUTE_ARGUMENT_NAME::partialParticleEnergy,
83 KIM::SUPPORT_STATUS::optional)
84 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
85 KIM::COMPUTE_ARGUMENT_NAME::partialVirial,
86 KIM::SUPPORT_STATUS::optional)
87 || modelComputeArgumentsCreate->SetArgumentSupportStatus(
88 KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial,
89 KIM::SUPPORT_STATUS::optional);
90
91 // No callbacks are set up for this potential.
92
93 #if 0
94 // Debugging info
95 std::cerr << "*** COMPUTE ARGUMENTS ***" << std::endl;
96 std::cerr << modelComputeArgumentsCreate->ToString() << std::endl;
97 #endif
98 return error;
99 }
100
101
102 // /* Reinit function */
103
104 // static int asap_emt_reinit(void *km)
105 // {
106 // intptr_t* pkim = *((intptr_t**) km);
107 // int ier;
108 // // Remove the old model
109 // AsapKimPotential *model = (AsapKimPotential *) KIM_API_get_model_buffer(pkim, &ier);
110 // if (KIM_STATUS_OK > ier)
111 // {
112 // KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_model_buffer", ier);
113 // return ier;
114 // }
115
116 // // Add the new model
117 // AsapKimPotential *newmodel = new AsapKimPotential(pkim, model->paramfile_names, model->nmstrlen,
118 // model->numparamfiles, true);
119 // delete model;
120 // return asap_emt_driver_initmodel(newmodel);
121 // }
122
123 /* Initialization function */
124 #define KIM_LOGGER_OBJECT_NAME modelDriverCreate
model_driver_create(KIM::ModelDriverCreate * const modelDriverCreate,KIM::LengthUnit const requestedLengthUnit,KIM::EnergyUnit const requestedEnergyUnit,KIM::ChargeUnit const requestedChargeUnit,KIM::TemperatureUnit const requestedTemperatureUnit,KIM::TimeUnit const requestedTimeUnit)125 extern "C" int model_driver_create(KIM::ModelDriverCreate * const modelDriverCreate,
126 KIM::LengthUnit const requestedLengthUnit,
127 KIM::EnergyUnit const requestedEnergyUnit,
128 KIM::ChargeUnit const requestedChargeUnit,
129 KIM::TemperatureUnit const requestedTemperatureUnit,
130 KIM::TimeUnit const requestedTimeUnit)
131 {
132
133 // Create the model
134 AsapKimPotential *model = NULL;
135 KimParameterProvider *provider = NULL;
136 try
137 {
138 model = new AsapKimPotential(modelDriverCreate, true);
139 provider = new KimParameterProvider(modelDriverCreate,
140 model->paramfile_names,
141 requestedLengthUnit,
142 requestedEnergyUnit,
143 requestedChargeUnit,
144 requestedTemperatureUnit,
145 requestedTimeUnit);
146 }
147 catch (AsapError &e)
148 {
149 std::cerr << e.GetMessage() << std::endl;
150 LOG_ERROR(e.GetMessage().c_str());
151 return true;
152 }
153
154 KimEMT *kimpotential = new KimEMT(model, provider);
155 model->SetPotential(kimpotential);
156
157
158 modelDriverCreate->SetModelBufferPointer(static_cast<void *>(model));
159
160 provider->CalcGammaEtc();
161 kimpotential->influenceDistance = provider->GetListCutoffDistance();
162 modelDriverCreate->SetInfluenceDistancePointer(&(kimpotential->influenceDistance));
163 modelDriverCreate->SetNeighborListPointers(
164 1,
165 &(kimpotential->influenceDistance),
166 &(kimpotential->modelWillNotRequestNeighborsOfNoncontributingParticles));
167
168 #if 0
169 std::cerr << "*** MODEL CREATION PRINTOUT ***" << std::endl;
170 std::cerr << modelDriverCreate->ToString()<< std::endl;
171 std::cerr << "*** MODEL CREATION PRINTOUT DONE ***" << std::endl;
172 #endif
173 return 0; // No error
174 }
175
176