Applying random constant forces to atoms

Hello,

I am trying to apply forces (that follow normal distribution and consistent along time step) to atoms. I was using following code, which generated normal distribution forces for each atom, but changed for every time step.

variable meanF equal 0.0
variable sigF equal 1e-3

variable fpx atom normal(v_meanF,v_sigF,123)
variable fpy atom normal(v_meanF,v_sigF,123)
variable fpz atom normal(v_meanF,v_sigF,123)

fix kick all addforce v_fpx v_fpy v_fpz

So, I added a line using fix store/state so that I can fix (freeze) the force along the time step. In other words, I want to sample forces for each atom following normal distribution and use that force along the simulation (consistent along the time step).

fix storeF all store/state 0 v_fpx v_fpy v_fpz
run 10

I also did run 10 since the documentation said that the atom style variables will not be stored immediately after the fix command is called. However, I found out from the log file that the forces applied are not consistent with time, rather different forces were being applied at different time steps.

Could you recommend some possible methods to resolve this problem?

The final code I am using now is

variable meanF equal 0.0
variable sigF equal 1e-3

variable fpx atom normal(v_meanF,v_sigF,123)
variable fpy atom normal(v_meanF,v_sigF,123)
variable fpz atom normal(v_meanF,v_sigF,123)

fix storeF all store/state 0 v_fpx v_fpy v_fpz
run 10

fix kick all addforce v_fpx v_fpy v_fpz

Thank you.

What do you mean by that?

I don’t quite understand what is the problem. The code is just doing what you ask it to do. The addition of fix store/state has no impact whatsoever to the fpx, fpy, and fpz atom style variables. That is how it is supposed to be.

If you want to access the stored forces, you would have to read out f_storeF[1], f_storeF[2] and f_storeF[3].

Thank you so much for your reply. Your suggestion helped me resolve the problem.

I wasn’t clear on explaining what I was trying to do.

What I wanted to do is,

(1) Sample forces for each atom following normal distribution at the beginning of the simulation.

(2) Apply sampled force in (1) along the simulation.

However, the simulation using above code was executing (1) for every time step.

I have resolve this problem by accessing the stored forces at the beginning (1) by using f_storeF[1], f_storeF[2] and f_storeF[3]. Now I can apply constant forces.

Thanks again for your help.

One small question I have is that since I can read stored forces using f_storeF[1], how can I use this value to fix add force command?

fix kick all addforce f_storeF[1] f_storeF[2] f_storeF[3]

Above command gives me an error because f_storeF[1] is not a floating point parameter. Could you let me know if there is a way to use stored force value in addforce command line? Thank you.

Please consult the documentation. Does it say it can read forces from fixes? No. Either numbers of equal style or atom style variables. But atom style variables can access per-atom data from fixes.

P.S.: you should change your topic title and possibly any further communication on this where you replace “consistent” with “constant”.

P.P.S: another way to have constant per-atom forces from a distribution of your choice is by creating a small file with a self-written tool and use an atomfile style variable to read them in.

Yes, you are right. I had a misunderstanding on variable concepts. I was able to resolve by using following lines,

variable fpx_restored atom f_storeF[1]
variable fpy_restored atom f_storeF[2]
variable fpz_restored atom f_storeF[3]

fix kick all addforce v_fpx_restored v_fpy_restored v_fpz_restored

where I could restore the atom style variables back from the fixes. Thanks again for helping me!

P.S. I also changed the title from consistent to constant. I will also try with atom file style variables.

Hello, I would like to ask one more small question regarding atomfile style variables.

As you mentioned yesterday, I tried to implement using atomfile style variables where I read data from the following file.

# fpx
4 # indicates how many atoms we will specify
# atom-ID value
1 0.01
2 0.02
3 0.03
4 0.04

# fpy
4
# atom-ID value
1 0.05
2 0.06
3 0.07
4 0.08

# fpz
4
# atom-ID value
1 0.09
2 0.10
3 0.11
4 0.12

where the above file is saved as forces.data file. Going through the documentations, I have understood the way to read data into a variable using

variable forces atomfile forces.data

and I also realized that we need to use next command in order to read the next set of data (in this case, data about fpy and fpx).

When I use next command, for atomfile-style variables, according to the documentation, the current per-atom values stored by the atomfile-style variable are returned by the function. And the next set of per-atom values in the file is read and stored.

Therefore, I used

variable fpx atom v_forces
next forces
variable fpy atom v_forces
next forces
variable fpz atom v_forces

to read each datasets and assign to variable fpx, fpy, and fpz, sequentially. However, in this case, all the variables are reading the last dataset. In other words, all the variables are assigned to the last dataset of the forces.data file above.

I would like to ask if I use next command, the next command is called before the variable assignment, so that in this case it skips the two datasets of forces.data file above and forces to assign all the variables (fpx, fpy, and fpz) into the last dataset of the data file.

Thank you.

This is the documented and expected behavior. Like equal style variables, atom style variable are evaluated when used. For example the variable fpx then will evaluate to the current values stored in v_forces, not the values it had when defining the variable.

The solution is to split your file into 3 files and define fpx, fpy, and fpz directly as atomfile variables.

I see. That makes sense. Thank you very much again for your reply. I hope you have a wonderful day.

Hello, I would like to ask if I am correctly using the fix addforce command. The problem I am having is that the minimization result looks exactly same before and after applying the force but I think it might be because of other reasons I missed. So I wanted to make sure I am using the fix addforce command in a correct manner.

I have loaded the force values using,

variable forcesX atomfile forcesX.data
variable forcesY atomfile forcesY.data
variable forcesZ atomfile forcesZ.data

where each .data file contains information about the constant force in specific direction (X, Y, Z) for each atom. The data file looks like,

# fpx
256
1 0.024382587109235614
2 -0.03499533342882159
3 0.009003128476514776
... 

Since the variables above are atomfile style variables, I converted them to atom style variables using

variable fpx atom v_forcesX
variable fpy atom v_forcesY
variable fpz atom v_forcesZ

According to the documentation, energy keyword is required if the added force is defined with one or more variables, and I will be performing energy minimization via the “minimize”. Therefore, I used

variable espace atom -(v_fpx*x+v_fpy*y+v_fpz*z)
fix kick all addforce v_fpx v_fpy v_fpz energy v_espace

since I am dealing with constant forces defined on each atom. Then I performed minimization via

min_style cg
minimize 0.0 0.0 100000 100000

Would this be a correct way to use fix addforce command when I want to load force data from external files (for x, y, z respectively)?

Thank you.

I think I figured it out.

Basically, on the documentation, it says,

The fix_modify energy option is supported by this fix to add the potential energy inferred by the added force to the global potential energy of the system.

Therefore, I added

fix kick all addforce v_fpx v_fpy v_fpz energy v_espace
fix_modify kick energy yes

so that the energy calculated directly during the fix add force can be transferred to the global potential energy which shall be minimized by the minimization command following.