1 // -*- C++ -*- 2 // Potential.h: Abstract base class for all potentials. 3 // 4 // Copyright (C) 2001-2012 Jakob Schiotz and Center for Individual 5 // Nanoparticle Functionality, Department of Physics, Technical 6 // 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 32 #ifndef POTENTIAL_H 33 #define POTENTIAL_H 34 35 #include "AsapPython.h" 36 #include <vector> 37 38 #include "Exception.h" 39 #include "AsapObject.h" 40 #include "SymTensor.h" 41 42 using std::vector; 43 44 namespace ASAPSPACE { 45 46 class Atoms; 47 class Vec; 48 class SuperCell; 49 class NeighborLocator; 50 51 class Potential; // Defined later in this file. 52 53 /// The Python object corresponding to a Potential object. 54 typedef struct { 55 PyObject_HEAD 56 Potential *cobj; // Access through this object, either same as orig_cobj or a wrapper. 57 Potential *orig_cobj; // The actual potential object 58 PyObject *weakrefs; 59 bool setatoms_called; // True if SetAtoms has been called. 60 } PyAsap_PotentialObject; 61 62 bool PyAsap_PotentialCheck(PyObject *obj); // Implemented in PotentialInterface.cpp 63 64 //typedef double symTensor[6]; 65 66 /// Abstract base class of all potentials. 67 68 /// A Potential calculates forces, energies and stresses for a list of 69 /// atoms. A given instance of a Potential is associated with a 70 /// specific Atoms object on a one-to-one bases, this is established 71 /// when Atoms.SetCalculator() is called. 72 /// 73 /// Four types of classes are derived from Potential. 74 /// - Concrete implementations of potentials, such as EMT 75 /// and MoPotential, LJPotential, BrennerPotential. 76 /// - Potentials wrapping concrete implementations, but providing 77 /// special functionalily, such as ParallelPotential (implementing 78 /// parallel simulations) or QCPotential (implementing the 79 /// QuasiContinuum method). 80 class Potential : public AsapObject 81 { 82 public: 83 Potential(PyObject *self, int verbose=0) { 84 atoms=NULL; 85 this->self = self; 86 this->verbose = verbose; 87 } 88 ~Potential()89 virtual ~Potential() {} 90 91 /// Set the atoms belonging to this potential. 92 93 /// This is called automatically by Atoms.SetCalculator() and should 94 /// not be called elsewhere. 95 /// 96 /// Any wrapping Potential (such as ParallelPotential) that needs to 97 /// chain to another Potential's SetAtoms method MUST instead call 98 /// Potential::SetAtoms_ThroughPython. 99 virtual void SetAtoms(PyObject *a, Atoms* accessobj = NULL) = 0; 100 101 virtual void SetAtoms_ThroughPython(PyObject *a, Atoms* accessobj = NULL); 102 103 /// Calculate the total energy of the system. 104 virtual double GetPotentialEnergy(PyObject *a) = 0; 105 106 /// Calculate the forces on all atoms and return the result. 107 virtual const vector<Vec> &GetForces(PyObject *a) = 0; 108 109 /// Calculate the "virials" of the atoms. 110 /// 111 /// The virial divided by the atomic volume is the stress of an atom. 112 virtual const vector<SymTensor> &GetVirials(PyObject *a) = 0; 113 114 /// Calculate the total "virial" of the system. 115 /// 116 /// The virial gives the stress of the sytem when divided by the system volume. 117 virtual SymTensor GetVirial(PyObject *a); 118 119 /// Calculate the energy of all atoms. 120 virtual const vector<double> &GetPotentialEnergies(PyObject *a) = 0; 121 122 // The following three functions are used to check if recalculations 123 // are needed. If a potential does not contain any logic to prevent 124 // recalculations, these functions should return True. 125 126 /// Is work required to calculate the energy? CalcReq_Energy(PyObject * pyatoms)127 virtual bool CalcReq_Energy(PyObject *pyatoms) {return true;} 128 129 /// Is work required to calculate the forces? CalcReq_Forces(PyObject * pyatoms)130 virtual bool CalcReq_Forces(PyObject *pyatoms) {return true;} 131 132 /// Is work required to calculate the stress? CalcReq_Virial(PyObject * pyatoms)133 virtual bool CalcReq_Virial(PyObject *pyatoms) {return CalcReq_Virials(pyatoms);} CalcReq_Virials(PyObject * pyatoms)134 virtual bool CalcReq_Virials(PyObject *pyatoms) {return true;} 135 136 // Check if Neighbor lists are up to date. 137 //virtual void CheckNeighborLists() = 0; 138 139 /// Return the neighbor list. 140 141 /// Return a BORROWED reference to the Python object containing 142 /// neighbor list for the 143 /// potential, if this type of potential supports it, and if it is 144 /// defined now. Otherwise, return NULL without setting a Python 145 /// error. GetNeighborList()146 virtual PyObject *GetNeighborList() const {return NULL;} 147 148 /// Return the cutoff radius used in the potential. 149 virtual double GetCutoffRadius() const = 0; 150 151 /// Return the lattice constant of the material, if well-defined. 152 153 /// If a lattice constant of the material can be defined, return it 154 /// in Angstrom, otherwise throw an exception. 155 virtual double GetLatticeConstant() const = 0; 156 157 /// Can this potential be used in parallel simulations? 158 159 /// 160 /// ParallelPotential checks this and protests if false. Note that 161 /// ParallelPotential itself returns false if this method is called, 162 /// as it cannot be passed to another instance of ParallelPotential. Parallelizable()163 virtual bool Parallelizable() const {return false;} 164 165 /// Print memory usage 166 virtual long PrintMemory() const = 0; 167 168 /// Clean up after an exception. Called by the interface code. 169 void RecoverAfterException(); 170 171 /// Return the atomic volumes that should be used to calculate the stresses 172 /// 173 /// If an empty volumes vector is returned, GetStress will divide the unit 174 /// cell evenly amongst the atoms. Can only be used after a call to GetVirials 175 /// with the same atoms; returns cached data, no atoms object is therefore passed GetAtomicVolumes(vector<double> & volumes)176 virtual void GetAtomicVolumes(vector<double> &volumes) {volumes.clear();} 177 178 protected: 179 Atoms *atoms; 180 PyObject *self; ///< This objects Python counterpart 181 int verbose; // Verbosity level. 182 }; 183 184 } // end namespace 185 186 #endif // POTENTIAL_H 187