Skip to content

Commit

Permalink
Number of supercell is done only on request and for <= 30 sites.
Browse files Browse the repository at this point in the history
This is because the app may get stuck in evaluating this for large systems.
  • Loading branch information
mikibonacci committed Oct 4, 2024
1 parent 634dc6e commit 55df53f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 17 deletions.
59 changes: 45 additions & 14 deletions src/aiidalab_qe_vibroscopy/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def change_supercell(_=None):
)
for elem in [self._sc_x, self._sc_y, self._sc_z]:
elem.observe(change_supercell, names="value")
elem.observe(self._estimate_supercells, names="value")
elem.observe(self._activate_estimate_supercells, names="value")

self.supercell_selector = ipw.HBox(
children=[
Expand All @@ -179,7 +179,7 @@ def change_supercell(_=None):
self.supercell_hint_button = ipw.Button(
description="Size hint",
disabled=False,
width="100px",
layout=ipw.Layout(width="100px"),
button_style="info",
)
# supercell hint (15A lattice params)
Expand All @@ -195,11 +195,23 @@ def change_supercell(_=None):
# supercell reset reaction
self.supercell_reset_button.on_click(self._reset_supercell)

# Estimate supercell button
self.supercell_estimate_button = ipw.Button(
description="Estimate number of supercells ➡",
disabled=False,
layout=ipw.Layout(width="240px", display="none"),
button_style="info",
tooltip="Number of supercells for phonons calculations;\nwarning: for large systems, this may take some time.",
)
# supercell reset reaction
self.supercell_estimate_button.on_click(self._estimate_supercells)

# Estimate the number of supercells for frozen phonons.
self.supercell_number_estimator = ipw.HTML(
description="Number of supercells to be computed:",
value="0",
# description="Number of supercells:",
value="?",
style={"description_width": "initial"},
layout=ipw.Layout(display="none"),
)

## end supercell hint.
Expand All @@ -212,6 +224,7 @@ def change_supercell(_=None):
self.supercell_selector,
self.supercell_hint_button,
self.supercell_reset_button,
self.supercell_estimate_button, # I do it on request, as it can take long time.
self.supercell_number_estimator,
],
),
Expand All @@ -229,19 +242,17 @@ def change_supercell(_=None):
style={"description_width": "initial"},
layout={"width": "300px"},
)
self.symmetry_symprec.observe(self._estimate_supercells, "value")
self.symmetry_symprec.observe(self._activate_estimate_supercells, "value")

# reset supercell
self.symmetry_symprec_reset_button = ipw.Button(
description="Reset symprec",
disabled=False,
layout=ipw.Layout(width="150px"),
layout=ipw.Layout(width="125px"),
button_style="warning",
)
# supercell reset reaction
self.symmetry_symprec_reset_button.on_click(
lambda _: setattr(self.symmetry_symprec, "value", 1e-5)
)
self.symmetry_symprec_reset_button.on_click(self._reset_symprec)

