Skip to content

Commit

Permalink
Implement writing of single step Structure
Browse files Browse the repository at this point in the history
Also write scaling factor to POSCAR file
  • Loading branch information
martin-schlipf committed Aug 31, 2023
1 parent 6edc039 commit 0387521
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
19 changes: 14 additions & 5 deletions src/py4vasp/_data/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class _Format:
def comment_line(self, topology, step_string):
return f"{topology}{step_string}{self.newline}"

def scaling_factor(self):
return f"1.0{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}"
Expand Down Expand Up @@ -98,10 +98,10 @@ def _repr_html_(self):
return self._create_repr(format_)

def _create_repr(self, format_=_Format()):
step = self._last_step_in_slice
step = self._get_last_step()
lines = (
format_.comment_line(self._topology(), self._step_string()),
format_.scaling_factor(),
format_.scaling_factor(self._raw_data.cell.scale),
format_.vectors_to_table(self._raw_data.cell.lattice_vectors[step]),
format_.ion_list(self._topology()),
format_.coordinate_system(),
Expand Down Expand Up @@ -288,7 +288,7 @@ def _topology(self):

def _lattice_vectors(self):
lattice_vectors = _LatticeVectors(self._raw_data.cell.lattice_vectors)
return lattice_vectors[self._get_steps()]
return self._raw_data.cell.scale * lattice_vectors[self._get_steps()]

def _positions(self):
return self._raw_data.positions[self._get_steps()]
Expand All @@ -306,6 +306,9 @@ def _viewer_from_trajectory(self):
def _get_steps(self):
return self._steps if self._is_trajectory else ()

def _get_last_step(self):
return self._last_step_in_slice if self._is_trajectory else ()

def _step_string(self):
if self._is_slice:
range_ = range(len(self._raw_data.positions))[self._steps]
Expand All @@ -315,6 +318,12 @@ def _step_string(self):
else:
return f" (step {self._steps + 1})"

def __getitem__(self, steps):
if not self._is_trajectory:
message = "The structure is not a Trajectory so accessing individual elements is not allowed."
raise exception.IncorrectUsage(message)
return super().__getitem__(steps)

@property
def _is_trajectory(self):
return self._raw_data.positions.ndim == 3
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ def _Sr2TiO4_cell():
[-0.839055341042049, -0.367478859090843, 0.401180037874301],
]
return raw.Cell(
lattice_vectors=scale * np.array(number_steps * [lattice_vectors]), scale=scale
lattice_vectors=np.array(number_steps * [lattice_vectors]), scale=scale
)


Expand Down
48 changes: 37 additions & 11 deletions tests/data/test_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

