Closed mbagheri20 closed 1 year ago
Hi @mbagheri20, Sorry for the delay in response. Thanks for bringing this issue to the table and providing the solution simultaneously. I suppose you have a branch that incorporated the changes. If so, can you submit a PR so I can merge it into our main branch to fix this? Thanks!
Hi @Zhuoying, I sent the PR but I did that changes last year. Hopefully, there are no changes in other places of the atomate new version that can affect this workflow.
Thanks @mbagheri20, I will let it run the test first before merging.
Hi, I think the eigenvector normalization in Raman workflow has a bug that In practice can make small errors in Raman tensors and intensities. For example, MoS2 is a well-known system and there are a lot of reports about that in literature. It has only two Raman-active modes, but when calculated with atomate, an extra mode appeared in the Raman spectrum.
The issue raised from WriteNormalmodeDisplacedPoscar class in atomate/vasp/firetasks/write_inputs.py and RamanTensorToDb class in atomate/vasp/firetasks/parse_outputs.py Eigenvector is size [natoms,3]. atomate default approach calculates the norm over row (x,y,z) for each atom, and gets the vector of size [natoms,1], and then normalizes each row. It means that each atom is displaced by the step size (default = 0.005 Å). That makes no sense if the eigenvector is such that, e.g., S should dominate but Mo also has a small non-zero contribution (due to noise, for example). Also, the default approach missed dividing eigenvectors by sqrt(mass). The correct way to normalize is to divide each row of eigenvector by sqrt(mass) and then normalize with the norm of the whole eigenvector (a single number).
`class WriteNormalmodeDisplacedPoscar(FiretaskBase): required_params = ["mode", "displacement"] def run_task(self, fw_spec): mode = self["mode"] disp = self["displacement"] structure = Structure.from_file("POSCAR") masses = np.array([site.specie.data['Atomic mass'] for site in structure]) nm_eigenvecs = np.array(fw_spec["normalmodes"]["eigenvecs"]) nm_eigenvec_sqm = nm_eigenvecs[mode, :, :] / np.sqrt(masses[:, np.newaxis]) nm_norms = np.linalg.norm(nm_eigenvec_sqm) *nm_displacement = (nm_eigenvec_sqm disp / nm_norms)** for i, vec in enumerate(nm_displacement): structure.translate_sites(i, vec, frac_coords=False)
structure.to(fmt="poscar", filename="POSCAR")`
`
class RamanTensorToDb(FiretaskBase):
`