ulissigroup / vasp-interactive

GNU Lesser General Public License v2.1
53 stars 11 forks source link

About the cell optimization #52

Open RedStar-Iron opened 9 months ago

RedStar-Iron commented 9 months ago

I have add the patch for cell optimization to the VASP source code, but how can I active the cell opt function when I use the vaspinteractive?

alchem0x2A commented 9 months ago

Please take a look at https://github.com/ulissigroup/vasp-interactive/blob/main/tests/test_unitcell_filter.py, the optimization of cell can be achieved by something like UnitCellFilter or StrainFilter in ASE, depending on the problem you're studying (i.e. are your scaled positions the same, or can also change?)

I would recommend at least try once the direct Cell opt routine in VASP (isif=3 or isif=4) to double check the sanity of the ASE optimization results

RedStar-Iron commented 9 months ago

Hi Tian,

I did the test for cell optimization by using the UnitCellFilter, StrainFilter and ExpcellFIlter. The results getting from UnitCellFilter and ExpcellFIlter are strange where the final structures changed a lot with extremly short bonds. The result from StrainFilter seems reasonable although it is still different from the structure getting from original vasp (I used the IOPTCAELL to just optimize the lattice length). If I use dist.pl to check the difference between original vasp one and StrainFilter one, it gives 7. And the difference of "cellpar" for these two is 3.45.

original vasp: 10.7768669430955306 0.0000000000000000 0.0000000000000000 0.0000000000000000 10.1331379995132043 0.0000000000000000 0.0000000000000000 0.0000000000000000 11.8358006835585172

StrainFilter : 10.6714800376568295 0.0000000000000000 0.0000000000000000 -0.0000000000000003 10.1933895089472646 -0.0000000000003578 0.0000000000000050 -0.0000000000009424 12.1820598150329271

alchem0x2A commented 9 months ago

Lattice optimization using ASE's optimizers may sometimes be problematic. Could you re-do the same optimization using plain ase.calculators.vasp.Vasp (i.e. the non-interactive one) to see if you get the same results? It is just to make sure there aren't any bugs introduced in the lattice patch I made to VASP source code. Previously it was tested against relatively smaller systems

RedStar-Iron commented 9 months ago

Hi Tian,

I did the test for it through ase.calculators.vasp.Vasp, it seems weird, it stopped in only 1 or 3 steps leading to nearly unchanged structure.

Below are my testing codes, I don't know if there are something wrongs with them.

Code - 1

It stopped in only 1 step

calc = Vasp(**vasp_inputs)
t_ = time()
initial_structure.calc = calc
mask = args.mask.split(" ")
mask = [True if x == "1" else False for x in mask]
print(mask)  # mask = [ True,True,True,False,False,False]
sf = StrainFilter(initial_structure,mask=mask)
dyn = BFGS(sf)
from ase.io.trajectory import Trajectory
with Trajectory("optimized.traj", "w", initial_structure) as traj:
    dyn.attach(traj)
    dyn.run(fmax=0.03)

Code - 2

It stopped in 3 steps

t_ = time()
calc = Vasp(**vasp_inputs)
initial_structure.calc = calc
sf1 = StrainFilter(initial_structure,mask=[True,True,True,False,False,False])
dyn = BFGS(sf1,trajectory="opt.traj")
print("------Starting VASP Optimization------")
dyn.run(fmax=0.03)
print("------Finished VASP Optimization------")
sf1.atoms.write("opt.traj")
print(f"Time to conduct VASP optimization: {time() - t_}")

Code - 3

It has been running for an hour, typically one ionic step took less than 1 min, but the CONTCAR nearly didn't change compared to the POSCAR

calc = Vasp(**vasp_inputs)
t_ = time()
initial_structure.calc = calc
mask = args.mask.split(" ")
mask = [True if x == "1" else False for x in mask]
sf = StrainFilter(initial_structure,mask=mask)
dyn = BFGS(sf)
# Use manual force threshold in order to read the iterations
n_elec = []
n_ion = 1
f = np.abs(initial_structure.get_forces()).max()
from ase.io.trajectory import Trajectory
with Trajectory("optimized.traj", "w", initial_structure) as traj:
    dyn.attach(traj)
    while f > 0.03:
        dyn.step()
        n_ion += 1
        f = np.abs(initial_structure.get_forces()).max()
        n_elec.append(calc.read_number_of_iterations())
sf.atoms.write("opt.traj")
print(f"Ionic steps: {n_ion}")
print(f"Electronic steps per ionic cycle: {n_elec}")
print(f"Time to conduct VASP: {time() - t_}")