Hello!
I am trying to apply an active force to particles. I tried to do this using fix external and filling the fexternal array but in this way I do not get the correct results. I tried another way, still using the fix external, where I, instead of using the fexternal array, gathered the force vector from all particles and simply added the active force directly and then scattered. This works!
Here are the two implementations. I have no idea why they yield different results. i checked and the fix is called at post_force. That’s why directly messing with the force array works, it is not cleared before the forces are applied.
Any ideas?
void active_force_fails(void *ptr, long int timestep, int nlocal, int *ids, double **x, double **fexternal)
{
double *theta = (double )malloc(nlocalsizeof(double));
lammps_gather_atoms(ptr,“d_theta”,1,1,theta);
double *dt_ptr = (double *)lammps_extract_global(ptr,"dt");
double dt = *dt_ptr;
double *drot_ptr = (double *) lammps_extract_variable(ptr,"Drot", NULL);
double drot = *drot_ptr;
double *factive_ptr = (double *) lammps_extract_variable(ptr,"factive", NULL);
double factive = *factive_ptr;
double upd;
for(int i=0;i<nlocal;i++) {
fexternal[i][0] = factive*cos(theta[i]);
fexternal[i][1] = factive*sin(theta[i]);
fexternal[i][2] = 0.0;
upd=sqrt(2*drot*dt)*gaussian_random(0.0,1.0);
theta[i] += upd;
}
lammps_scatter_atoms(ptr,"d_theta",1,1,theta);
free(theta);
}
void active_force_works(void *ptr, long int timestep, int nlocal, int *ids, double **x, double **fexternal)
{
double *theta = (double )malloc(nlocalsizeof(double));
lammps_gather_atoms(ptr,“d_theta”,1,1,theta);
double *dt_ptr = (double *)lammps_extract_global(ptr,"dt");
double dt = *dt_ptr;
double *drot_ptr = (double *) lammps_extract_variable(ptr,"Drot", NULL);
double drot = *drot_ptr;
double *factive_ptr = (double *) lammps_extract_variable(ptr,"factive", NULL);
double factive = *factive_ptr;
double *f = (double *)malloc(3*nlocal*sizeof(double));
lammps_gather_atoms(ptr,(char *) "f",1,3,f);
double upd,sqr2dt;
sqr2dt = sqrt(2*drot*dt);
for(int i=0;i<nlocal;i++) {
f[i*3] += factive*cos(theta[i]);
f[3*i+1] += factive*sin(theta[i]);
upd=sqr2dt*gaussian_random(0.0,1.0);
theta[i] += upd;
}
lammps_scatter_atoms(ptr,"d_theta",1,1,theta);
lammps_scatter_atoms(ptr,(char *) "f",1,3,f);
free(f);
free(theta);
}