Lammps integrator adapt charge

Hello everyone!

I have a question about the built in Lammps NVE-integrator. I want to build a potentiostat where I change the charge of particles placed on two electrodes to control the electric field. The medium between the electrodes is filled with charged particles. As I understood from the doc "fix adapt" should change the charge of a specified group of atoms during the simulation (in my case the particles of the electrode). After I performed some test it seems that this adaption works but is done after the full nve step which results in strange dynamics. My question is now:
Is it possible to adapt the charge WITHIN the md step, so that I perform the integration of positions, then update the charge and then I calculate the "new" forces (including the new charge) and update the velocities?
So far I had the idea to perform the integration inside the lammps input script, but I do not know if it is even possible to integrate the positions, forces and velocities by hand? In some older emails of the list I found an answer that it is not possible to invoke the calculation of forces manually but maybe nowadays?
Of course the other possibility would be to write my own fix/integrator but I wanted to try everything within the environment of Lammps first.

In the case of writing my own integrator: maybe you can tell me in which files of the source code I should start or where I can add my own integrator exactly?

Thanks in advance
Florian

Florian,

your assessment of how fix adapt works is not correct.

the change of settings is called during Fix::pre_force() which is exactly at the point that you want it to be. i.e. after the position update and before the force computation and the second half velocity update.

Axel.

Hello Axel,

thank you very much for clarifiying this! After I could eliminate this problem I was wondering if it is possible to increment a variable duing the simulation. Let's say I have a charge on an atom at timestep 0 and want to add a delta (which I want to recalculate every timestep) to it and assign this new charge to the atoms. I tried to run

variable charge equal v_charge+v_dq

but this resulted in an error "Variable has circular dependency" error.
I know I can enforce immediate evaluation with a ${charge} but this is not what I want because then

variable charge equal ${charge}+v_dq

would add a 0 to dq every time. (charge has the initial value of 0.0)

I had the idea to evaluate the sum with a fix but this did not work as I expected:

variable hold equal ${charge}
variable charge equal v_hold+v_dq
fix store all ave/time 1 1 1 v_charge

So my question is:
Is it possible to realize such an incrementation during run time and how to perform it properly?

Thanks in advance
Florian

Hello Axel,

thank you very much for clarifiying this! After I could eliminate this

just one more clarification. fix adapt does not change the charge, it changes a scale factor that is applied to coulomb force and energy calculations in supported pair styles.

problem I was wondering if it is possible to increment a variable duing
the simulation. Let’s say I have a charge on an atom at timestep 0 and
want to add a delta (which I want to recalculate every timestep) to it
and assign this new charge to the atoms. I tried to run

variable charge equal v_charge+v_dq

but this resulted in an error “Variable has circular dependency” error.

yes, this is by design. if this would be allowed, it would result in undefined behavior since in LAMMPS equal style variables are more like a function than a variable and what you are trying to define is essentially a recursive function call without an option to break the recursion. since equal style variables are evaluated every time they are read, this would also be a problem if the recursion could be limited, since this will result in an undefined number of updates.

however, as an alternative to equal style variables, you could use a python style variable, which would allow executing a python function to compute a property. please note, that you will still have to deal with the issue of the function being called at every reference and thus multiple times per timestep, so you would need to build in a check to get consistent results and only allow one update per timestep.

beyond that, the cleanest approach (where you can also then modify charges directly) would be to write a new fix style of your own. you can probably borrow some inspiration for the QEq fixes that perform charge equilibration, i.e. also some kind of dynamically changing charges once at every step during the propagation of an MD run,

axel.