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