// -*- C++ -*-
// KimAtoms.h: Interface to KIM pretending to be the atoms.
//
// Copyright (C) 2012-2013 Jakob Schiotz and the 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 .
// This is a reimplementation of the ASAP Atoms object. It does not
// inherit from the usual Atoms object, as Atoms.h include Python.h
// which is not available in OpenKIM.
#ifndef KIMATOMS_H
#define KIMATOMS_H
#include "KimAsapPython.h"
#include "Asap.h"
#include "Vec.h"
#include "IVec.h"
#include
#include
using std::set;
using std::vector;
namespace ASAPSPACE {
class NeighborLocator;
// Supported neighbor list types
typedef enum {asapkim_cluster, asapkim_opbc_h} asapkim_nbtype;
class KimAtoms // Will be renamed Atoms in a typedef !
{
protected:
/// Delete the interface object.
///
/// Protected: may only be called from AsapAtoms_DECREF() friend function.
virtual ~KimAtoms();
public:
/// Create the interface object.
KimAtoms(intptr_t* pkim = NULL);
/// Pass new KIM pointers to this object.
void ReInit(int nAtoms, int nGhost, double *pos, int *z);
// Reference counting
friend void AsapAtoms_INCREF(KimAtoms *atoms);
friend void AsapAtoms_DECREF(KimAtoms *atoms);
/// Begin and End do nothing
virtual void Begin(void *pyatoms) {};
virtual void End() {};
/// Atoms are always active
inline bool IsActive() const {return true;}
/// Get the number of atoms
inline int GetNumberOfAtoms() const {return nAtoms;}
inline int GetNumberOfGhostAtoms() const {return nGhosts;}
// Note: HasGhostAtoms may have to be improved when parallel simulations
// are supported, see ticket #56, which is fixed for "normal" Asap use,
// but not necessarily for OpenKIM use (will depend on how parallelization
// is finally handled).
inline bool HasGhostAtoms() const {return nGhosts != 0;}
/// Get the cartesian positions. Ghost positions, if any, are at the end.
inline const Vec *GetPositions() const {return &positions[0];}
void GetPositions(vector &pos, bool ghosts=false) const;
void GetScaledPositions(vector &scaledpos, bool ghosts=false);
/// Get a copy of some positions, converted to scaled space.
void GetScaledPositions(vector &scaledpos, const set &which);
/// Get the atomic numbers
const asap_z_int *GetAtomicNumbers() const {return &numbers[0];}
/// Print memory usage
virtual long PrintMemory() const {return 0;}
/// Get a set of all elements present in the simulations.
virtual void GetListOfElements(set &elements) const;
int GetPositionsCounter() const {return counter;}
int GetMomentaCounter() const {return counter;}
int GetNumbersCounter() const {return counter;}
int GetCellCounter() const {return counter;}
/// Get the cartesian momenta
const Vec *GetMomenta();
const double *GetMasses();
bool UpdateBeforeCalculation(bool flag, double range) {return flag;}
virtual void CommunicateData(double *address, int n = 1) {}
/// Return three integers specifying the CPU layout.
virtual IVec GetNumberOfCells() const {return IVec(1,1,1);}
/// Get the supercell
const Vec *GetCell() const {return cell;}
/// Get the supercell. No sanity check!
const Vec *GET_CELL() const {return cell;}
/// Get the volume of the supercell
double GetVolume() const;
/// Get the height of the supercell
const double *GetCellHeights();
/// Get the inverse supercell
const Vec *GetInverseCell();
const bool *GetBoundaryConditions() const {return pbc;}
void SetPBC(bool x, bool y, bool z) {pbc[0] = x; pbc[1] = y; pbc[2] = z;}
void SetDiagonalCell(double d[3]);
private:
void invert_cell();
public:
// Public data (naughty!)
int refcount; ///< Number of references to this object.
NeighborLocator *kim_interface_nblist;
private:
// Data
intptr_t* pkim; // KIM API object.
int nAtoms; // The number of atoms
int nGhosts;
int nAllAtoms;
vector positions; ///< A copy of the positions of the atoms.
vector numbers; ///< A copy of the atomic numbers.
int counter, count_inverse_cell;
Vec cell[3]; ///< The unit cell
Vec inverse[3]; ///< The inverse unit cell
double heights[3]; ///< Heights of the unit cell
bool pbc[3];
asapkim_nbtype nbtype;
};
/// Increase the reference count of an Atoms object
inline void AsapAtoms_INCREF(KimAtoms *atoms)
{
atoms->refcount++;
}
/// Decrease the reference count of Atoms, deallocate if it reaches zero.
inline void AsapAtoms_DECREF(KimAtoms *atoms)
{
atoms->refcount--;
if (atoms->refcount == 0)
delete atoms;
}
} // end namespace
// Fake the real Atoms object
#define Atoms KimAtoms
#endif // KIM_ATOMS_H