Skip to content

[Code scan] PWmat atom.config writer uses frame 0 cell for every frame #997

Description

@njzjz

This issue is part of a Codex global repository code scan.

from_system_data() writes system["cells"][f_idx] to the PWmat LATTICE section, but fractionalizes coordinates with np.linalg.inv(system["cells"][0]). For multi-frame systems with changing cells, frame_idx > 0 writes coordinates in the wrong fractional basis.

Affected code:

posis = system["coords"][f_idx]
# atype_idx = [[idx,tt] for idx,tt in enumerate(atype)]
# sort_idx = np.argsort(atype, kind = 'mergesort')
sort_idx = np.lexsort((np.arange(len(atype)), atype))
atype = atype[sort_idx]
posis = posis[sort_idx]
symbal = []
for ii, jj in zip(atom_numbs, atom_names):
for kk in range(ii):
symbal.append(jj)
atomic_numbers = []
for ii in symbal:
atomic_numbers.append(ELEMENTS.index(ii) + 1)
posi_list = []
for jj, ii in zip(atomic_numbers, posis):
ii = np.matmul(ii, np.linalg.inv(system["cells"][0]))
posi_list.append("%d %15.10f %15.10f %15.10f 1 1 1" % (jj, ii[0], ii[1], ii[2])) # noqa: UP031

Minimal reproducer:

import numpy as np
from dpdata.formats.pwmat.atomconfig import from_system_data

system = {
    "atom_names": ["H"],
    "atom_numbs": [1],
    "atom_types": np.array([0]),
    "cells": np.array([np.eye(3), np.eye(3) * 2.0]),
    "coords": np.array([[[1.0, 0.0, 0.0]], [[1.0, 0.0, 0.0]]]),
}

print(from_system_data(system, f_idx=1))

Current output writes the frame-1 lattice with length 2, but the position line is fractionalized as 1.0000000000 0.0000000000 0.0000000000. It should be 0.5000000000 0.0000000000 0.0000000000 for the frame-1 cell.

The coordinate conversion should use system["cells"][f_idx].

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions