Skip to content

Commit

Permalink
Add help text
Browse files Browse the repository at this point in the history
  • Loading branch information
edan-bainglass committed Jan 9, 2025
1 parent f3dd922 commit 5984ed4
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,18 @@ def render(self):
if self.rendered:
return

self.description = ipw.HTML("""
<div style="margin-bottom: 5px;">
<b>Magnetization:</b>
<br>
Default magnetic moments correspond to theoretical values.
</div>
""")
self.header = ipw.HTML("<b>Magnetization:</b>")

self.unit = ipw.HTML(
value="µ<sub>B</sub>",
layout=ipw.Layout(margin="2px 2px 5px"),
)

self.magnetization_type_help = ipw.HTML()
ipw.dlink(
(self._model, "type_help"),
(self.magnetization_type_help, "value"),
)

self.magnetization_type = ipw.ToggleButtons(
style={
Expand Down Expand Up @@ -80,11 +85,19 @@ def render(self):
(self.tot_magnetization, "value"),
)

self.tot_magnetization_with_unit = ipw.HBox(
children=[
self.tot_magnetization,
self.unit,
],
layout=ipw.Layout(align_items="center"),
)

self.kind_moment_widgets = ipw.VBox()

self.container = ipw.VBox(
children=[
self.tot_magnetization,
self.tot_magnetization_with_unit,
]
)

Expand All @@ -99,12 +112,14 @@ def _on_input_structure_change(self, _):

def _on_electronic_type_change(self, _):
self._switch_widgets()
self._model.update_type_help()

def _on_spin_type_change(self, _):
self.refresh(specific="spin")

def _on_magnetization_type_change(self, _):
self._toggle_widgets()
self._model.update_type_help()

def _update(self, specific=""):
if self.updated:
Expand Down Expand Up @@ -152,7 +167,15 @@ def _build_kinds_widget(self):
],
)
self.links.append(link)
children.append(kind_moment_widget)
children.append(
ipw.HBox(
children=[
kind_moment_widget,
self.unit,
],
layout=ipw.Layout(align_items="center"),
)
)

self.kind_moment_widgets.children = children

Expand All @@ -162,23 +185,29 @@ def _switch_widgets(self):
if self._model.spin_type == "none":
children = []
else:
children = [self.description]
children = [self.header]
if self._model.electronic_type == "metal":
children.extend(
[
self.magnetization_type,
self.magnetization_type_help,
self.container,
]
)
else:
children.append(self.tot_magnetization)
children.extend(
[
self.magnetization_type_help,
self.tot_magnetization_with_unit,
],
)
self.children = children

def _toggle_widgets(self):
if self._model.spin_type == "none" or not self.rendered:
return
self.container.children = [
self.tot_magnetization
self.tot_magnetization_with_unit
if self._model.type == "tot_magnetization"
else self.kind_moment_widgets
]
67 changes: 50 additions & 17 deletions src/aiidalab_qe/app/configuration/advanced/magnetization/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,46 +30,79 @@ class MagnetizationConfigurationSettingsModel(
type_options = tl.List(
trait=tl.List(tl.Unicode()),
default_value=[
["Magnetic moments", "starting_magnetization"],
["Initial magnetic moments", "starting_magnetization"],
["Total magnetization", "tot_magnetization"],
],
)
type = tl.Unicode("starting_magnetization")
type_help = tl.Unicode("")
total = tl.Float(0.0)
moments = tl.Dict(
key_trait=tl.Unicode(), # kind name
value_trait=tl.Float(), # magnetic moment
default_value={},
)

_TYPE_HELP_TEMPLATE = """
<div style="line-height: 1.4; margin-bottom: 5px">
{content}
</div>
"""

def update(self, specific=""): # noqa: ARG002
if self.spin_type == "none" or not self.has_structure:
self._defaults["moments"] = {}
else:
try:
family = fetch_pseudo_family_by_label(self.family)
initial_guess = get_starting_magnetization(self.input_structure, family)
self._defaults["moments"] = {
kind.name: round(
initial_guess[kind.name]
* family.get_pseudo(kind.symbol).z_valence,
3,
)
for kind in self.input_structure.kinds
}
except NotExistent:
self._defaults["moments"] = {
kind_name: 0.0
for kind_name in self.input_structure.get_kind_names()
}
self.update_type_help()
self._update_default_moments()
with self.hold_trait_notifications():
self.moments = self._get_default_moments()

def update_type_help(self):
if self.electronic_type == "insulator" or self.type == "tot_magnetization":
self.type_help = self._TYPE_HELP_TEMPLATE.format(
content="""
Constrain the desired total electronic magnetization (difference
between majority and minority spin charge).
"""
)
else:
self.type_help = self._TYPE_HELP_TEMPLATE.format(
content="""
If a nonzero ground-state magnetization is expected, you
<strong>must</strong> assign a nonzero value to at least one atomic
type (note that the app might already provide tentative initial
values to chemical elements that typically display magnetism).
To simulate an antiferromagnetic state, first, if you have not
done so already, please use the atom tag editor <b>(Select
structure -> Edit structure -> Edit atom tags)</b> to mark atoms of
the species of interest as distinct by assigning each a different
integer tag. Once tagged, assign each an initial magnetic moments
of opposite sign.
"""
)

def reset(self):
with self.hold_trait_notifications():
self.type = self.traits()["type"].default_value
self.total = self.traits()["total"].default_value
self.moments = self._get_default_moments()

def _update_default_moments(self):
try:
family = fetch_pseudo_family_by_label(self.family)
initial_guess = get_starting_magnetization(self.input_structure, family)
self._defaults["moments"] = {
kind.name: round(
initial_guess[kind.name] * family.get_pseudo(kind.symbol).z_valence,
3,
)
for kind in self.input_structure.kinds
}
except NotExistent:
self._defaults["moments"] = {
kind_name: 0.0 for kind_name in self.input_structure.get_kind_names()
}

def _get_default_moments(self):
return deepcopy(self._defaults.get("moments", {}))

0 comments on commit 5984ed4

Please sign in to comment.