Hello,
I am extracting forces from many atomic configurations and I have coupled my LAMMPS with C++ to reduce overhead and use the forces as variables in my C++ code. This is a lot faster than reading and writing dump files, but there is still some overhead associated with getting the forces. This is because I call "run 0 pre yes post no" up to 10^8 times for different configurations, and then extract the forces for those configurations. I was wondering if there is a faster way to accomplish this task.
Here is a simplified version of my C++ code to demonstrate my point:
#include <iostream>
#include <array>
#include <math.h>
#include <algorithm>
#include "mpi.h"
// these are LAMMPS include files
#include "lammps.h"
#include "input.h"
#include "atom.h"
#include "library.h"
using namespace std;
// LAMMPS NAMESPACE AND POINTERS
using namespace LAMMPS_NS;
char *args1[] = {
(char *) "lmp",
(char *) "-screen",
(char*) "none",
0};
LAMMPS *lmp;
const int N=64; // number of atoms
double f[3*N]; // per-atom force vector
int main(int argc, char **argv)
{
MPI_Init(&argc,&argv);
LAMMPS *lmp;
lmp = new LAMMPS(3,args1,MPI_COMM_WORLD);
// Prepare the run
lmp->input->one("log none");
lmp->input->one("neighbor 1.0 multi");
lmp->input->one("boundary p p p");
lmp->input->one("units metal");
lmp->input->one("atom_style atomic");
lmp->input->one("atom_modify map array");
lmp->input->one("lattice diamond 5.431");
lmp->input->one("region box block 0 2 0 2 0 2 units lattice");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
lmp->input->one("mass 1 28.0855");
lmp->input->one("pair_style tersoff");
lmp->input->one("fix 1 all nve");
lmp->input->one("pair_coeff * * Si.tersoff Si");
int loops = pow(10,4); // ---------------------------------------- Increase this number to observe overhead ---------------------------------------------
for (int i=1; i<=loops; i++)
{
// Displace the atoms
lmp->input->one("displace_atoms all random 0.01 0.01 0.01 5");
// Evaluate the potential
lmp->input->one("run 0 pre yes post no");
// Get the forces
lammps_gather_atoms(lmp,"f",1,3,f);
}
MPI_Finalize();
}
And my potential file looks like this:
# DATE: 2007-10-25 CONTRIBUTOR: Aidan Thompson, [email protected] CITATION: Tersoff, Phys Rev B, 37, 6991 (1988)
# Tersoff parameters for various elements and mixtures
# multiple entries can be added to this file, LAMMPS reads the ones it needs
# these entries are in LAMMPS "metal" units:
# A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms
# other quantities are unitless
# This is the Si parameterization from a particular Tersoff paper:
# J. Tersoff, PRB, 37, 6991 (1988)
# See the SiCGe.tersoff file for different Si variants.
# format of a single entry (one or more lines):
# element 1, element 2, element 3,
# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A
Si Si Si 3.0000 1.0000 1.3258 4.8381 2.0417 0.0000 22.9560
0.3368 1.3258 95.3738 3.0000 0.2000 3.2394 3264.7000
The purpose of my C++ code is to perturb the atoms and get the forces for the perturbed configurations. Notice the "loop" variable in my code. The overhead I've experienced with this value are as follows:
10^3 loops: 1.1 seconds
10^4 loops: 11.2 seconds
10^5 loops: 145 seconds
10^6 loops: 11 minutes
10^7 loops: 1 hour
10^8 loops: 10 hours
If I change the run command to "run 0 pre no post no" this overhead is drastically reduced (obviously) but then the newly gathered forces are not representative of the perturbed configuration, since "pre no" acts as if nothing was changed.
I was wondering if there is a quicker way to get the forces from snapshots of many configurations. As shown, 10^8 calls of "run 0 pre yes post no" takes ~10 hours. I was hoping to do 10^10 runs for my purposes, and this would take a while.
Is there a quicker way to get the forces from many configurations, or have I done all I can do?