Line data Source code
1 : # SPDX-FileCopyrightText: 2025 PairInteraction Developers
2 : # SPDX-License-Identifier: LGPL-3.0-or-later
3 1 : from __future__ import annotations
4 :
5 1 : from typing import TYPE_CHECKING, Literal
6 :
7 1 : import numpy as np
8 1 : from PySide6.QtWidgets import (
9 : QLabel,
10 : )
11 :
12 1 : from pairinteraction_gui.config.base_config import BaseConfig
13 1 : from pairinteraction_gui.qobjects import Item, QnItemInt, RangeItem
14 :
15 : if TYPE_CHECKING:
16 : from pairinteraction_gui.page import OneAtomPage, TwoAtomsPage
17 :
18 :
19 1 : RangesKeys = Literal["Ex", "Ey", "Ez", "Bx", "By", "Bz", "Distance", "Angle"]
20 :
21 :
22 1 : class SystemConfig(BaseConfig):
23 : """Section for configuring the system parameters."""
24 :
25 1 : margin = (5, 15, 5, 5)
26 1 : spacing = 10
27 :
28 1 : title = "System"
29 1 : page: OneAtomPage | TwoAtomsPage
30 :
31 1 : def setupEField(self) -> None:
32 1 : efield_label = QLabel("<b>Electric field</b>")
33 1 : self.layout().addWidget(efield_label)
34 :
35 1 : self.Ex = RangeItem(self, "Ex", unit="V/cm", tooltip_label="electric field in x-direction")
36 1 : self.Ey = RangeItem(self, "Ey", unit="V/cm", tooltip_label="electric field in y-direction")
37 1 : self.Ez = RangeItem(self, "Ez", unit="V/cm", tooltip_label="electric field in z-direction")
38 :
39 1 : self.layout().addWidget(self.Ex)
40 1 : self.layout().addWidget(self.Ey)
41 1 : self.layout().addWidget(self.Ez)
42 :
43 1 : def setupBField(self) -> None:
44 1 : bfield_label = QLabel("<b>Magnetic field</b>")
45 1 : self.layout().addWidget(bfield_label)
46 :
47 1 : self.Bx = RangeItem(self, "Bx", unit="Gauss", tooltip_label="magnetic field in x-direction")
48 1 : self.By = RangeItem(self, "By", unit="Gauss", tooltip_label="magnetic field in y-direction")
49 1 : self.Bz = RangeItem(self, "Bz", unit="Gauss", tooltip_label="magnetic field in z-direction")
50 :
51 1 : self.layout().addWidget(self.Bx)
52 1 : self.layout().addWidget(self.By)
53 1 : self.layout().addWidget(self.Bz)
54 :
55 1 : def setupDiamagnetism(self) -> None:
56 1 : self.layout().addWidget(QLabel("<b>Diamagnetism</b>"))
57 1 : self.diamagnetism = Item(self, "Enable diamagnetism", checked=True)
58 1 : self.layout().addWidget(self.diamagnetism)
59 :
60 1 : def get_ranges_dict(self) -> dict[RangesKeys, list[float]]:
61 : """Return the electric and magnetic field ranges."""
62 1 : steps = self.page.calculation_config.steps.value()
63 1 : all_ranges = self._get_all_ranges()
64 1 : ranges_min_max: dict[str, tuple[float, float]] = {
65 : item.label.text(): item.values() for item in all_ranges if item.isChecked()
66 : }
67 1 : if len(ranges_min_max) == 0:
68 0 : ranges_min_max["Bz"] = (0, 0)
69 :
70 1 : return {key: np.linspace(value[0], value[1], steps).tolist() for key, value in ranges_min_max.items()} # type: ignore [misc]
71 :
72 1 : def _get_all_ranges(self) -> list[RangeItem]:
73 : """Return all range items."""
74 1 : return [self.Ex, self.Ey, self.Ez, self.Bx, self.By, self.Bz]
75 :
76 :
77 1 : class SystemConfigOneAtom(SystemConfig):
78 1 : page: OneAtomPage
79 :
80 1 : def setupWidget(self) -> None:
81 1 : self.setupEField()
82 1 : self.setupBField()
83 1 : self.setupDiamagnetism()
84 :
85 :
86 1 : class SystemConfigTwoAtoms(SystemConfig):
87 1 : page: TwoAtomsPage
88 :
89 1 : def setupWidget(self) -> None:
90 1 : self.setupEField()
91 1 : self.setupBField()
92 1 : self.setupDiamagnetism()
93 1 : self.setupDistance()
94 1 : self.setupAngle()
95 1 : self.setupOrder()
96 :
97 1 : def setupDistance(self) -> None:
98 1 : label = QLabel("<b>Distance</b>")
99 1 : self.layout().addWidget(label)
100 :
101 1 : self.distance = RangeItem(self, "Distance", vdefaults=(3, 8), vrange=(0, np.inf), unit="<span>μm</span>")
102 1 : self.layout().addWidget(self.distance)
103 :
104 1 : def setupAngle(self) -> None:
105 1 : label = QLabel("<b>Angle</b> (0° = z-axis, 90° = x-axis)")
106 1 : self.layout().addWidget(label)
107 :
108 1 : self.angle = RangeItem(self, "Angle", vdefaults=(0, 0), vrange=(0, 360), unit="degree")
109 1 : self.layout().addWidget(self.angle)
110 :
111 1 : def setupOrder(self) -> None:
112 1 : self.layout().addWidget(QLabel("<b>Multipole expansion order</b>"))
113 1 : self.order = QnItemInt(
114 : self,
115 : "Multipole order",
116 : vmin=3,
117 : vmax=5,
118 : vdefault=3,
119 : tooltip="Select the order of the multipole expansion",
120 : checkable=False,
121 : )
122 1 : self.layout().addWidget(self.order)
123 :
124 1 : def _get_all_ranges(self) -> list[RangeItem]:
125 : """Return all range items."""
126 1 : return [*super()._get_all_ranges(), self.distance, self.angle]
|