aton 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {aton-0.2.1 → aton-0.2.2}/PKG-INFO +1 -1
  2. {aton-0.2.1 → aton-0.2.2}/aton/_version.py +1 -1
  3. {aton-0.2.1 → aton-0.2.2}/aton/interface/__init__.py +1 -1
  4. {aton-0.2.1 → aton-0.2.2}/aton/phys/atoms.py +1 -1
  5. {aton-0.2.1 → aton-0.2.2}/aton/phys/functions.py +1 -1
  6. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/plot.py +31 -8
  7. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/system.py +64 -29
  8. {aton-0.2.1 → aton-0.2.2}/aton.egg-info/PKG-INFO +1 -1
  9. {aton-0.2.1 → aton-0.2.2}/tests/test_qrotor.py +20 -0
  10. {aton-0.2.1 → aton-0.2.2}/LICENSE +0 -0
  11. {aton-0.2.1 → aton-0.2.2}/README.md +0 -0
  12. {aton-0.2.1 → aton-0.2.2}/aton/__init__.py +0 -0
  13. {aton-0.2.1 → aton-0.2.2}/aton/interface/castep.py +0 -0
  14. {aton-0.2.1 → aton-0.2.2}/aton/interface/phonopy.py +0 -0
  15. {aton-0.2.1 → aton-0.2.2}/aton/interface/qe.py +0 -0
  16. {aton-0.2.1 → aton-0.2.2}/aton/interface/slurm.py +0 -0
  17. {aton-0.2.1 → aton-0.2.2}/aton/phys/__init__.py +0 -0
  18. {aton-0.2.1 → aton-0.2.2}/aton/phys/units.py +0 -0
  19. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/__init__.py +0 -0
  20. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/constants.py +0 -0
  21. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/potential.py +0 -0
  22. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/rotate.py +0 -0
  23. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/solve.py +0 -0
  24. {aton-0.2.1 → aton-0.2.2}/aton/qrotor/systems.py +0 -0
  25. {aton-0.2.1 → aton-0.2.2}/aton/spx/__init__.py +0 -0
  26. {aton-0.2.1 → aton-0.2.2}/aton/spx/classes.py +0 -0
  27. {aton-0.2.1 → aton-0.2.2}/aton/spx/deuterium.py +0 -0
  28. {aton-0.2.1 → aton-0.2.2}/aton/spx/fit.py +0 -0
  29. {aton-0.2.1 → aton-0.2.2}/aton/spx/normalize.py +0 -0
  30. {aton-0.2.1 → aton-0.2.2}/aton/spx/plot.py +0 -0
  31. {aton-0.2.1 → aton-0.2.2}/aton/spx/samples.py +0 -0
  32. {aton-0.2.1 → aton-0.2.2}/aton/st/__init__.py +0 -0
  33. {aton-0.2.1 → aton-0.2.2}/aton/st/alias.py +0 -0
  34. {aton-0.2.1 → aton-0.2.2}/aton/st/call.py +0 -0
  35. {aton-0.2.1 → aton-0.2.2}/aton/st/file.py +0 -0
  36. {aton-0.2.1 → aton-0.2.2}/aton/txt/__init__.py +0 -0
  37. {aton-0.2.1 → aton-0.2.2}/aton/txt/edit.py +0 -0
  38. {aton-0.2.1 → aton-0.2.2}/aton/txt/extract.py +0 -0
  39. {aton-0.2.1 → aton-0.2.2}/aton/txt/find.py +0 -0
  40. {aton-0.2.1 → aton-0.2.2}/aton.egg-info/SOURCES.txt +0 -0
  41. {aton-0.2.1 → aton-0.2.2}/aton.egg-info/dependency_links.txt +0 -0
  42. {aton-0.2.1 → aton-0.2.2}/aton.egg-info/requires.txt +0 -0
  43. {aton-0.2.1 → aton-0.2.2}/aton.egg-info/top_level.txt +0 -0
  44. {aton-0.2.1 → aton-0.2.2}/setup.cfg +0 -0
  45. {aton-0.2.1 → aton-0.2.2}/setup.py +0 -0
  46. {aton-0.2.1 → aton-0.2.2}/tests/__init__.py +0 -0
  47. {aton-0.2.1 → aton-0.2.2}/tests/test_edit.py +0 -0
  48. {aton-0.2.1 → aton-0.2.2}/tests/test_extract.py +0 -0
  49. {aton-0.2.1 → aton-0.2.2}/tests/test_file.py +0 -0
  50. {aton-0.2.1 → aton-0.2.2}/tests/test_find.py +0 -0
  51. {aton-0.2.1 → aton-0.2.2}/tests/test_qe.py +0 -0
  52. {aton-0.2.1 → aton-0.2.2}/tests/test_spx.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aton
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: The Ab-iniTiO & Neutron research toolbox, or ATON, provides powerful and comprehensive tools for cutting-edge materials research, focused on (but not limited to) neutron science.
5
5
  Author: Pablo Gila-Herranz
