Inquiry about Sinusoidal Oscillation

I am using LAMMPS version lammps-22Dec2022 on the CentOS operating system.
I intend to apply a sinusoidal deformation gamma_a * sin(omega * t) to the system, as shown in the figure below.
wiggle

I utilized the fix deform wiggle ... remap v to induce deformation to the box. To apply this deformation to particles, I employed the fix nvt/sllod command.

Next, the box is divided into 20 equal parts along the y direction, and the average x-direction velocities of particles in each part are calculated.

I expected the average x-direction velocity of particles at position y to be y * gamma_a * omega * cos(omega * t), with the maximum velocity at the top of the box (the twentieth part) and an average velocity of 0 at the bottom, with the same phase.

However, I observed a phase difference of pi, resulting in velocities being opposite to expectations. The velocity at the top of the box (the twentieth part) is 0.5 * y_max * gamma_a * omega * cos(omega * t) instead of y_max * gamma_a * omega * cos(omega * t).


This means that the x-direction velocity for the tenth part of the box is closer to 0.

I am aware of a similar issue in simple shear cases, where the solution involves adding the expected velocity gradient in the x-direction before shearing. However, this approach is not applicable to oscillatory scenarios.

I also noticed that a similar question was raised in this forum before, but a satisfactory solution was not provided. Additionally, LAMMPS does not have pre-existing examples of oscillatory shearing. I would like to ask if using fix deform wiggle ... remap v + fix nvt/sllod in LAMMPS can achieve oscillatory shear, as the nvt/sllod equation assumes a uniform velocity bias.

Below is my code.

variable        strain equal 0.02
variable		omega equal 0.1

units 		    lj
dimension 	    3
boundary 	    p p p
atom_style 	    sphere 

lattice 	    fcc 1.38
region 	        box block 0 11 0 11 0 11
create_box 	    2 box
create_atoms 	1 box 
group           smaller_atoms id 1:19652:5
set 		    group smaller_atoms type 2

change_box 	    all triclinic

set 		    type 1 mass 1
set 		    type 2 mass 1

neighbor 	    1.0 multi
neigh_modify 	delay 0
comm_modify 	mode multi

pair_style 	    lj/cut 2.5
pair_coeff 	    1 1 1.0 1.0 2.5
pair_coeff 	    2 2 0.5 0.88 2.5
pair_coeff 	    1 2 1.5 0.8 2.5

# start heat ################

velocity 	    all create 5.0 4738964 dist gaussian rot yes

timestep 	    0.001
fix 		    motion all nve
fix 		    start_heat all langevin 5.0 5.0 $(100.0*dt) 347589123 zero yes

thermo 	        1000
thermo_style 	custom step temp epair etotal press vol pxy

run 		    50000

unfix 		    start_heat
unfix 		    motion

reset_timestep  0

# eq run #####################

velocity        all zero linear
velocity        all zero angular
velocity 	    all scale 1.0

timestep        0.005
fix 		    1 all nvt temp 1 1 $(100.0*dt)
run				500000
unfix			1

# wiggle shear ###############

variable		A equal v_strain*ly
variable		T equal 2*PI/v_omega
fix 		    1 all deform 1 xy wiggle $(v_A) $(v_T) remap v units box
fix 		    2 all nvt/sllod temp 1.0 1.0 $(100.0*dt)

compute 	    layers all chunk/atom bin/1d y center 0.05 units reduced
fix 		    layers_vx all ave/chunk 20 50 1000 layers vx file profile_vx.txt

thermo_style	custom step c_2_temp temp epair etotal press vol pxy
thermo		    1000

run		        100000

Thank you in advance.

You need to carefully check if the velocity profile assumed by fix nvt/sllod is consistent with the box’s actual velocity profile, for example with compute temp/profile to see if the box achieves the desired temperature with rough spatial homogeneity.

Beyond that, I don’t see why your observations are a problem. Physically speaking, there is no difference between having:

  1. one set of particles moving rightward at 1 nm/ps and another set moving leftward at 1 nm/ps
  2. one set of particles moving rightward at 2 nm/ps and another set stationary;

in both situations the particles have the same relative velocity.