REF_POSCAR = """\
Sr2TiO4
1.0
6.9229000000000003 0.0000000000000000 0.0000000000000000
4.6945030167999979 5.0880434191000035 0.0000000000000000
-5.8086962205000017 -2.5440193935999971 2.7773292841999986
6.9229000000000003
1.0000000000000000 0.0000000000000000 0.0000000000000000
0.6781122097386930 0.7349583872510080 0.0000000000000000
-0.8390553410420490 -0.3674788590908430 0.4011800378743010
Sr Ti O
2 1 4
Direct
Expand All @@ -29,11 +29,11 @@

REF_HTML = """\
Sr2TiO4<br>
1.0<br>
6.9229000000000003<br>
<table>
<tr><td> 6.9229000000000003</td><td> 0.0000000000000000</td><td> 0.0000000000000000</td></tr>
<tr><td> 4.6945030167999979</td><td> 5.0880434191000035</td><td> 0.0000000000000000</td></tr>
<tr><td> -5.8086962205000017</td><td> -2.5440193935999971</td><td> 2.7773292841999986</td></tr>
<tr><td> 1.0000000000000000</td><td> 0.0000000000000000</td><td> 0.0000000000000000</td></tr>
<tr><td> 0.6781122097386930</td><td> 0.7349583872510080</td><td> 0.0000000000000000</td></tr>
<tr><td> -0.8390553410420490</td><td> -0.3674788590908430</td><td> 0.4011800378743010</td></tr>
</table>
Sr Ti O<br>
2 1 4<br>
Expand All @@ -48,6 +48,22 @@
<tr><td> 0.0000000000000000</td><td> 0.5000000000000000</td><td> 0.5000000000000000</td></tr>
</table>"""

REF_Ca3AsBr3 = """Ca3AsBr3
5.9299999999999997
1.0000000000000000 0.0000000000000000 0.0000000000000000
0.0000000000000000 1.0000000000000000 0.0000000000000000
0.0000000000000000 0.0000000000000000 1.0000000000000000
Ca As Br Ca Br
2 1 1 1 2
Direct
0.5000000000000000 0.0000000000000000 0.0000000000000000
0.0000000000000000 0.5000000000000000 0.0000000000000000
0.0000000000000000 0.0000000000000000 0.0000000000000000
0.0000000000000000 0.5000000000000000 0.5000000000000000
0.0000000000000000 0.0000000000000000 0.5000000000000000
0.5000000000000000 0.0000000000000000 0.5000000000000000
0.5000000000000000 0.5000000000000000 0.0000000000000000"""


@pytest.fixture
def Sr2TiO4(raw_data):
Expand All @@ -67,7 +83,8 @@ def Ca3AsBr3(raw_data):
def make_structure(raw_structure):
structure = Structure.from_data(raw_structure)
structure.ref = types.SimpleNamespace()
structure.ref.lattice_vectors = raw_structure.cell.lattice_vectors
cell = raw_structure.cell
structure.ref.lattice_vectors = cell.scale * cell.lattice_vectors
structure.ref.positions = raw_structure.positions
return structure

Expand Down Expand Up @@ -107,12 +124,13 @@ def test_read_Ca3AsBr3(Ca3AsBr3, Assert):
assert actual["names"] == ["Ca_1", "Ca_2", "As_1", "Br_1", "Ca_3", "Br_2", "Br_3"]


def test_to_poscar(Sr2TiO4):
def test_to_poscar(Sr2TiO4, Ca3AsBr3):
assert Sr2TiO4.to_POSCAR() == REF_POSCAR
assert Sr2TiO4[0].to_POSCAR() == REF_POSCAR.replace("Sr2TiO4", "Sr2TiO4 (step 1)")
for steps in (slice(None), slice(1, 3)):
with pytest.raises(exception.NotImplemented):
Sr2TiO4[steps].to_POSCAR()
assert Ca3AsBr3.to_POSCAR() == REF_Ca3AsBr3


def test_from_poscar(Sr2TiO4, Assert, not_core):
Expand Down Expand Up @@ -303,11 +321,13 @@ def check_plot_structure(structure):
cell.assert_called_once()


def test_incorrect_step(Sr2TiO4):
def test_incorrect_step(Sr2TiO4, Ca3AsBr3):
with pytest.raises(exception.IncorrectUsage):
Sr2TiO4[100].read()
with pytest.raises(exception.IncorrectUsage):
Sr2TiO4[[0, 1]].read()
with pytest.raises(exception.IncorrectUsage):
Ca3AsBr3[0]


def test_print_final(Sr2TiO4, format_):
Expand All @@ -319,6 +339,7 @@ def test_print_specific(Sr2TiO4, format_):
actual, _ = format_(Sr2TiO4[0])
ref_plain = REF_POSCAR.replace("Sr2TiO4", "Sr2TiO4 (step 1)")
ref_html = REF_HTML.replace("Sr2TiO4", "Sr2TiO4 (step 1)")
assert actual["text/plain"] == ref_plain
assert actual == {"text/plain": ref_plain, "text/html": ref_html}


Expand All @@ -329,6 +350,11 @@ def test_print_trajectory(Sr2TiO4, format_):
assert actual == {"text/plain": ref_plain, "text/html": ref_html}


def test_print_Ca3AsBr3(Ca3AsBr3, format_):
actual, _ = format_(Ca3AsBr3)
assert actual["text/plain"] == REF_Ca3AsBr3


def test_factory_methods(raw_data, check_factory_methods):
data = raw_data.structure("Sr2TiO4")
check_factory_methods(Structure, data)

0 comments on commit 0387521

Please sign in to comment.