Skip to content

Commit

Permalink
Rename topology -> stoichiometry
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-schlipf committed Jan 28, 2025
1 parent dd86faa commit 68cea47
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 281 deletions.
8 changes: 5 additions & 3 deletions src/py4vasp/_calculation/_CONTCAR.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,18 @@ def _line_generator(self):
selective_dynamics = self._raw_data.selective_dynamics
yield convert.text_to_string(self._raw_data.system)
yield from _cell_lines(cell)
yield self._topology().to_POSCAR()
yield self._stoichiometry().to_POSCAR()
if not selective_dynamics.is_none():
yield "Selective dynamics"
yield "Direct"
yield from _ion_position_lines(positions, selective_dynamics)
yield from _lattice_velocity_lines(self._raw_data.lattice_velocities, cell)
yield from _ion_velocity_lines(self._raw_data.ion_velocities)

def _topology(self):
return calculation._topology.from_data(self._raw_data.structure.topology)
def _stoichiometry(self):
return calculation._stoichiometry.from_data(
self._raw_data.structure.stoichiometry
)


def _cell_lines(cell):
Expand Down
2 changes: 1 addition & 1 deletion src/py4vasp/_calculation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class provides a more flexible interface with which you can determine the source
"workfunction",
"_CONTCAR",
"_dispersion",
"_topology",
"_stoichiometry",
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,13 @@
_subscript = "_"


class Topology(base.Refinery):
"""The topology of the crystal describes the ions of a crystal and their connectivity.
At the current stage, this class only exposes the name of the atoms in the unit
cell. In the future, we could add functionality for the user to group multiple
atoms. If you are interested in this feature and have a specific use case in mind,
please create an issue on Github_.
.. _Github: https://github.com/vasp-dev/py4vasp
"""
class Stoichiometry(base.Refinery):
"""The stoichiometry of the crystal describes how many ions of each type exist in a crystal."""

@classmethod
def from_ase(cls, structure):
"""Generate a Topology from the given ase Atoms object."""
return cls.from_data(raw_topology_from_ase(structure))
"""Generate a stoichiometry from the given ase Atoms object."""
return cls.from_data(raw_stoichiometry_from_ase(structure))

@base.data_access
def __str__(self):
Expand All @@ -43,7 +35,7 @@ def _repr_html_(self):

@base.data_access
def to_dict(self):
"""Read the topology and convert it to a dictionary.
"""Read the stoichiometry and convert it to a dictionary.
Returns
-------
Expand All @@ -59,7 +51,7 @@ def to_dict(self):

@base.data_access
def to_frame(self):
"""Convert the topology to a DataFrame
"""Convert the stoichiometry to a DataFrame
Returns
-------
Expand All @@ -70,7 +62,7 @@ def to_frame(self):

@base.data_access
def to_mdtraj(self):
"""Convert the topology to a mdtraj.Topology."""
"""Convert the stoichiometry to a mdtraj.Topology."""
df = self.to_frame()
df["serial"] = None
df["resSeq"] = 0
Expand All @@ -80,7 +72,7 @@ def to_mdtraj(self):

@base.data_access
def to_POSCAR(self, format_newline=""):
"""Generate the topology lines for the POSCAR file.
"""Generate the stoichiometry lines for the POSCAR file.
Parameters
----------
Expand Down Expand Up @@ -156,8 +148,8 @@ def _ion_types(self):
return (clean_string(ion_type) for ion_type in self._raw_data.ion_types)


def raw_topology_from_ase(structure):
"""Convert the given ase Atoms object to a raw.Topology."""
def raw_stoichiometry_from_ase(structure):
"""Convert the given ase Atoms object to a raw.Stoichiometry."""
number_ion_types = []
ion_types = []
for element in structure.symbols:
Expand All @@ -166,7 +158,7 @@ def raw_topology_from_ase(structure):
else:
ion_types.append(element)
number_ion_types.append(1)
return raw.Topology(number_ion_types, ion_types)
return raw.Stoichiometry(number_ion_types, ion_types)


def _merge_to_slice_if_possible(selections):
Expand Down
5 changes: 3 additions & 2 deletions src/py4vasp/_calculation/density.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class Density(base.Refinery, structure.Mixin, view.Mixin):
def __str__(self):
_raise_error_if_no_data(self._raw_data.charge)
grid = self._raw_data.charge.shape[1:]
topology = calculation._topology.from_data(self._raw_data.structure.topology)
raw_stoichiometry = self._raw_data.structure.stoichiometry
stoichiometry = calculation._stoichiometry.from_data(raw_stoichiometry)
if self._selection == "kinetic_energy":
name = "Kinetic energy"
elif self.is_nonpolarized():
Expand All @@ -93,7 +94,7 @@ def __str__(self):
else:
name = "Noncollinear"
return f"""{name} density:
structure: {pretty.pretty(topology)}
structure: {pretty.pretty(stoichiometry)}
grid: {grid[2]}, {grid[1]}, {grid[0]}"""