Thermally speaking, it is the peculiar kinetic energy in frame 1, the stationary-center-of-mass frame, that is directly proportional to temperature via Boltzmann’s constant. (An ice cube is not instantaneously heated by the translational velocity of me throwing it across the room.)

Thank you for your reply. Following your suggestion, I used the following command to divide the system into 10 segments along the y direction and calculated the temperature of each segment after removing the translational velocity using compute temp/profile.

compute unbiased_temp all temp/profile 1 0 0 y 10 out bin
fix output_temp all ave/time 100 10 1000 c_unbiased_temp[*] mode vector file unbiased_temp_$(v_omega).txt

I noticed that when omega is small, the temperature distribution along the y-direction is near the set value of 1.0. However, as omega increases, it deviates significantly from 1.0. The deviation is larger near the center of the box.
ytemp

I believe that the small deviation of the temperature distribution from 1.0 when omega is small is not necessarily an indication of the correct application of the Sllod equation for the sinusoidal oscillation, but rather due to the additional sinusoidal oscillation velocity (proportional to omega) being much smaller compared to the thermal velocity, which becomes more apparent when omega is large.

This might indicate that fix deform wiggle remap v combined with fix nvt/sllod may not be suitable for simulating sinusoidal oscillations. I am unsure if there are alternative solutions available.

Code:

variable        strain equal 0.02
variable		omega equal 5.0

units 		    lj
dimension 	    3
boundary 	    p p p
atom_style 	    sphere 

lattice 	    fcc 1.38
region 	        box block 0 11 0 11 0 11
create_box 	    2 box
create_atoms 	1 box 
group           smaller_atoms id 1:19652:5
set 		    group smaller_atoms type 2

change_box 	    all triclinic

set 		    type 1 mass 1
set 		    type 2 mass 1

neighbor 	    1.0 multi
neigh_modify 	delay 0
comm_modify 	mode multi

pair_style 	    lj/cut 2.5
pair_coeff 	    1 1 1.0 1.0 2.5
pair_coeff 	    2 2 0.5 0.88 2.5
pair_coeff 	    1 2 1.5 0.8 2.5

# start heat ################

velocity 	    all create 5.0 4738964 dist gaussian rot yes

timestep 	    0.001
fix 		    motion all nve
fix 		    start_heat all langevin 5.0 5.0 $(100.0*dt) 347589123 zero yes

thermo 	        1000
thermo_style 	custom step temp epair etotal press vol pxy

run 		    50000

unfix 		    start_heat
unfix 		    motion

reset_timestep  0

# eq run #####################

velocity        all zero linear
velocity        all zero angular
velocity 	    all scale 1.0

timestep        0.005
fix 		    1 all nvt temp 1 1 $(100.0*dt)
run				500000
unfix			1

# wiggle shear ###############

variable		A equal v_strain*ly
variable		T equal 2*PI/v_omega
fix 		    1 all deform 1 xy wiggle $(v_A) $(v_T) remap v units box
fix 		    2 all nvt/sllod temp 1.0 1.0 $(100.0*dt)

# compute 	    layers all chunk/atom bin/1d y center 0.05 units reduced
# fix 		    layers_vx all ave/chunk 20 50 1000 layers vx file profile_vx.txt

compute         unbiased_temp all temp/profile 1 0 0 y 10 out bin
fix             output_temp all ave/time 100 10 1000 c_unbiased_temp[*] mode vector file unbiased_temp_$(v_omega).txt

thermo_style	custom step c_2_temp temp epair etotal press vol pxy
thermo		    1000

run		        100000

Good job checking for different oscillatory amplitudes. This looks like a case of mismatched velocity profiles between the deformation mechanism and the thermostat. Specifically, it looks like fix nvt/sllod assumes a velocity profile going from 0 to vmax, while fix deform is actually imposing a velocity profile going from -vmax/2 to +vmax/2.

You can try:

compute ProfileTemp all temp/profile ...
fix Thermostat all nvt ...
fix_modify Thermostat temp c_ProfileTemp

This uses temp/profile to directly calculate the velocity profile instead of using a theoretical linear profile, known as a “profile-unbiased thermostat” or PUT (search the literature for this term to see how it has been previously applied).

