Program Listing for File lammps_pele.cpp#
↰ Return to documentation for file (source/lammps_pele.cpp)
#include <iostream>
#include "pele/lammps_pele.hpp"
#include "library.h"
#if defined(LAMMPS_LIB_MPI)
#include <mpi.h>
#endif
#include <stdio.h>
#include "angle.h"
#include "atom.h"
#include "bond.h"
#include "comm.h"
#include "compute.h"
#include "dihedral.h"
#include "domain.h"
#include "error.h"
#include "fix.h"
#include "force.h"
#include "group.h"
#include "info.h"
#include "input.h"
#include "improper.h"
#include "kspace.h"
#include "lmppython.h"
#include "memory.h"
#include "modify.h"
#include "neigh_list.h"
#include "neighbor.h"
#include "output.h"
#include "pair.h"
#if defined(LMP_PLUGIN)
#include "plugin.h"
#endif
#include "region.h"
#include "timer.h"
#include "universe.h"
#include "update.h"
#include "variable.h"
#include "pele/base_potential.hpp"
#include <cstdint>
using namespace std;
using namespace LAMMPS_NS;
namespace pele {
LAMMPSPotential::LAMMPSPotential(uintptr_t handle) : handle(handle) {};
double LAMMPSPotential::get_energy(Array<double> const &xs)
{
auto lmp = (LAMMPS *) this->handle;
auto comm = (Comm *) lmp->comm;
auto timer = (Timer *) lmp->timer;
auto modify = (Modify *) lmp->modify;
auto neighbor = (Neighbor *) lmp->neighbor;
auto domain = (Domain *) lmp->domain;
auto atom = (Atom *) lmp->atom;
auto force = (Force *) lmp->force;
auto update = (Update *) lmp->update;
auto output = (Output *) lmp->output;
class Compute *pe_compute;
double **x = lmp->atom->x;
int ii;
int eflag=1;
int vflag=1;
int triclinic = domain->triclinic;
int neigh_every, neigh_delay, neigh_dist_check;
if (update->first_update == 0) {
lammps_command(lmp, "run 0 pre no post no");
}
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if ((neigh_every != 1) || (neigh_delay != 0)) {
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
}
update->whichflag = 1;
pe_compute = modify->get_compute_by_id("thermo_pe");
if (!pe_compute) lmp->error->all(FLERR,"Minimization could not find thermo_pe compute");
// read coordinates
for (int i = 0; i < lmp->atom->nlocal; i++) {
ii = 3*i;
x[i][0] = xs[ii+0];
x[i][1] = xs[ii+1];
x[i][2] = xs[ii+2];
}
// check for reneighboring
// always communicate since minimizer moved atoms
int nflag = neighbor->decide();
if (nflag == 0) {
timer->stamp();
comm->forward_comm();
timer->stamp(Timer::COMM);
} else {
if (modify->n_min_pre_exchange) {
timer->stamp();
modify->min_pre_exchange();
timer->stamp(Timer::MODIFY);
}
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
if (domain->box_change) {
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
}
timer->stamp();
comm->exchange();
if (atom->sortfreq > 0 &&
update->ntimestep >= atom->nextsort) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(Timer::COMM);
if (modify->n_min_pre_neighbor) {
modify->min_pre_neighbor();
timer->stamp(Timer::MODIFY);
}
neighbor->build(1);
timer->stamp(Timer::NEIGH);
if (modify->n_min_post_neighbor) {
modify->min_post_neighbor();
timer->stamp(Timer::MODIFY);
}
}
memset(&atom->f[0][0],0,3*sizeof(double) * atom->nlocal);
timer->stamp();
if (modify->n_min_pre_force) {
modify->min_pre_force(vflag);
timer->stamp(Timer::MODIFY);
}
force->pair->compute(eflag,vflag);
timer->stamp(Timer::PAIR);
if (atom->molecular != Atom::ATOMIC) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
timer->stamp(Timer::BOND);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
timer->stamp(Timer::KSPACE);
}
if (modify->n_min_pre_reverse) {
modify->min_pre_reverse(eflag,vflag);
timer->stamp(Timer::MODIFY);
}
if (force->newton) {
comm->reverse_comm();
timer->stamp(Timer::COMM);
}
if (modify->n_min_post_force) {
timer->stamp();
modify->min_post_force(vflag);
timer->stamp(Timer::MODIFY);
}
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
update->whichflag = 0;
pe_compute->compute_scalar();
return pe_compute->scalar;
}
double LAMMPSPotential::get_energy_gradient(Array<double> const &xs, Array<double> &gs)
{
auto lmp = (LAMMPS *) this->handle;
auto comm = (Comm *) lmp->comm;
auto timer = (Timer *) lmp->timer;
auto modify = (Modify *) lmp->modify;
auto neighbor = (Neighbor *) lmp->neighbor;
auto domain = (Domain *) lmp->domain;
auto atom = (Atom *) lmp->atom;
auto force = (Force *) lmp->force;
auto update = (Update *) lmp->update;
auto output = (Output *) lmp->output;
class Compute *pe_compute;
double **x = lmp->atom->x;
double **f = lmp->atom->f;
int ii;
int eflag=1;
int vflag=1;
int triclinic = domain->triclinic;
int neigh_every, neigh_delay, neigh_dist_check;
if (update->first_update == 0) {
lammps_command(lmp, "run 0 pre no post no");
}
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if ((neigh_every != 1) || (neigh_delay != 0)) {
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
}
update->whichflag = 1;
pe_compute = modify->get_compute_by_id("thermo_pe");
if (!pe_compute) lmp->error->all(FLERR,"Minimization could not find thermo_pe compute");
// read coordinates
for (int i = 0; i < lmp->atom->nlocal; i++) {
ii = 3*i;
x[i][0] = xs[ii+0];
x[i][1] = xs[ii+1];
x[i][2] = xs[ii+2];
}
// check for reneighboring
// always communicate since minimizer moved atoms
int nflag = neighbor->decide();
if (nflag == 0) {
timer->stamp();
comm->forward_comm();
timer->stamp(Timer::COMM);
} else {
if (modify->n_min_pre_exchange) {
timer->stamp();
modify->min_pre_exchange();
timer->stamp(Timer::MODIFY);
}
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
if (domain->box_change) {
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
}
timer->stamp();
comm->exchange();
if (atom->sortfreq > 0 &&
update->ntimestep >= atom->nextsort) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(Timer::COMM);
if (modify->n_min_pre_neighbor) {
modify->min_pre_neighbor();
timer->stamp(Timer::MODIFY);
}
neighbor->build(1);
timer->stamp(Timer::NEIGH);
if (modify->n_min_post_neighbor) {
modify->min_post_neighbor();
timer->stamp(Timer::MODIFY);
}
}
memset(&atom->f[0][0],0,3*sizeof(double) * atom->nlocal);
timer->stamp();
if (modify->n_min_pre_force) {
modify->min_pre_force(vflag);
timer->stamp(Timer::MODIFY);
}
force->pair->compute(eflag,vflag);
timer->stamp(Timer::PAIR);
if (atom->molecular != Atom::ATOMIC) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
timer->stamp(Timer::BOND);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
timer->stamp(Timer::KSPACE);
}
if (modify->n_min_pre_reverse) {
modify->min_pre_reverse(eflag,vflag);
timer->stamp(Timer::MODIFY);
}
if (force->newton) {
comm->reverse_comm();
timer->stamp(Timer::COMM);
}
if (modify->n_min_post_force) {
timer->stamp();
modify->min_post_force(vflag);
timer->stamp(Timer::MODIFY);
}
// write force
for (int i = 0; i < lmp->atom->nlocal; i++) {
ii = 3*i;
gs[ii+0] = -f[i][0];
gs[ii+1] = -f[i][1];
gs[ii+2] = -f[i][2];
}
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
update->whichflag = 0;
pe_compute->compute_scalar();
return pe_compute->scalar;
}
}