forked from lijiext/lammps
668 lines
20 KiB
C++
668 lines
20 KiB
C++
// Header file for this class
|
|
#include "LammpsInterface.h"
|
|
|
|
// LAMMPS includes
|
|
#include "lammps.h"
|
|
#include "atom.h" // x, v, f
|
|
#include "domain.h" // for basing locations on regions
|
|
#include "region.h" // region bounding box and style
|
|
#include "force.h" // boltzman constant
|
|
#include "group.h" // atom masks
|
|
#include "memory.h" // grow atom information
|
|
#include "compute.h" // computes
|
|
#include "modify.h" //
|
|
#include "neighbor.h" // neighbors
|
|
#include "neigh_list.h" // neighbor list
|
|
#include "update.h" // timestepping information
|
|
#include "pair.h" // pair potentials
|
|
#include "lattice.h" // lattice parameters
|
|
#include "comm.h" //
|
|
|
|
// ATC includes
|
|
#include "ATC_Error.h"
|
|
#include "MatrixLibrary.h"
|
|
|
|
// Other include files
|
|
#include "mpi.h"
|
|
#include <cstring>
|
|
|
|
namespace ATC {
|
|
|
|
|
|
LammpsInterface * LammpsInterface::myInstance_ = NULL;
|
|
|
|
// -----------------------------------------------------------------
|
|
// instance()
|
|
// -----------------------------------------------------------------
|
|
LammpsInterface * LammpsInterface::instance()
|
|
{
|
|
if (myInstance_ == NULL) {
|
|
myInstance_ = new LammpsInterface();
|
|
}
|
|
return myInstance_;
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// constructor
|
|
// -----------------------------------------------------------------
|
|
LammpsInterface::LammpsInterface()
|
|
: lammps_(NULL),
|
|
atomPE_(NULL),
|
|
commRank_(0)
|
|
{
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// general interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
MPI_Comm LammpsInterface::world() { return lammps_->world; }
|
|
|
|
// -----------------------------------------------------------------
|
|
// atom interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
int LammpsInterface::nlocal() { return lammps_->atom->nlocal; }
|
|
|
|
int LammpsInterface::nghost() { return lammps_->atom->nghost; }
|
|
|
|
double LammpsInterface::natoms() { return lammps_->atom->natoms; }
|
|
|
|
int LammpsInterface::nmax() { return lammps_->atom->nmax; }
|
|
|
|
int LammpsInterface::ntypes() { return lammps_->atom->ntypes; }
|
|
|
|
double ** LammpsInterface::xatom() { return lammps_->atom->x; }
|
|
|
|
const double ** LammpsInterface::xatom() const { return (const double**)(lammps_->atom->x); }
|
|
|
|
double ** LammpsInterface::vatom() { return lammps_->atom->v; }
|
|
|
|
double ** LammpsInterface::fatom() { return lammps_->atom->f; }
|
|
|
|
int * LammpsInterface::atom_mask() { return lammps_->atom->mask; }
|
|
|
|
int * LammpsInterface::atom_type() { return lammps_->atom->type; }
|
|
|
|
int * LammpsInterface::atom_tag() { return lammps_->atom->tag; }
|
|
|
|
double * LammpsInterface::atom_mass() { return lammps_->atom->mass; }
|
|
|
|
double LammpsInterface::atom_mass(int iType) { return lammps_->atom->mass[iType]; }
|
|
|
|
double * LammpsInterface::atom_rmass() { return lammps_->atom->rmass; }
|
|
|
|
double * LammpsInterface::atom_charge() { return lammps_->atom->q; }
|
|
|
|
// -----------------------------------------------------------------
|
|
// domain interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
int LammpsInterface::dimension() { return lammps_->domain->dimension; }
|
|
|
|
int LammpsInterface::nregion() { return lammps_->domain->nregion; }
|
|
|
|
void LammpsInterface::get_box_bounds(double & boxxlo, double & boxxhi,
|
|
double & boxylo, double & boxyhi,
|
|
double & boxzlo, double &boxzhi)
|
|
{
|
|
if (lammps_->domain->triclinic == 0) {
|
|
boxxlo = lammps_->domain->boxlo[0];
|
|
boxxhi = lammps_->domain->boxhi[0];
|
|
boxylo = lammps_->domain->boxlo[1];
|
|
boxyhi = lammps_->domain->boxhi[1];
|
|
boxzlo = lammps_->domain->boxlo[2];
|
|
boxzhi = lammps_->domain->boxhi[2];
|
|
}
|
|
else {
|
|
boxxlo = lammps_->domain->boxlo_bound[0];
|
|
boxxhi = lammps_->domain->boxhi_bound[0];
|
|
boxylo = lammps_->domain->boxlo_bound[1];
|
|
boxyhi = lammps_->domain->boxhi_bound[1];
|
|
boxzlo = lammps_->domain->boxlo_bound[2];
|
|
boxzhi = lammps_->domain->boxhi_bound[2];
|
|
}
|
|
}
|
|
|
|
int LammpsInterface::xperiodic() { return lammps_->domain->xperiodic; }
|
|
|
|
int LammpsInterface::yperiodic() { return lammps_->domain->yperiodic; }
|
|
|
|
int LammpsInterface::zperiodic() { return lammps_->domain->zperiodic; }
|
|
|
|
int LammpsInterface::nperiodic()
|
|
{
|
|
int nprd = 0;
|
|
if ( lammps_->domain->xperiodic > 0 ) { nprd++ ; }
|
|
if ( lammps_->domain->yperiodic > 0 ) { nprd++ ; }
|
|
if ( lammps_->domain->zperiodic > 0 ) { nprd++ ; }
|
|
return nprd;
|
|
}
|
|
|
|
double LammpsInterface::domain_xprd() { return lammps_->domain->xprd; }
|
|
|
|
double LammpsInterface::domain_yprd() { return lammps_->domain->yprd; }
|
|
|
|
double LammpsInterface::domain_zprd() { return lammps_->domain->zprd; }
|
|
|
|
double LammpsInterface::domain_xy() { return lammps_->domain->xy; }
|
|
|
|
double LammpsInterface::domain_xz() { return lammps_->domain->xz; }
|
|
|
|
double LammpsInterface::domain_yz() { return lammps_->domain->yz; }
|
|
|
|
int LammpsInterface::domain_triclinic() { return lammps_->domain->triclinic; }
|
|
|
|
void LammpsInterface::get_box_periodicity(int & xperiodic,
|
|
int & yperiodic,
|
|
int & zperiodic)
|
|
{
|
|
xperiodic = lammps_->domain->xperiodic;
|
|
yperiodic = lammps_->domain->yperiodic;
|
|
zperiodic = lammps_->domain->zperiodic;
|
|
}
|
|
|
|
int LammpsInterface::get_region_id(const char * regionName) {
|
|
int nregion = this->nregion();
|
|
for (int iregion = 0; iregion < nregion; iregion++) {
|
|
if (strcmp(regionName, region_name(iregion)) == 0) {
|
|
return iregion;
|
|
}
|
|
}
|
|
throw ATC_Error(0,"Region has not been defined");
|
|
return -1;
|
|
}
|
|
// -----------------------------------------------------------------
|
|
// update interface methods
|
|
// -----------------------------------------------------------------
|
|
LammpsInterface::UnitsType LammpsInterface::units_style(void)
|
|
{
|
|
if (strcmp(lammps_->update->unit_style,"lj") == 0) return LJ;
|
|
else if (strcmp(lammps_->update->unit_style,"real") == 0) return REAL;
|
|
else if (strcmp(lammps_->update->unit_style,"metal") == 0) return METAL;
|
|
else return UNKNOWN;
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// lattice interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
double LammpsInterface::xlattice() { return lammps_->domain->lattice->xlattice; }
|
|
|
|
double LammpsInterface::ylattice() { return lammps_->domain->lattice->ylattice; }
|
|
|
|
double LammpsInterface::zlattice() { return lammps_->domain->lattice->zlattice; }
|
|
|
|
LammpsInterface::LatticeType LammpsInterface::lattice_style()
|
|
{
|
|
if (lammps_->domain->lattice)
|
|
return (LammpsInterface::LatticeType)lammps_->domain->lattice->style;
|
|
else
|
|
throw ATC_Error(0,"Lattice has not been defined");
|
|
}
|
|
|
|
//* retuns the number of basis vectors
|
|
int LammpsInterface::get_n_basis()
|
|
{
|
|
return lammps_->domain->lattice->nbasis;
|
|
}
|
|
|
|
//* returns the basis vectors, transformed to the box coords
|
|
void LammpsInterface::get_basis(double **basis)
|
|
{
|
|
LAMMPS_NS::Lattice *lattice = lammps_->domain->lattice;
|
|
int i,j;
|
|
double origin[3] = {0.0, 0.0, 0.0};
|
|
lattice->lattice2box(origin[0], origin[1], origin[2]);
|
|
for (i=0; i<get_n_basis(); i++)
|
|
{
|
|
memcpy(basis[i],lattice->basis[i],3*sizeof(double));
|
|
lattice->lattice2box(basis[i][0], basis[i][1], basis[i][2]);
|
|
for (j=0; j<3; j++) basis[i][j] -= origin[j];
|
|
}
|
|
}
|
|
|
|
//* gets the unit cell vectors
|
|
void LammpsInterface::get_unit_cell(double *a1, double *a2, double *a3)
|
|
{
|
|
int i, j;
|
|
double *a[3] = {a1,a2,a3};
|
|
double origin[3] = {0.0,0.0,0.0};
|
|
LAMMPS_NS::Lattice *lattice = lammps_->domain->lattice;
|
|
// transform origin
|
|
lattice->lattice2box(origin[0], origin[1], origin[2]);
|
|
|
|
// copy reference lattice vectors
|
|
memcpy(a[0], lattice->a1, 3*sizeof(double));
|
|
memcpy(a[1], lattice->a2, 3*sizeof(double));
|
|
memcpy(a[2], lattice->a3, 3*sizeof(double));
|
|
|
|
for (i=0; i<3; i++)
|
|
{
|
|
lattice->lattice2box(a[i][0], a[i][1], a[i][2]);
|
|
for (j=0; j<3; j++) a[i][j] -= origin[j];
|
|
}
|
|
}
|
|
|
|
//* gets number of atoms in a unit cell
|
|
int LammpsInterface::num_atoms_per_cell(void)
|
|
{
|
|
int naCell = 0;
|
|
LatticeType type = lattice_style();
|
|
if (type == LammpsInterface::SC) naCell = 1;
|
|
else if (type == LammpsInterface::BCC) naCell = 2;
|
|
else if (type == LammpsInterface::FCC) naCell = 4;
|
|
else if (type == LammpsInterface::DIAMOND) naCell = 8;
|
|
else if (comm_rank()==0) {
|
|
//{throw ATC_Error(0,"lattice style not currently supported by ATC");}
|
|
cout << "ATC WARNING: Cannot get number of atoms per cell from lattice\n";
|
|
naCell = 1; //HACK to enable us to keep going since this is only used to compute volume per atom
|
|
// ATC modes with a user specified atomic volume or using only volumetric quantities are fine
|
|
}
|
|
return naCell;
|
|
}
|
|
|
|
//* gets tributary volume for an atom
|
|
double LammpsInterface::volume_per_atom(void)
|
|
{
|
|
double naCell = num_atoms_per_cell();
|
|
double volPerAtom =
|
|
xlattice() * ylattice() * zlattice() / naCell;
|
|
return volPerAtom;
|
|
}
|
|
|
|
//* gets lattice basis
|
|
void LammpsInterface::get_lattice(MATRIX &N, MATRIX &B)
|
|
{
|
|
int nbasis = get_n_basis();
|
|
double **basis = new double*[nbasis];
|
|
N.reset(3,3);
|
|
B.reset(3,nbasis);
|
|
for (int i=0; i<nbasis; i++) basis[i] = column(B,i).get_ptr();
|
|
get_basis(basis);
|
|
get_unit_cell(column(N,0).get_ptr(),
|
|
column(N,1).get_ptr(),
|
|
column(N,2).get_ptr());
|
|
delete [] basis;
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// force interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
double LammpsInterface::boltz() { return lammps_->force->boltz; }
|
|
|
|
double LammpsInterface::mvv2e() { return lammps_->force->mvv2e; }
|
|
|
|
double LammpsInterface::ftm2v() { return lammps_->force->ftm2v; }
|
|
|
|
double LammpsInterface::nktv2p() { return lammps_->force->nktv2p; }
|
|
|
|
double LammpsInterface::qqr2e() { return lammps_->force->qqr2e; }
|
|
|
|
double LammpsInterface::qe2f() { return lammps_->force->qe2f; }
|
|
|
|
double LammpsInterface::dielectric() { return lammps_->force->dielectric; }
|
|
|
|
double LammpsInterface::qqrd2e() { return lammps_->force->qqrd2e; }
|
|
|
|
double LammpsInterface::pair_force(int i, int j, double rsq,
|
|
double & fmag_over_rmag)
|
|
{
|
|
int itype = (lammps_->atom->type)[i];
|
|
int jtype = (lammps_->atom->type)[j];
|
|
// return value is the energy
|
|
if (rsq < (lammps_->force->pair->cutsq)[itype][jtype]) {
|
|
return lammps_->force->pair->single(i,j,itype,jtype,
|
|
rsq,1.0,1.0,fmag_over_rmag);
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
double LammpsInterface::pair_cutoff()
|
|
{
|
|
return lammps_->force->pair->cutforce;
|
|
}
|
|
|
|
int LammpsInterface::single_enable()
|
|
{
|
|
return lammps_->force->pair->single_enable;
|
|
}
|
|
|
|
//* Boltzmann's constant in M,L,T,t units
|
|
double LammpsInterface::kBoltzmann() {
|
|
return (lammps_->force->boltz)/(lammps_->force->mvv2e);
|
|
}
|
|
|
|
//* Dulong-Petit heat capacity
|
|
double LammpsInterface::heat_capacity() {
|
|
double rhoCp = dimension()*kBoltzmann()/volume_per_atom();
|
|
return rhoCp;
|
|
}
|
|
|
|
//* reference mass density
|
|
double LammpsInterface::mass_density()
|
|
{
|
|
const int ntypes = lammps_->atom->ntypes;
|
|
const int *mass_setflag = lammps_->atom->mass_setflag;
|
|
const int *type = lammps_->atom->type;
|
|
const double *mass = lammps_->atom->mass;
|
|
const double *rmass = lammps_->atom->rmass;
|
|
// NOTE currently assumes all atoms have same mass and volume
|
|
// in the future, mass and volume will be different but density should be
|
|
// an atom indepedent quantity
|
|
if (mass) {
|
|
if (type) return mass[type[0]]/volume_per_atom();
|
|
// no type array - just use first type that has a set mass
|
|
for (int i=1; i<=ntypes; i++) {
|
|
if (mass_setflag[i]) return mass[i]/volume_per_atom();
|
|
}
|
|
// NOTE: no masses specified in input file should we warn the user of this?
|
|
return 0.0;
|
|
}
|
|
// NOTE is this valid - lammps likes to not use 0 index
|
|
if (rmass) return rmass[0]/volume_per_atom();
|
|
return 0.0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// group interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
int LammpsInterface::ngroup() { return lammps_->group->ngroup; }
|
|
|
|
int LammpsInterface::group_bit(int iGroup) { return lammps_->group->bitmask[iGroup]; }
|
|
|
|
int LammpsInterface::find_group(const char * c) { return lammps_->group->find(c); }
|
|
|
|
int LammpsInterface::group_inverse_mask(int iGroup)
|
|
{
|
|
return lammps_->group->inversemask[iGroup];
|
|
}
|
|
|
|
char * LammpsInterface::group_name(int iGroup)
|
|
{
|
|
return lammps_->group->names[iGroup];
|
|
}
|
|
|
|
void LammpsInterface::group_bounds(int iGroup, double * b)
|
|
{
|
|
lammps_->group->bounds(iGroup, b);
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// memory interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
double * LammpsInterface::create_1d_double_array(int nlo, int nhi, const char *name) {
|
|
return lammps_->memory->create_1d_double_array(nlo, nhi, name);
|
|
}
|
|
|
|
void LammpsInterface::destroy_1d_double_array(double * d, int i) {
|
|
lammps_->memory->destroy_1d_double_array(d, i);
|
|
}
|
|
|
|
double ** LammpsInterface::create_2d_double_array(int n1, int n2, const char *name) {
|
|
return lammps_->memory->create_2d_double_array(n1, n2, name);
|
|
}
|
|
|
|
void LammpsInterface::destroy_2d_double_array(double **d) {
|
|
lammps_->memory->destroy_2d_double_array(d);
|
|
}
|
|
|
|
double **LammpsInterface::grow_2d_double_array(double **array,
|
|
int n1,
|
|
int n2,
|
|
const char *name)
|
|
{
|
|
return lammps_->memory->grow_2d_double_array(array, n1, n2, name);
|
|
}
|
|
|
|
int ** LammpsInterface::create_2d_int_array(int n1, int n2, const char *name) {
|
|
return lammps_->memory->create_2d_int_array(n1, n2, name);
|
|
}
|
|
|
|
void LammpsInterface::destroy_2d_int_array(int **i) {
|
|
lammps_->memory->destroy_2d_int_array(i);
|
|
}
|
|
|
|
int ** LammpsInterface::grow_2d_int_array(int **array, int n1, int n2, const char *name) {
|
|
return lammps_->memory->grow_2d_int_array(array, n1, n2, name);
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// update interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
double LammpsInterface::dt() { return lammps_->update->dt; }
|
|
|
|
int LammpsInterface::ntimestep() { return lammps_->update->ntimestep; }
|
|
|
|
int LammpsInterface::nsteps() { return lammps_->update->nsteps; }
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// neighbor list interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
void LammpsInterface::init_list(int id, LAMMPS_NS::NeighList *ptr) { list_ = ptr; }
|
|
|
|
int LammpsInterface::neighbor_list_inum() { return list_->inum; }
|
|
|
|
int * LammpsInterface::neighbor_list_numneigh() { return list_->numneigh; }
|
|
|
|
int * LammpsInterface::neighbor_list_ilist() { return list_->ilist; }
|
|
|
|
int ** LammpsInterface::neighbor_list_firstneigh() { return list_->firstneigh; }
|
|
|
|
int LammpsInterface::neighbor_ago() { return lammps_->neighbor->ago; }
|
|
|
|
// -----------------------------------------------------------------
|
|
// region interface methods
|
|
// -----------------------------------------------------------------
|
|
|
|
char * LammpsInterface::region_name(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->id;
|
|
}
|
|
|
|
char * LammpsInterface::region_style(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->style;
|
|
}
|
|
|
|
double LammpsInterface::region_xlo(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_xlo;
|
|
}
|
|
|
|
double LammpsInterface::region_xhi(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_xhi;
|
|
}
|
|
|
|
double LammpsInterface::region_ylo(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_ylo;
|
|
}
|
|
|
|
double LammpsInterface::region_yhi(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_yhi;
|
|
}
|
|
|
|
double LammpsInterface::region_zlo(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_zlo;
|
|
}
|
|
|
|
double LammpsInterface::region_zhi(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->extent_zhi;
|
|
}
|
|
|
|
double LammpsInterface::region_xscale(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->xscale;
|
|
}
|
|
|
|
double LammpsInterface::region_yscale(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->yscale;
|
|
}
|
|
|
|
double LammpsInterface::region_zscale(int iRegion)
|
|
{
|
|
return lammps_->domain->regions[iRegion]->zscale;
|
|
}
|
|
|
|
int LammpsInterface::region_match(int iRegion, double x, double y, double z) {
|
|
return lammps_->domain->regions[iRegion]->match(x,y,z);
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// compute methods
|
|
// -----------------------------------------------------------------
|
|
int LammpsInterface::find_compute(const char* tag)
|
|
{
|
|
// a clunky way to safely get rid of the const
|
|
int n = strlen(tag) + 1;
|
|
char* tag_copy = new char[n];
|
|
strcpy(tag_copy,tag);
|
|
|
|
int icompute = lammps_->modify->find_compute(tag_copy);
|
|
if (icompute < 0) {
|
|
string msg("Could not find compute ");
|
|
msg += tag;
|
|
throw ATC_Error(0,msg);
|
|
}
|
|
return icompute;
|
|
}
|
|
|
|
LAMMPS_NS::Compute* LammpsInterface::get_compute(const char* tag)
|
|
{
|
|
int icompute = find_compute(tag);
|
|
LAMMPS_NS::Compute* cmpt = lammps_->modify->compute[icompute];
|
|
return cmpt;
|
|
}
|
|
|
|
double** LammpsInterface::compute_vector_data(const char* tag)
|
|
{
|
|
LAMMPS_NS::Compute* cmpt = get_compute(tag);
|
|
if (!(cmpt->invoked_flag & INVOKED_PERATOM)) {
|
|
cmpt->compute_peratom();
|
|
cmpt->invoked_flag |= INVOKED_PERATOM;
|
|
}
|
|
return cmpt->array_atom;
|
|
}
|
|
|
|
double* LammpsInterface::compute_scalar_data(const char* tag)
|
|
{
|
|
LAMMPS_NS::Compute* cmpt = get_compute(tag);
|
|
if (!(cmpt->invoked_flag & INVOKED_PERATOM)) {
|
|
cmpt->compute_peratom();
|
|
cmpt->invoked_flag |= INVOKED_PERATOM;
|
|
}
|
|
return cmpt->vector_atom;
|
|
}
|
|
|
|
int LammpsInterface::compute_ncols(const char* tag)
|
|
{
|
|
int icompute = find_compute(tag);
|
|
int ncols = lammps_->modify->compute[icompute]->size_peratom_cols;
|
|
if (ncols == 0) ncols = 1; // oddity of lammps, used as flag for scalar
|
|
return ncols;
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// compute pe/atom interface methods
|
|
// -----------------------------------------------------------------
|
|
int LammpsInterface::atomPE_create(void)
|
|
{
|
|
//char * list[3] = {"atcPE","all","pe/atom"};
|
|
char * list[4] = {"atcPE","all","pe/atom","pair"};
|
|
int icompute = lammps_->modify->find_compute(list[0]);
|
|
if (icompute < 0) {
|
|
lammps_->modify->add_compute(3,list);
|
|
icompute = lammps_->modify->find_compute(list[0]);
|
|
}
|
|
if (! atomPE_ ) {
|
|
atomPE_ = lammps_->modify->compute[icompute];
|
|
}
|
|
return icompute;
|
|
}
|
|
|
|
void LammpsInterface::atomPE_init(void)
|
|
{
|
|
if (atomPE_) {
|
|
atomPE_->init();
|
|
}
|
|
else {
|
|
throw ATC_Error(0,"no atomPE compute");
|
|
}
|
|
}
|
|
|
|
void LammpsInterface::atomPE_addstep(int step)
|
|
{
|
|
atomPE_->addstep(step);
|
|
}
|
|
|
|
double * LammpsInterface::atomPE_compute(void)
|
|
{
|
|
if (atomPE_) {
|
|
atomPE_->compute_peratom();
|
|
return atomPE_->vector_atom;
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
void LammpsInterface::unwrap_coordinates(int iatom, double* xatom)
|
|
{
|
|
double **x = lammps_->atom->x;
|
|
int *mask = lammps_->atom->mask;
|
|
int *image = lammps_->atom->image;
|
|
int nlocal = lammps_->atom->nlocal;
|
|
|
|
double *h = lammps_->domain->h;
|
|
double xprd = lammps_->domain->xprd;
|
|
double yprd = lammps_->domain->yprd;
|
|
double zprd = lammps_->domain->zprd;
|
|
int xbox,ybox,zbox;
|
|
|
|
// for triclinic, need to unwrap current atom coord via h matrix
|
|
// NOTE: Using current box dimensions.
|
|
if (lammps_->domain->triclinic == 0) {
|
|
xbox = (image[iatom] & 1023) - 512;
|
|
ybox = (image[iatom] >> 10 & 1023) - 512;
|
|
zbox = (image[iatom] >> 20) - 512;
|
|
xatom[0] = x[iatom][0] + xbox*xprd;
|
|
xatom[1] = x[iatom][1] + ybox*yprd;
|
|
xatom[2] = x[iatom][2] + zbox*zprd;
|
|
} else {
|
|
xbox = (image[iatom] & 1023) - 512;
|
|
ybox = (image[iatom] >> 10 & 1023) - 512;
|
|
zbox = (image[iatom] >> 20) - 512;
|
|
xatom[0] = x[iatom][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
|
|
xatom[1] = x[iatom][1] + h[1]*ybox + h[3]*zbox;
|
|
xatom[2] = x[iatom][2] + h[2]*zbox;
|
|
}
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// other methods
|
|
// -----------------------------------------------------------------
|
|
|
|
/** Return lammps pointer -- only as a last resort! */
|
|
LAMMPS_NS::LAMMPS * LammpsInterface::get_lammps_ptr() { return lammps_; }
|
|
|
|
}
|