self.children = [
ipw.VBox(
Expand Down Expand Up @@ -285,13 +296,23 @@ def change_supercell(_=None):

@tl.observe("input_structure")
def _update_input_structure(self, change):
if self.input_structure is not None:
if self.input_structure:
for direction, periodic in zip(
[self._sc_x, self._sc_y, self._sc_z], self.input_structure.pbc
):
direction.value = 2 if periodic else 1
direction.disabled = False if periodic else True

self.supercell_number_estimator.layout.display = (
"block" if len(self.input_structure.sites) <= 30 else "none"
)
self.supercell_estimate_button.layout.display = (
"block" if len(self.input_structure.sites) <= 30 else "none"
)
else:
self.supercell_number_estimator.layout.display = "none"
self.supercell_estimate_button.layout.display = "none"

def _display_supercell(self, change):
selected = change["new"]
if selected in [1, 3]:
Expand All @@ -308,19 +329,23 @@ def _suggest_supercell(self, _=None):
suggested_3D = 15 // np.array(s.cell.cellpar()[:3]) + 1

# if disabled, it means that it is a non-periodic direction.
# here we manually unobserve the `_estimate_supercells`, so it is faster
# here we manually unobserve the `_activate_estimate_supercells`, so it is faster
# and only compute when all the three directions are updated
self.block = True
for direction, suggested, original in zip(
[self._sc_x, self._sc_y, self._sc_z], suggested_3D, s.cell.cellpar()[:3]
):
direction.value = suggested if not direction.disabled else 1
self.block = False
self._estimate_supercells()
self._activate_estimate_supercells()
else:
return

@tl.observe("input_structure")
def _activate_estimate_supercells(self, _=None):
self.supercell_estimate_button.disabled = False
self.supercell_number_estimator.value = "?"

# @tl.observe("input_structure")
@disable_print
def _estimate_supercells(self, _=None):
"""_summary_
Expand Down Expand Up @@ -372,6 +397,7 @@ def _estimate_supercells(self, _=None):
supercells = preprocess_data.get_supercells_with_displacements()
"""
self.supercell_number_estimator.value = f"{len(supercells)}"
self.supercell_estimate_button.disabled = True

return

Expand All @@ -385,7 +411,12 @@ def _reset_supercell(self, _=None):
reset_supercell.append(2 if periodic else 1)
(self._sc_x.value, self._sc_y.value, self._sc_z.value) = reset_supercell
self.block = False
self._estimate_supercells()
self._activate_estimate_supercells()
return

def _reset_symprec(self, _=None):
self.symmetry_symprec.value = 1e-5
self._activate_estimate_supercells()
return

def get_panel_value(self):
Expand Down
25 changes: 22 additions & 3 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def test_x_settings(generate_structure_data):

@pytest.mark.usefixtures("sssp")
def test_supercell_number_estimator(generate_structure_data):
"""Test the settings of the vibroscopy app."""
"""Test the supercell_number_estimator setting of the vibroscopy app."""

from aiidalab_qe.app.configuration import ConfigureQeAppWorkChainStep

Expand All @@ -89,25 +89,29 @@ def test_supercell_number_estimator(generate_structure_data):
configure_step.workchain_settings.properties["vibronic"].run.value = True
parameters = configure_step.settings["vibronic"].get_panel_value()
assert parameters["supercell_selector"] == [2, 2, 2]
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "1"
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "?"
configure_step.settings["vibronic"]._suggest_supercell()
parameters = configure_step.settings["vibronic"].get_panel_value()
assert parameters["supercell_selector"] == [4, 4, 4]
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "?"
configure_step.settings["vibronic"]._estimate_supercells()
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "1"
configure_step.settings["vibronic"]._sc_x.value = 3
configure_step.settings["vibronic"]._sc_y.value = 2
configure_step.settings["vibronic"]._sc_z.value = 2
configure_step.settings["vibronic"]._estimate_supercells()
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "4"
configure_step.settings["vibronic"]._reset_supercell()
configure_step.settings["vibronic"]._sc_x.value = 2
configure_step.settings["vibronic"]._sc_y.value = 2
configure_step.settings["vibronic"]._sc_z.value = 2
configure_step.settings["vibronic"]._estimate_supercells()
assert configure_step.settings["vibronic"].supercell_number_estimator.value == "1"


@pytest.mark.usefixtures("sssp")
def test_symprec(generate_structure_data):
"""Test the settings of the vibroscopy app."""
"""Test the symprec setting of the vibroscopy app."""

from aiidalab_qe.app.configuration import ConfigureQeAppWorkChainStep

Expand All @@ -123,3 +127,18 @@ def test_symprec(generate_structure_data):
configure_step.settings["vibronic"].reset()
parameters = configure_step.settings["vibronic"].get_panel_value()
assert parameters["symmetry_symprec"] == 1e-5


@pytest.mark.usefixtures("sssp")
def test_supercell_estimator_button(generate_structure_data):
"""Test the settings of the button for the supercell number estimator."""

from aiidalab_qe.app.configuration import ConfigureQeAppWorkChainStep

configure_step = ConfigureQeAppWorkChainStep()
structure = generate_structure_data("silicon")
configure_step.input_structure = structure
configure_step.workchain_settings.properties["vibronic"].run.value = True
assert not configure_step.settings["vibronic"].supercell_estimate_button.disabled
configure_step.settings["vibronic"]._estimate_supercells()
assert configure_step.settings["vibronic"].supercell_estimate_button.disabled

0 comments on commit 55df53f

Please sign in to comment.