Hi Axel,
Thank you for the clarification of the class structure/syntax; that helped a lot. I will look into the friend class.
To give context, in the custom fix, I want to compute the total potential energy of 2 states
- State 1: the existing system during the current timestep
- State 2: same configuration, but with a different charge distribution calculated by the fix
The fix then decides, based on the energy, with which configuration to proceed. The one part I was stuck on was clearing out the forces, to avoid accumulation over the multiple calculations. The surrounding code is below:
// State 1
[ make and save atomic-vector changes]
[ apply relevant reverse and forward comm to update atomic info on all processors ]
//Independent force computation for state 1, copied from verlet.cpp
force_clear(); // having a problem invoking this
if (force->pair) force->pair->compute(eflag,vflag);
if (force->kspace) force->kspace->compute(eflag,vflag);
if (force->newton) comm->reverse_comm();
// Independent PE computation for state 1, copied from compute_pe.cpp
one = 0.0; scalar1 = 0.0;
if (force->pair) one += force->pair->eng_vdwl + force->pair->eng_coul;
MPI_Allreduce(&one,&scalar1,1,MPI_DOUBLE,MPI_SUM,world);
if (force->kspace) scalar1 += force->kspace->energy;
[ do a similar force/pe computation for state 2]
[make a decision to proceed with state 1 or 2 based on scalar1 vs. scalar 2]
Following up on Adrian’s email, I am leaning more towards invoking the method from verlet than the copy-paste approach. However, this is a summary of how it was copy-pasted and what errors I got, for reference.
-
I deactivated the torque flag check, because I know for sure I have rigid bodies and torques in my system
-
I am not sure what the extraflag means
-
I could not compile atom->avec->force_clear in the fix (got an error).
…/fix_qeq_shielded_ecam.cpp:181:28: error: invalid use of incomplete type ‘class LAMMPS_NS::AtomVec’
if (extraflag) atom->avec->force_clear(0,nbytes);
- This was the modified copy-pasted code:
size_t nbytes;
//if (external_force_clear) return;
// clear force on all particles
// if either newton flag is set, also include ghosts
// when using threads always clear all forces.
int nlocal = atom->nlocal;
if (neighbor->includegroup == 0) {
nbytes = sizeof(double) * nlocal;
if (force->newton) nbytes += sizeof(double) * atom->nghost;
if (nbytes) {
memset(&atom->f[0][0],0,3nbytes);
//if (torqueflag)
memset(&atom->torque[0][0],0,3nbytes);
if (extraflag) atom->avec->force_clear(0,nbytes);
}
// neighbor includegroup flag is set
// clear force only on initial nfirst particles
// if either newton flag is set, also include ghosts
} else {
nbytes = sizeof(double) * atom->nfirst;
if (nbytes) {
memset(&atom->f[0][0],0,3nbytes);
//if (torqueflag)
memset(&atom->torque[0][0],0,3nbytes);
if (extraflag) atom->avec->force_clear(0,nbytes);
}
if (force->newton) {
nbytes = sizeof(double) * atom->nghost;
if (nbytes) {
memset(&atom->f[nlocal][0],0,3nbytes);
//if (torqueflag)
memset(&atom->torque[nlocal][0],0,3nbytes);
if (extraflag) atom->avec->force_clear(nlocal,nbytes);
}
}