Hi all!
I am developing a C++ code that uses LAMMPS as a library.
Once I initialize LAMMPS and run for a few timesteps, I can easily access the pair-wise neighbor list requested by the interatomic potential through the relevant pointer as follows:
NeighList *mylist = lmp->force->pair->list;
Here, I face a couple of issues. Firstly, the neighbor list requested by the interatomic potential I am using (lj/cut/coul/cut) is a “half list”. However, I definitely need a “full list” for the code I am developing.
Secondly, I am using a “special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0” command in my LAMMPS input file. This means that the neighbor list requested by the pair style will not include “bonded atoms”. Of course, there is a way of accessing the bond list using something like that:
int **bondlist = lmp->neighbor->bondlist;
Generally, it would be really helpful if I could somehow request a new neighbor list from within the C++ script that is “full” and includes bonded neighboring atoms. This way I could simply use a single data container, let LAMMPS deal with the scattering of data across different processes, and nicely iterate through my neighbor list to retrieve the necessary data.
Is there any way I could request a new “full” neighbor list that also includes bonded interactions, from within the C++ code? Can I “delete/remove” the neighbor list once I am done using it and perform an additional run?
Here is an example code:
//System Headers
#include <iostream>
#include <vector>
#include <fstream>
#include <cstdio>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <mpi.h>
//LAMMPS Headers
#include "./libraries/LAMMPS_source/lmppath.h"
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
#include QUOTE(LMPPATH/src/lammps.h)
#include QUOTE(LMPPATH/src/input.h)
#include QUOTE(LMPPATH/src/atom.h)
#include QUOTE(LMPPATH/src/library.h)
#include QUOTE(LMPPATH/src/neighbor.h)
#include QUOTE(LMPPATH/src/neigh_list.h)
#include QUOTE(LMPPATH/src/force.h)
#include QUOTE(LMPPATH/src/pair.h)
#include QUOTE(LMPPATH/src/compute.h)
#include QUOTE(LMPPATH/src/pointers.h)
using namespace LAMMPS_NS;
using namespace std;
void setupMPI( int *narg , char ***arg , int *nprocs , int *me , double &time_start ){
MPI_Init( narg , arg );
MPI_Comm_rank( MPI_COMM_WORLD , me );
MPI_Comm_size( MPI_COMM_WORLD , nprocs );
time_start = MPI_Wtime( );
}
void initializeLMP( LAMMPS **lmp ){
*lmp = new LAMMPS( 0 , NULL , MPI_COMM_WORLD );
}
void readLMPinput( const std::string &lmp_input , LAMMPS *lmp ){
lmp->input->file( lmp_input.c_str( ) ); //LAMMPS constructor only uses c style strings so
}
void finalizeMPI( int *me , const double &time_start ){
double time_end = MPI_Wtime( );
printf( "Elapsed time is %f\n (process %i) \n", time_end - time_start , *me );
MPI_Finalize();
}
void deleteArraysAndObj( LAMMPS **lmp ){
delete *lmp;
}
int main( int narg , char **arg )
{
//Declare variables
int me , nprocs;
double time_start;
string lmp_input = arg[ 2 ];
LAMMPS *lmp = NULL;
//Prepare
if ( narg != 3 ) {
printf( "Syntax Error. Input command should be in the following form: mpirun -np N ./main -in in.lammps\n" );
exit( 1 );
}
setupMPI( &narg , &arg , &nprocs , &me , time_start );
initializeLMP( &lmp );
readLMPinput( lmp_input , lmp );
//Main
lmp->input->one("run 1000"); //RUN LAMMPS FOR A FEW STEPS
//Request a "full" neighbor list that includes bonded interactions -> HOW???
//Loop over neighbor list in parallel and extract data/perform operations
//Delete neighbor list
lmp->input->one("run 1000"); //RUN LAMMPS OF A FEW MORE STEPS
//Finalize
deleteArraysAndObj( &lmp );
finalizeMPI( &me , time_start );
}
Thank you in advance for your help
Kind regards,
Stavros