// -*- C++ -*-
// Potential.h: Abstract base class for all potentials.
//
// Copyright (C) 2001-2012 Jakob Schiotz and Center for Individual
// Nanoparticle Functionality, Department of Physics, Technical
// University of Denmark. Email: schiotz@fysik.dtu.dk
//
// This file is part of Asap version 3.
// Asap is released under the GNU Lesser Public License (LGPL) version 3.
// However, the parts of Asap distributed within the OpenKIM project
// (including this file) are also released under the Common Development
// and Distribution License (CDDL) version 1.0.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// version 3 as published by the Free Software Foundation. Permission
// to use other versions of the GNU Lesser General Public License may
// granted by Jakob Schiotz or the head of department of the
// Department of Physics, Technical University of Denmark, as
// described in section 14 of the GNU General Public License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// and the GNU Lesser Public License along with this program. If not,
// see .
#ifndef POTENTIAL_H
#define POTENTIAL_H
#include "AsapPython.h"
#include
#include "Exception.h"
#include "AsapObject.h"
using std::vector;
namespace ASAPSPACE {
class Atoms;
class Vec;
class SymTensor;
class SuperCell;
class NeighborLocator;
class Potential; // Defined later in this file.
/// The Python object corresponding to a Potential object.
typedef struct {
PyObject_HEAD
Potential *cobj;
PyObject *weakrefs;
} PyAsap_PotentialObject;
bool PyAsap_PotentialCheck(PyObject *obj); // Implemented in PotentialInterface.c
//typedef double symTensor[6];
/// Abstract base class of all potentials.
/// A Potential calculates forces, energies and stresses for a list of
/// atoms. A given instance of a Potential is associated with a
/// specific Atoms object on a one-to-one bases, this is established
/// when Atoms.SetCalculator() is called.
///
/// Four types of classes are derived from Potential.
/// - Concrete implementations of potentials, such as EMT
/// and MoPotential, LJPotential, BrennerPotential.
/// - Potentials wrapping concrete implementations, but providing
/// special functionalily, such as ParallelPotential (implementing
/// parallel simulations) or QCPotential (implementing the
/// QuasiContinuum method).
class Potential : public AsapObject
{
public:
virtual ~Potential() {}
/// Set the atoms belonging to this potential.
/// This is called automatically by Atoms.SetCalculator() and should
/// not be called elsewhere.
virtual void SetAtoms(PyObject *a, Atoms* accessobj = NULL) = 0;
/// Calculate the total energy of the system.
virtual double GetPotentialEnergy(PyObject *a) = 0;
/// Calculate the forces on all atoms and return the result.
virtual const vector &GetForces(PyObject *a) = 0;
/// Calculate the stress on all atoms.
virtual const vector &GetStresses(PyObject *a, bool virialonly=false) = 0;
/// Calculate the total stress of the system.
/// Note that the output variable stress is not zeroed first. In
/// quasicontinuum simulations and other situations where there is a
/// contribution to the stress which is not from the atoms, the
/// stress parameter can initially be set to the appropriate
/// derivatives of the energy of that part of the calculation
/// (without the volume normalization, which will be performed by
/// the potential).
virtual void GetStress(PyObject *a, double stress[6], bool virialonly=false) = 0;
/// Calculate the energy of all atoms.
virtual const vector &GetPotentialEnergies(PyObject *a) = 0;
// The following three functions are used to check if recalculations
// are needed. If a potential does not contain any logic to prevent
// recalculations, these functions should return True.
/// Is work required to calculate the energy?
virtual bool CalcReq_Energy(PyObject *pyatoms) {return true;}
/// Is work required to calculate the forces?
virtual bool CalcReq_Forces(PyObject *pyatoms) {return true;}
/// Is work required to calculate the stress?
virtual bool CalcReq_Stress(PyObject *pyatoms) {return true;}
// Check if Neighbor lists are up to date.
//virtual void CheckNeighborLists() = 0;
/// Return the neighbor list.
/// Return a BORROWED reference to the Python object containing
/// neighbor list for the
/// potential, if this type of potential supports it, and if it is
/// defined now. Otherwise, return NULL without setting a Python
/// error.
virtual PyObject *GetNeighborList() const {return NULL;}
/// Return the cutoff radius used in the potential.
virtual double GetCutoffRadius() const = 0;
/// Return the lattice constant of the material, if well-defined.
/// If a lattice constant of the material can be defined, return it
/// in Angstrom, otherwise throw an exception.
virtual double GetLatticeConstant() const = 0;
/// Can this potential be used in parallel simulations?
///
/// ParallelPotential checks this and protests if false. Note that
/// ParallelPotential itself returns false if this method is called,
/// as it cannot be passed to another instance of ParallelPotential.
virtual bool Parallelizable() const {return false;}
/// Print memory usage
virtual long PrintMemory() const = 0;
/// Clean up after an exception. Called by the interface code.
void RecoverAfterException();
protected:
Atoms *atoms;
};
} // end namespace
#endif // POTENTIAL_H