In theory having too few bins in the PUT will make your results depend on the number of bins. You can assess this by measuring a fine-grained temperature profile during the simulation – either with another compute temp/profile or using fix ave/chunk ... temp.

Thank you for your advice. I have employed the PUT strategy using the following commands:

fix 		    1 all deform 1 xy wiggle $(v_A) $(v_T) remap v units box
compute         unbiased_temp all temp/profile 1 0 0 y $(v_ybins) out bin
fix             2 all nvt temp 1.0 1.0 $(100*dt)
fix_modify      2 temp unbiased_temp

Meanwhile, I utilize another compute temp/profile to monitor the temperature distribution after removing the flow field velocity:

compute         monitor_unbiased_temp all temp/profile 1 0 0 y $(v_ybins) out bin
fix             output_temp all ave/time 100 10 1000 c_monitor_unbiased_temp[*] mode vector file unbiased_temp_$(v_omega)_$(v_ybins).txt

By adjusting the variable ybins to divide the bin number in the y direction of temp/profile, I found that the obtained velocity distribution still deviates from 1.0.
puttemp

Interestingly, using thermo_style custom temp, I obtained a temperature close to 1.1, whereas previously, when using the SLLOD equation, this command calculated a temperature of around 0.65.
putsllod

Complete code:

variable        strain equal 0.02
variable		omega equal 8.0
variable        ybins equal 20

units 		    lj
dimension 	    3
boundary 	    p p p
atom_style 	    sphere 

lattice 	    fcc 1.38
region 	        box block 0 11 0 11 0 11
create_box 	    2 box
create_atoms 	1 box 
group           smaller_atoms id 1:19652:5
set 		    group smaller_atoms type 2

change_box 	    all triclinic

set 		    type 1 mass 1
set 		    type 2 mass 1

neighbor 	    1.0 multi
neigh_modify 	delay 0
comm_modify 	mode multi

pair_style 	    lj/cut 2.5
pair_coeff 	    1 1 1.0 1.0 2.5
pair_coeff 	    2 2 0.5 0.88 2.5
pair_coeff 	    1 2 1.5 0.8 2.5

# start heat ################

velocity 	    all create 5.0 478964 dist gaussian rot yes

timestep 	    0.001
fix 		    motion all nve
fix 		    start_heat all langevin 5.0 5.0 $(100.0*dt) 34789123 zero yes

thermo 	        1000
thermo_style 	custom step temp epair etotal press vol pxy

run 		    50000

unfix 		    start_heat
unfix 		    motion

reset_timestep  0

# eq run #####################

velocity        all zero linear
velocity        all zero angular
velocity 	    all scale 1.0

timestep        0.005
fix 		    1 all nvt temp 1 1 $(100.0*dt)
run				500000
unfix			1

# wiggle shear ###############

variable		A equal v_strain*ly
variable		T equal 2*PI/v_omega
fix 		    1 all deform 1 xy wiggle $(v_A) $(v_T) remap v units box
compute         unbiased_temp all temp/profile 1 0 0 y $(v_ybins) out bin
fix             2 all nvt temp 1.0 1.0 $(100*dt)
fix_modify      2 temp unbiased_temp

compute         monitor_unbiased_temp all temp/profile 1 0 0 y $(v_ybins) out bin
fix             output_temp all ave/time 100 10 1000 c_monitor_unbiased_temp[*] mode vector file unbiased_temp_$(v_omega)_$(v_ybins).txt

thermo_style	custom step temp epair etotal press vol pxy
thermo		    1000

run		        200000

I think it may be that the frequency of the applied oscillations is so high that thermostat is not possible, perhaps doing similar sinusoidal oscillations needs to be done within a certain frequency.

Yes – there is always a chance that you are hitting a genuine limit of the thermostat and it cannot dissipate the heat of shearing fast enough.

You can try to make the thermostat more “aggressive”, firstly by setting tchain 1 (chain Nose Hoover thermostats are known to induce inaccuracies for strongly dissipative non-equilibrium simulations ), and then by setting a shorter time constant.

Thanks. So this seems to be an “empirical” problem in LAMMPS, since it seems impossible to determine exactly what value of the oscillation frequency is less than which the simulation results are reliable.