6
6
  Author-email: pgila001@ikasle.ehu.eus
@@ -10,5 +10,5 @@ https://semver.org/
10
10
 
11
11
  """
12
12
 
13
- __version__ = 'v0.2.1'
13
+ __version__ = 'v0.2.2'
14
14
 
@@ -33,7 +33,7 @@ To modify values from an input file,
33
33
  ```python
34
34
  from aton.interface import qe
35
35
  # Add a hydrogen atom to a specific position
36
- qe.add_atom('H 0.10 0.20 0.30')
36
+ qe.add_atom('relax.in', 'H 0.10 0.20 0.30')
37
37
  # Set the input ecutwfc value
38
38
  qe.set_value('relax.in', 'ecutwfc', 60.0)
39
39
  ```
@@ -22,7 +22,7 @@ The `atoms` dictionary can be loaded directly as `aton.phys.atoms`.
22
22
  ```python
23
23
  from aton import phys
24
24
  aluminium_neutron_cross_section = phys.atoms['Al'].cross_section # 1.503
25
- He4_mass = phys.atoms['H'].isotope[4].mass # 4.0026032497
25
+ He4_mass = phys.atoms['He'].isotope[4].mass # 4.0026032497
26
26
  ```
27
27
 
28
28
  ---
@@ -62,7 +62,7 @@ def export_atoms(
62
62
  "```python\n"
63
63
  "from aton import phys\n"
64
64
  "aluminium_neutron_cross_section = phys.atoms['Al'].cross_section # 1.503\n"
65
- "He4_mass = phys.atoms['H'].isotope[4].mass # 4.0026032497\n\n"
65
+ "He4_mass = phys.atoms['He'].isotope[4].mass # 4.0026032497\n\n"
66
66
  "```\n\n"
67
67
  "---\n"
68
68
  "'''\n\n\n"
@@ -25,7 +25,12 @@ import numpy as np
25
25
  from copy import deepcopy
26
26
 
27
27
 
28
- def potential(data, title:str=None, marker='', linestyle='-') -> None:
28
+ def potential(
29
+ data,
30
+ title:str=None,
31
+ marker='',
32
+ linestyle='-',
33
+ ) -> None:
29
34
  """Plot the potential values of `data` (System object, or list of systems).
30
35
 
31
36
  Title can be customized with `title`.
@@ -52,7 +57,7 @@ def potential(data, title:str=None, marker='', linestyle='-') -> None:
52
57
  plt.title(title_str)
53
58
  plt.xlabel('Angle / rad')
54
59
  plt.ylabel('Potential energy / meV')