@documentation.format(
Expand Down
14 changes: 7 additions & 7 deletions src/py4vasp/_calculation/partial_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def stm_settings(self):
def __str__(self):
"""Return a string representation of the partial charge density."""
return f"""
{"spin polarized" if self._spin_polarized() else ""} partial charge density of {self._topology()}:
{"spin polarized" if self._spin_polarized() else ""} partial charge density of {self._stoichiometry()}:
on fine FFT grid: {self.grid()}
{"summed over all contributing bands" if 0 in self.bands() else f" separated for bands: {self.bands()}"}
{"summed over all contributing k-points" if 0 in self.kpoints() else f" separated for k-points: {self.kpoints()}"}
Expand Down Expand Up @@ -208,16 +208,16 @@ def _constant_current_stm(self, smoothed_charge, current, spin, stm_settings):
scan = z_grid[np.argmax(splines(z_grid) >= current, axis=-1)]
scan = z_step * (scan - scan.min())
spin_label = "both spin channels" if spin == "total" else f"spin {spin}"
topology = self._topology()
label = f"STM of {topology} for {spin_label} at constant current={current*1e9:.2f} nA"
stoichiometry = self._stoichiometry()
label = f"STM of {stoichiometry} for {spin_label} at constant current={current*1e9:.2f} nA"
return Contour(data=scan, lattice=self._get_stm_plane(), label=label)

def _constant_height_stm(self, smoothed_charge, tip_height, spin, stm_settings):
zz = self._z_index_for_height(tip_height + self._get_highest_z_coord())
height_scan = smoothed_charge[:, :, zz] * stm_settings.enhancement_factor
spin_label = "both spin channels" if spin == "total" else f"spin {spin}"
topology = self._topology()
label = f"STM of {topology} for {spin_label} at constant height={float(tip_height):.2f} Angstrom"
stoichiometry = self._stoichiometry()
label = f"STM of {stoichiometry} for {spin_label} at constant height={float(tip_height):.2f} Angstrom"
return Contour(data=height_scan, lattice=self._get_stm_plane(), label=label)

def _z_index_for_height(self, tip_height):
Expand All @@ -242,8 +242,8 @@ def _get_lowest_z_coord(self):
cart_coords = _get_sanitized_cartesian_positions(self._structure)
return np.min(cart_coords[:, 2])

def _topology(self):
return str(self._structure._topology())
def _stoichiometry(self):
return str(self._structure._stoichiometry())

def _estimate_vacuum(self):
_raise_error_if_vacuum_not_along_z(self._structure)
Expand Down
6 changes: 3 additions & 3 deletions src/py4vasp/_calculation/phonon.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ def selections(self):
"direction": ["x", "y", "z"],
}

def _topology(self):
return calculation._topology.from_data(self._raw_data.topology)
def _stoichiometry(self):
return calculation._stoichiometry.from_data(self._raw_data.stoichiometry)

def _init_atom_dict(self):
return {
key: value.indices
for key, value in self._topology().read().items()
for key, value in self._stoichiometry().read().items()
if key != select.all
}

Expand Down
2 changes: 1 addition & 1 deletion src/py4vasp/_calculation/phonon_band.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __str__(self):
return f"""phonon band data:
{self._raw_data.dispersion.eigenvalues.shape[0]} q-points
{self._raw_data.dispersion.eigenvalues.shape[1]} modes
{self._topology()}"""
{self._stoichiometry()}"""

@base.data_access
def to_dict(self):
Expand Down
6 changes: 3 additions & 3 deletions src/py4vasp/_calculation/phonon_dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class PhononDos(phonon.Mixin, base.Refinery, graph.Mixin):
@base.data_access
def __str__(self):
energies = self._raw_data.energies
topology = self._topology()
stoichiometry = self._stoichiometry()
return f"""phonon DOS:
[{energies[0]:0.2f}, {energies[-1]:0.2f}] mesh with {len(energies)} points
{3 * topology.number_atoms()} modes
{topology}"""
{3 * stoichiometry.number_atoms()} modes
{stoichiometry}"""

@base.data_access
@documentation.format(selection=phonon.selection_doc)
Expand Down
6 changes: 4 additions & 2 deletions src/py4vasp/_calculation/potential.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ def __str__(self):
description = "noncollinear potential:"
else:
description = "nonpolarized potential:"
topology = calculation._topology.from_data(self._raw_data.structure.topology)
structure = f"structure: {topology}"
stoichiometry = calculation._stoichiometry.from_data(
self._raw_data.structure.stoichiometry
)
structure = f"structure: {stoichiometry}"
grid = f"grid: {potential.shape[3]}, {potential.shape[2]}, {potential.shape[1]}"
available = "available: " + ", ".join(
kind for kind in VALID_KINDS if not self._get_potential(kind).is_none()
Expand Down
10 changes: 5 additions & 5 deletions src/py4vasp/_calculation/projector.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __str__(self):
if self._raw_data.orbital_types.is_none():
return "no projectors"
return f"""projectors:
atoms: {", ".join(self._topology().ion_types())}
atoms: {", ".join(self._stoichiometry().ion_types())}
orbitals: {", ".join(self._orbital_types())}"""

@base.data_access
Expand Down Expand Up @@ -190,8 +190,8 @@ def _raise_error_if_orbitals_missing(self):
message = "Projectors are not available, rerun Vasp setting LORBIT >= 10."
raise exception.IncorrectUsage(message)

def _topology(self):
return calculation._topology.from_data(self._raw_data.topology)
def _stoichiometry(self):
return calculation._stoichiometry.from_data(self._raw_data.stoichiometry)

def _init_dicts(self):
if self._raw_data.orbital_types.is_none():
Expand All @@ -204,7 +204,7 @@ def _init_dicts(self):
def _init_atom_dict(self):
return {
key: value.indices
for key, value in self._topology().read().items()
for key, value in self._stoichiometry().read().items()
if key != _select_all
}

Expand Down Expand Up @@ -347,7 +347,7 @@ def _init_dicts_old(self):
}

def _init_atom_dict_old(self):
return self._topology().read()
return self._stoichiometry().read()

def _init_orbital_dict_old(self):
self._raise_error_if_orbitals_missing()
Expand Down
28 changes: 14 additions & 14 deletions src/py4vasp/_calculation/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np

from py4vasp import calculation, exception, raw
from py4vasp._calculation import _topology, base, slice_
from py4vasp._calculation import _stoichiometry, base, slice_
from py4vasp._third_party import view
from py4vasp._util import documentation, import_, reader

Expand All @@ -23,14 +23,14 @@ class _Format:
end_table: str = ""
newline: str = ""

def comment_line(self, topology, step_string):
return f"{topology}{step_string}{self.newline}"
def comment_line(self, stoichiometry, step_string):
return f"{stoichiometry}{step_string}{self.newline}"

def scaling_factor(self, scale):
return f"{self._element_to_string(scale)}{self.newline}".lstrip()

def ion_list(self, topology):
return f"{topology.to_POSCAR(self.newline)}{self.newline}"
def ion_list(self, stoichiometry):
return f"{stoichiometry.to_POSCAR(self.newline)}{self.newline}"

def coordinate_system(self):
return f"Direct{self.newline}"
Expand Down Expand Up @@ -95,7 +95,7 @@ def from_POSCAR(cls, poscar, *, elements=None):
def from_ase(cls, structure):
"""Generate a structure from the ase Atoms class."""
structure = raw.Structure(
topology=_topology.raw_topology_from_ase(structure),
stoichiometry=_stoichiometry.raw_stoichiometry_from_ase(structure),
cell=_cell_from_ase(structure),
positions=structure.get_scaled_positions()[np.newaxis],
)
Expand All @@ -120,10 +120,10 @@ def _repr_html_(self):
def _create_repr(self, format_=_Format()):
step = self._get_last_step()
lines = (
format_.comment_line(self._topology(), self._step_string()),
format_.comment_line(self._stoichiometry(), self._step_string()),
format_.scaling_factor(self._scale()),
format_.vectors_to_table(self._raw_data.cell.lattice_vectors[step]),
format_.ion_list(self._topology()),
format_.ion_list(self._stoichiometry()),
format_.coordinate_system(),
format_.vectors_to_table(self._raw_data.positions[step]),
)
Expand All @@ -146,8 +146,8 @@ def to_dict(self):
return {
"lattice_vectors": self.lattice_vectors(),
"positions": self.positions(),
"elements": self._topology().elements(),
"names": self._topology().names(),
"elements": self._stoichiometry().elements(),
"names": self._stoichiometry().names(),
}

@base.data_access
Expand All @@ -170,7 +170,7 @@ def to_view(self, supercell=None):
"""
make_3d = lambda array: array if array.ndim == 3 else array[np.newaxis]
positions = make_3d(self.positions())
elements = np.tile(self._topology().elements(), (len(positions), 1))
elements = np.tile(self._stoichiometry().elements(), (len(positions), 1))
return view.View(
elements=elements,
lattice_vectors=make_3d(self.lattice_vectors()),
Expand Down Expand Up @@ -241,7 +241,7 @@ def to_mdtraj(self):
raise exception.NotImplemented(message)
data = self.to_dict()
xyz = data["positions"] @ data["lattice_vectors"] * self.A_to_nm
trajectory = mdtraj.Trajectory(xyz, self._topology().to_mdtraj())
trajectory = mdtraj.Trajectory(xyz, self._stoichiometry().to_mdtraj())
trajectory.unitcell_vectors = data["lattice_vectors"] * Structure.A_to_nm
return trajectory

Expand Down Expand Up @@ -356,8 +356,8 @@ def _parse_supercell(self, supercell):
)
raise exception.IncorrectUsage(message)

def _topology(self):
return calculation._topology.from_data(self._raw_data.topology)
def _stoichiometry(self):
return calculation._stoichiometry.from_data(self._raw_data.stoichiometry)

def _scale(self):
if isinstance(self._raw_data.cell.scale, np.float64):
Expand Down
Loading

0 comments on commit 68cea47

Please sign in to comment.