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