55
- plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], ['0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
60
+ plt.xticks([-2*np.pi, -3*np.pi/2, -np.pi, -np.pi/2, 0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], [r'$-2\pi$', r'$-\frac{3\pi}{2}$', r'$-\pi$', r'$-\frac{\pi}{2}$', '0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
56
61
 
57
62
  for i, s in enumerate(system):
58
63
  plt.plot(s.grid, s.potential_values, marker=marker[i], linestyle=linestyle[i], label=s.comment)
@@ -63,7 +68,10 @@ def potential(data, title:str=None, marker='', linestyle='-') -> None:
63
68
  plt.show()
64
69
 
65
70
 
66
- def energies(data, title:str=None) -> None:
71
+ def energies(
72
+ data,
73
+ title:str=None,
74
+ ) -> None:
67
75
  """Plot the eigenvalues of `data` (System or a list of System objects)."""
68
76
  if isinstance(data, System):
69
77
  var = [data]
@@ -85,7 +93,7 @@ def energies(data, title:str=None) -> None:
85
93
  plt.xlabel(xlabel_text)
86
94
  plt.ylabel(ylabel_text)
87
95
  plt.title(title)
88
- plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], ['0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
96
+ plt.xticks([-2*np.pi, -3*np.pi/2, -np.pi, -np.pi/2, 0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], [r'$-2\pi$', r'$-\frac{3\pi}{2}$', r'$-\pi$', r'$-\frac{\pi}{2}$', '0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
89
97
 
90
98
  unique_potentials = []
91
99
  unique_groups = []
@@ -119,7 +127,12 @@ def energies(data, title:str=None) -> None:
119
127
  plt.show()
120
128
 
121
129
 
122
- def reduced_energies(data:list, title:str=None, values:list=[], legend:list=[]) -> None:
130
+ def reduced_energies(
131
+ data:list,
132
+ title:str=None,
133
+ values:list=[],
134
+ legend:list=[],
135
+ ) -> None:
123
136
  """Plots the reduced energy of the system E/B vs the reduced potential energy V/B.
124
137
 
125
138
  Takes a `data` list of System objects as input.
@@ -167,7 +180,14 @@ def reduced_energies(data:list, title:str=None, values:list=[], legend:list=[])
167
180
  plt.show()
168
181
 
169
182
 
170
- def wavefunction(system:System, title:str=None, square:bool=True, levels=[0, 1, 2], overlap=False):
183
+ def wavefunction(
184
+ system:System,
185
+ title:str=None,
186
+ square:bool=True,
187
+ levels=[0, 1, 2],
188
+ overlap=False,
189
+ yticks:bool=False,
190
+ ) -> None:
171
191
  """Plot the wavefunction of a `system` for the specified `levels`.
172
192
 
173
193
  Wavefunctions are squared by default, showing the probabilities;
@@ -181,6 +201,8 @@ def wavefunction(system:System, title:str=None, square:bool=True, levels=[0, 1,
181
201
  but note that this overlap is limited by the number of System.E_levels,
182
202
  that must be specified before solving the system.
183
203
  Setting `overlap` will ignore the `levels` argument.
204
+
205
+ Set `yticks = True` to plot the wavefunction yticks.
184
206
  """
185
207
  data = deepcopy(system)
186
208
  eigenvectors = data.eigenvectors
@@ -190,10 +212,11 @@ def wavefunction(system:System, title:str=None, square:bool=True, levels=[0, 1,
190
212
  plt.title(title)
191
213
  ax1.set_xlabel('Angle / radians')
192
214
  ax1.set_ylabel('Potential / meV')
193
- ax1.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], ['0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
215
+ ax1.set_xticks([-2*np.pi, -3*np.pi/2, -np.pi, -np.pi/2, 0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi], [r'$-2\pi$', r'$-\frac{3\pi}{2}$', r'$-\pi$', r'$-\frac{\pi}{2}$', '0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])
194
216
  ax1.plot(data.grid, data.potential_values, color='blue', linestyle='-')
195
217
  ax2 = ax1.twinx()
196
- ax2.set_yticks([])
218
+ if not yticks:
219
+ ax2.set_yticks([])
197
220
  ax2.set_ylabel('Squared wavefunction' if square else 'Wavefunction')
198
221
 
199
222
  # Set levels list
@@ -91,23 +91,52 @@ class System:
91
91
  self.runtime: float = None
92
92
  """Time taken to solve the eigenvalues."""
93
93
 
94
- def summary(self):
95
- return {
96
- 'version': self.version,
97
- 'comment': self.comment,
98
- 'group': self.group,
99
- 'gridsize': self.gridsize,
100
- 'B': self.B,
101
- 'potential_name': self.potential_name,
102
- 'potential_constants': self.potential_constants.tolist() if isinstance(self.potential_constants, np.ndarray) else self.potential_constants,
103
- 'potential_offset': self.corrected_potential_offset,
104
- 'potential_min': self.potential_min,
105
- 'potential_max': self.potential_max,
106
- 'eigenvalues': self.eigenvalues.tolist() if isinstance(self.eigenvalues, np.ndarray) else self.eigenvalues,
107
- 'energy_barrier': self.energy_barrier,
108
- 'transitions': self.transitions,
109
- 'runtime': self.runtime,
110
- }
94
+ def solve(self, new_gridsize:int=None):
95
+ """Solves the quantum system.
96
+
97
+ The potential can be interpolated to a `new_gridsize`.
98
+
99
+ Same as running `aton.qrotor.solve.energies(System)`.
100
+ """
101
+ from .solve import energies
102
+ if new_gridsize:
103
+ self.gridsize = new_gridsize
104
+ return energies(self)
105
+
106
+ def change_phase(self, phase:float, calculate:bool=True):
107
+ """Apply a phase shift to the grid and potential values.
108
+
109
+ The `phase` should be a multiple of $\pi$ (e.g., 3/2 for $3\pi/2$).
110
+ The resulting grid will be expressed between $-2\pi$ and $2\pi$.
111
+
112
+ The System is solved immediately after the phase change.
113
+ This last step ensures that all eigenvalues and wavefunctions are correct.
114
+ You can override this step with `calculate = False`,
115
+ but remember to solve the System later!
116
+ """
117
+ if not any(self.potential_values) or not any(self.grid):
118
+ raise ValueError("System.potential_values and System.grid must be set before applying a phase shift.")
119
+ # Normalise the phase between 0 and 2
120
+ if abs(phase) >= 2:
121
+ phase = phase % 2
122
+ while phase < 0:
123
+ phase = phase + 2
124
+ # Shift the grid, between -2pi and 2pi
125
+ self.grid = (self.grid + (phase * np.pi))
126
+ # Apply the phase shift to potential values
127
+ phase_points = int((phase / 2) * self.gridsize)
128
+ self.potential_values = np.roll(self.potential_values, phase_points)
129
+ # Check that the grid is still within -2pi and 2pi, otherwise normalise it for a final time
130
+ while self.grid[0] <= (-2 * np.pi + 0.1): # With a small tolerance
131
+ self.grid = self.grid + 2 * np.pi
132
+ print('plus 2')
133
+ while self.grid[-1] >= 2.5 * np.pi: # It was not a problem until reaching 5/2 pi
134
+ self.grid = self.grid -2 * np.pi
135
+ print('minus 2')
136
+ print(f'Potential shifted by {phase}π')
137
+ if calculate:
138
+ self.solve()
139
+ return self
111
140
 
112
141
  def set_grid(self, gridsize:int=None):
113
142
  """Sets the `System.grid` to the specified `gridsize` from 0 to $2\\pi$.
@@ -163,18 +192,6 @@ class System:
163
192
  return self
164
193
  self.group = group # No match was found
165
194
  return self
166
-
167
- def solve(self, new_gridsize:int=None):
168
- """Solves the quantum system.
169
-
170
- The potential can be interpolated to a `new_gridsize`.
171
-
172
- Same as running `aton.qrotor.solve.energies(System)`.
173
- """
174
- from .solve import energies
175
- if new_gridsize:
176
- self.gridsize = new_gridsize
177
- return energies(self)
178
195
 
179
196
  def reduce_size(self):
180
197
  """Discard data that takes too much space,
@@ -184,3 +201,21 @@ class System:
184
201
  self.grid = []
185
202
  return self
186
203
 
204
+ def summary(self):
205
+ return {
206
+ 'version': self.version,
207
+ 'comment': self.comment,
208
+ 'group': self.group,
209
+ 'gridsize': self.gridsize,
210
+ 'B': self.B,
211
+ 'potential_name': self.potential_name,
212
+ 'potential_constants': self.potential_constants.tolist() if isinstance(self.potential_constants, np.ndarray) else self.potential_constants,
213
+ 'potential_offset': self.potential_offset,
214
+ 'potential_min': self.potential_min,
215
+ 'potential_max': self.potential_max,
216
+ 'eigenvalues': self.eigenvalues.tolist() if isinstance(self.eigenvalues, np.ndarray) else self.eigenvalues,
217
+ 'energy_barrier': self.energy_barrier,
218
+ 'transitions': self.transitions,
219
+ 'runtime': self.runtime,
220
+ }
221
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aton
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: The Ab-iniTiO & Neutron research toolbox, or ATON, provides powerful and comprehensive tools for cutting-edge materials research, focused on (but not limited to) neutron science.
5
5
  Author: Pablo Gila-Herranz
6
6
  Author-email: pgila001@ikasle.ehu.eus
@@ -2,6 +2,7 @@ import aton.qrotor as qr
2
2
  import aton.interface as interface
3
3
  import aton.txt.extract as extract
4
4
  import aton.st.file as file
5
+ import numpy as np
5
6
 
6
7
 
7
8
  folder = 'tests/samples/'
@@ -68,3 +69,22 @@ def test_solve_zero():
68
69
  assert round(system.eigenvalues[7], 2) == 16.0
69
70
  assert round(system.eigenvalues[8], 2) == 16.0
70
71
 
72
+
73
+ def test_phase():
74
+ sys = qr.System()
75
+ sys.B = 1.0
76
+ sys.potential_name = 'cos'
77
+ sys.gridsize = 10000
78
+ sys.solve()
79
+ # plus pi/2, which will be -3pi/2
80
+ sys.change_phase(0.5)
81
+ assert round(sys.grid[0], 2) == round(-np.pi * 3/2, 2)
82
+ # The first potential value should be 0,
83
+ # but remember that the potential offset is corrected
84
+ # so it should be half potential_max, so 1.0/2
85
+ assert round(sys.potential_values[0], 2) == 0.5
86
+ # minus pi, which will become -pi/2
87
+ sys.change_phase(-1)
88
+ assert round(sys.grid[0], 2) == round(-np.pi/2, 2)
89
+ assert round(sys.potential_values[0], 2) == 0.5
90
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes