1 // -*- C++ -*-
2 // KimAtoms.h:  Interface to KIM pretending to be the atoms.
3 //
4 // Copyright (C) 2012-2013 Jakob Schiotz and the Department of Physics,
5 // Technical University of Denmark.  Email: schiotz@fysik.dtu.dk
6 //
7 // This file is part of Asap version 3.
8 // Asap is released under the GNU Lesser Public License (LGPL) version 3.
9 // However, the parts of Asap distributed within the OpenKIM project
10 // (including this file) are also released under the Common Development
11 // and Distribution License (CDDL) version 1.0.
12 //
13 // This program is free software: you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public License
15 // version 3 as published by the Free Software Foundation.  Permission
16 // to use other versions of the GNU Lesser General Public License may
17 // granted by Jakob Schiotz or the head of department of the
18 // Department of Physics, Technical University of Denmark, as
19 // described in section 14 of the GNU General Public License.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // and the GNU Lesser Public License along with this program.  If not,
28 // see <http://www.gnu.org/licenses/>.
29 
30 // This is a reimplementation of the ASAP Atoms object.  It does not
31 // inherit from the usual Atoms object, as Atoms.h include Python.h
32 // which is not available in OpenKIM.
33 
34 
35 #ifndef KIMATOMS_H
36 #define KIMATOMS_H
37 
38 #include "KimAsapPython.h"
39 #include "Asap.h"
40 #include "Vec.h"
41 #include "IVec.h"
42 #include <set>
43 #include <vector>
44 
45 using std::set;
46 using std::vector;
47 
48 namespace ASAPSPACE {
49 
50 class NeighborLocator;
51 
52 // Supported neighbor list types
53 typedef enum {asapkim_cluster, asapkim_opbc_h} asapkim_nbtype;
54 
55 class KimAtoms  // Will be renamed Atoms in a typedef !
56 {
57 protected:
58   /// Delete the interface object.
59   ///
60   /// Protected: may only be called from AsapAtoms_DECREF() friend function.
61   virtual ~KimAtoms();
62 
63 public:
64   /// Create the interface object.
65   KimAtoms();
66 
67   /// Pass new KIM pointers to this object.
68   void ReInit(KIM::ModelComputeArguments const * const modelComputeArguments,
69 	      int nAtoms,
70 	      double const *pos,
71 	      int const *z,
72 	      int const *contributes);
73 
GetModelComputeArgumentsObject()74   KIM::ModelComputeArguments const * const GetModelComputeArgumentsObject() {return modelComputeArguments;}
75 
GetParticleContributes()76   const int *GetParticleContributes() {return contributes;}
77 
78   // Reference counting
79   friend void AsapAtoms_INCREF(KimAtoms *atoms);
80   friend void AsapAtoms_DECREF(KimAtoms *atoms);
81 
82   /// Begin and End do nothing
83   virtual void Begin(void *pyatoms, bool expect_reopen=false) {};
End()84   virtual void End() {};
85 
86   /// Atoms are always active
IsActive()87   inline bool IsActive() const {return true;}
88 
89   /// Get the number of atoms
GetNumberOfAtoms()90   inline int GetNumberOfAtoms() const {return nAtoms;}
91 
GetNumberOfGhostAtoms()92   inline int GetNumberOfGhostAtoms() const {return 0;}  // All atoms in nAtoms !
93 
94   /// Get total number of atoms in parallel simulation.
95   ///
96   /// In a serial simulation, same as GetNumberOfAtoms, in a parallel simulation
97   /// it is the sum over these over all processors.
GetTotalNumberOfAtoms()98   virtual int GetTotalNumberOfAtoms() const {return GetNumberOfAtoms();}
99 
100   // In reality, this function tells if the number of atoms might vary
101   // (e.g. in parallel simulations).
HasGhostAtoms()102   inline bool HasGhostAtoms() const {return true;}
103 
104   /// Get the cartesian positions.  Ghost positions, if any, are at the end.
GetPositions()105   inline const Vec *GetPositions() const {return &positions[0];}
106 
107   void GetPositions(vector<Vec> &pos, bool ghosts=false) const;
108 
109   void GetScaledPositions(vector<Vec> &scaledpos, bool ghosts=false);
110 
111   /// Get a copy of some positions, converted to scaled space.
112   void GetScaledPositions(vector<Vec> &scaledpos, const set<int> &which);
113 
114   /// Get the atomic numbers
GetAtomicNumbers()115   const asap_z_int *GetAtomicNumbers() const {return &numbers[0];}
116 
117   /// Print memory usage
PrintMemory()118   virtual long PrintMemory() const {return 0;}
119 
120   /// Get a set of all elements present in the simulations.
121   virtual void GetListOfElements(set<int> &elements) const;
122 
GetPositionsCounter()123   int GetPositionsCounter() const {return counter;}
GetMomentaCounter()124   int GetMomentaCounter() const {return counter;}
GetNumbersCounter()125   int GetNumbersCounter() const {return counter;}
GetCellCounter()126   int GetCellCounter() const {return counter;}
127 
128   /// Get the cartesian momenta
129   const Vec *GetMomenta();
130 
131   const double *GetMasses();
132 
UpdateBeforeCalculation(bool flag,double range)133   bool UpdateBeforeCalculation(bool flag, double range) {return flag;}
134 
135   virtual void CommunicateData(double *address, int n = 1) {}
136 
137   /// Return three integers specifying the CPU layout.
GetNumberOfCells()138   virtual IVec GetNumberOfCells() const {return IVec(1,1,1);}
139 
140   /// Get the supercell
GetCell()141   const Vec *GetCell() const {return cell;}
142 
143   /// Get the supercell.   No sanity check!
GET_CELL()144   const Vec *GET_CELL() const {return cell;}
145 
146   /// Get the volume of the supercell
147   double GetVolume() const;
148 
149   /// Get the height of the supercell
150   const double *GetCellHeights();
151 
152   /// Get the inverse supercell
153   const Vec *GetInverseCell();
154 
GetBoundaryConditions()155   const bool *GetBoundaryConditions() const {return pbc;}
156 
SetPBC(bool x,bool y,bool z)157   void SetPBC(bool x, bool y, bool z) {pbc[0] = x; pbc[1] = y; pbc[2] = z;}
158 
159   void SetDiagonalCell(double d[3]);
160 
161 private:
162   void invert_cell();
163 
164 public:
165   // Public data (naughty!)
166   int refcount;           ///< Number of references to this object.
167   NeighborLocator *kim_interface_nblist;
168 
169 private:
170   // Data
171   const KIM::ModelComputeArguments *modelComputeArguments;
172   int nAtoms;  // The number of atoms
173   vector<Vec> positions;  ///< A copy of the positions of the atoms.
174   vector<asap_z_int> numbers;    ///< A copy of the atomic numbers.
175   const int *contributes;  ///< Does the atom contribute? (Not a copy, no casting).
176   int counter, count_inverse_cell;
177   Vec cell[3];            ///< The unit cell
178   Vec inverse[3];         ///< The inverse unit cell
179   double heights[3];      ///< Heights of the unit cell
180   bool pbc[3];
181   asapkim_nbtype nbtype;
182 };
183 
184 
185 /// Increase the reference count of an Atoms object
AsapAtoms_INCREF(KimAtoms * atoms)186 inline void AsapAtoms_INCREF(KimAtoms *atoms)
187 {
188   atoms->refcount++;
189 }
190 
191 /// Decrease the reference count of Atoms, deallocate if it reaches zero.
AsapAtoms_DECREF(KimAtoms * atoms)192 inline void AsapAtoms_DECREF(KimAtoms *atoms)
193 {
194   atoms->refcount--;
195   if (atoms->refcount == 0)
196     delete atoms;
197 }
198 
199 } // end namespace
200 
201 // Fake the real Atoms object
202 #define Atoms KimAtoms
203 #define NormalAtoms KimAtoms
204 
205 #endif // KIM_ATOMS_H
206