asd-gui 1.3.0__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.
- asd_gui-1.3.0/ASD_GUI/ASD_GUI.py +56 -0
- asd_gui-1.3.0/ASD_GUI/Input_Creator/ASDInputAux.py +314 -0
- asd_gui-1.3.0/ASD_GUI/Input_Creator/ASDInputGen.py +843 -0
- asd_gui-1.3.0/ASD_GUI/Input_Creator/__init__.py +0 -0
- asd_gui-1.3.0/ASD_GUI/PLOT/ASDPlots2D.py +255 -0
- asd_gui-1.3.0/ASD_GUI/PLOT/ASDPlotsReading.py +516 -0
- asd_gui-1.3.0/ASD_GUI/PLOT/__init__.py +0 -0
- asd_gui-1.3.0/ASD_GUI/TemplateStructurePic/pp_b2.png +0 -0
- asd_gui-1.3.0/ASD_GUI/TemplateStructurePic/pp_bcc.png +0 -0
- asd_gui-1.3.0/ASD_GUI/TemplateStructurePic/pp_fcc.png +0 -0
- asd_gui-1.3.0/ASD_GUI/TemplateStructurePic/pp_sc.png +0 -0
- asd_gui-1.3.0/ASD_GUI/UI/ASDInputWindows.py +927 -0
- asd_gui-1.3.0/ASD_GUI/UI/ASDMenuToolbar.py +718 -0
- asd_gui-1.3.0/ASD_GUI/UI/ASDUIDriver.py +1846 -0
- asd_gui-1.3.0/ASD_GUI/UI/ASD_Viz.ui +8966 -0
- asd_gui-1.3.0/ASD_GUI/UI/Error_Msg.ui +60 -0
- asd_gui-1.3.0/ASD_GUI/UI/Info_Msg.ui +60 -0
- asd_gui-1.3.0/ASD_GUI/UI/InitPhase_Creator.ui +248 -0
- asd_gui-1.3.0/ASD_GUI/UI/Momfile_Creator.ui +173 -0
- asd_gui-1.3.0/ASD_GUI/UI/Posfile_Creator.ui +375 -0
- asd_gui-1.3.0/ASD_GUI/UI/Restart_Creator.ui +904 -0
- asd_gui-1.3.0/ASD_GUI/UI/__init__.py +1 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKEneActors.py +357 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKGenActors.py +285 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKMomActors.py +500 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKNeighActors.py +370 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKReading.py +905 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/ASDVTKVizOptions.py +1333 -0
- asd_gui-1.3.0/ASD_GUI/VTK_Viz/__init__.py +1 -0
- asd_gui-1.3.0/ASD_GUI/__init__.py +0 -0
- asd_gui-1.3.0/MANIFEST.in +2 -0
- asd_gui-1.3.0/PKG-INFO +8 -0
- asd_gui-1.3.0/README.md +86 -0
- asd_gui-1.3.0/asd_gui.egg-info/PKG-INFO +8 -0
- asd_gui-1.3.0/asd_gui.egg-info/SOURCES.txt +39 -0
- asd_gui-1.3.0/asd_gui.egg-info/dependency_links.txt +1 -0
- asd_gui-1.3.0/asd_gui.egg-info/requires.txt +7 -0
- asd_gui-1.3.0/asd_gui.egg-info/top_level.txt +1 -0
- asd_gui-1.3.0/bin/asd_gui +62 -0
- asd_gui-1.3.0/setup.cfg +4 -0
- asd_gui-1.3.0/setup.py +27 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
""" @package ASD_GUI
|
|
2
|
+
Main executable for the UppASD GUI. The GUI is designed to allow for pre-processing
|
|
3
|
+
and post-processing activities with ease.
|
|
4
|
+
The GUI has the following capabilities
|
|
5
|
+
- VTK Visualization:
|
|
6
|
+
- Restart files (Final snapshot of a simulation)
|
|
7
|
+
- Moment files (Animation/video rendering of the data)
|
|
8
|
+
- If one has a KMC file one can see the movement of the KMC particles.
|
|
9
|
+
- If there is a cluster file one can see the location of the impurity cluster atoms.
|
|
10
|
+
- Neighbour setup
|
|
11
|
+
- Allows to see the Heisenberg exchange neighbours in real space, with colormapping
|
|
12
|
+
being determined by the magnitude of the interactions.
|
|
13
|
+
- Plot the DMI vectors between neighbours, with the colormap being determined
|
|
14
|
+
by the magnitude of the vectors.
|
|
15
|
+
- Site dependent energy, allowing for time-dependent rendering.
|
|
16
|
+
- It also includes several general actors, such a colorbars, axes and time step visualization
|
|
17
|
+
- It allows for on the fly modification of the glyphs for the magnetization,
|
|
18
|
+
visualization of the magnetization density.
|
|
19
|
+
- On the fly change of the size of the magnetization glyphs.
|
|
20
|
+
- Matplotlib Plots:
|
|
21
|
+
- Spin-spin correlation function.
|
|
22
|
+
- Plots the colormap when the dynamical correlation function is used.
|
|
23
|
+
- Plot the AMS obtained from linear spin wave theory.
|
|
24
|
+
- Magnetization averages.
|
|
25
|
+
- One can turn on/off component at will.
|
|
26
|
+
- Single atom trajectories in the unit sphere.
|
|
27
|
+
- Input file generation
|
|
28
|
+
- One can setup the basic features to create the inpsd.dat
|
|
29
|
+
- Visual creation of the posfile and momfile
|
|
30
|
+
- Creation of magnetic configurations for the restarfiles
|
|
31
|
+
- Domain walls.
|
|
32
|
+
- Skyrmions.
|
|
33
|
+
- Helical spin spirals.
|
|
34
|
+
Author
|
|
35
|
+
----------
|
|
36
|
+
Jonathan Chico
|
|
37
|
+
"""
|
|
38
|
+
import sys
|
|
39
|
+
from PyQt6.QtWidgets import QApplication
|
|
40
|
+
from ASD_GUI.UI.ASDUIDriver import UppASDVizMainWindow
|
|
41
|
+
|
|
42
|
+
################################################################################
|
|
43
|
+
## @brief Main executable class to run the ASD_Visualizer
|
|
44
|
+
# @details It calls the ASDUIDriver which contains the UppASDVizMainWindow class
|
|
45
|
+
# containing the wrapper class defining the data needed to setup the GUI.
|
|
46
|
+
# @author Jonathan Chico
|
|
47
|
+
################################################################################
|
|
48
|
+
if __name__ == '__main__':
|
|
49
|
+
|
|
50
|
+
# Open the Application Window
|
|
51
|
+
app = QApplication(sys.argv)
|
|
52
|
+
window = UppASDVizMainWindow()
|
|
53
|
+
window.show()
|
|
54
|
+
window.iren.Initialize() # Need this line to actually show the render inside Qt
|
|
55
|
+
# Return
|
|
56
|
+
sys.exit(app.exec())
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
""" @package ASDInputAux
|
|
2
|
+
Set of auxiliary functions to write restartfiles .
|
|
3
|
+
It has functions to generate the coordinate file, as well as to write the
|
|
4
|
+
following magnetic configurations:
|
|
5
|
+
- Domain walls:
|
|
6
|
+
- Neel planar wall.
|
|
7
|
+
- Bloch planar wall.
|
|
8
|
+
- Vortex wall.
|
|
9
|
+
- Skyrmion states:
|
|
10
|
+
- Neel skyrmion.
|
|
11
|
+
- Bloch skyrmion.
|
|
12
|
+
- Helical spin spirals.
|
|
13
|
+
|
|
14
|
+
Author
|
|
15
|
+
----------
|
|
16
|
+
Jonathan Chico
|
|
17
|
+
"""
|
|
18
|
+
################################################################################
|
|
19
|
+
# @brief Function to generate domain wall profiles.
|
|
20
|
+
#
|
|
21
|
+
# @details It can generate
|
|
22
|
+
# - Planar domain walls:
|
|
23
|
+
# - Neel planar wall.
|
|
24
|
+
# - Bloch planar wall.
|
|
25
|
+
# - Vortex domain walls.
|
|
26
|
+
#
|
|
27
|
+
# The domain walls can be centered at a certain point in the lattice and with a given width.
|
|
28
|
+
# The chirality and type of wall (Neel and Bloch) can be chosen.
|
|
29
|
+
# @author Jonathan Chico
|
|
30
|
+
################################################################################
|
|
31
|
+
def write_domain_wall(Natom,Mensemble,coord,DWInfo):
|
|
32
|
+
import numpy as np
|
|
33
|
+
tol=1e-9
|
|
34
|
+
# Magnetization of the system
|
|
35
|
+
mag=np.zeros([Mensemble,Natom,3],dtype=np.float64)
|
|
36
|
+
# Setup a planar domain wall type, i.e. a 1D object
|
|
37
|
+
if DWInfo['type']=='planar':
|
|
38
|
+
# Plane indicates which is the "propagation direction of the DW"
|
|
39
|
+
# The sign in front of the 1/cosh determines the chirality of the wall
|
|
40
|
+
if DWInfo['DWtype']=='Bloch':
|
|
41
|
+
if DWInfo['easy_axis']=='x':
|
|
42
|
+
#---------------------------------------------------------------
|
|
43
|
+
# Loop over the atoms in the system
|
|
44
|
+
#---------------------------------------------------------------
|
|
45
|
+
for jj in range(0,Mensemble):
|
|
46
|
+
for ii in range(0,Natom):
|
|
47
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
48
|
+
mag[:,ii,0]=np.tanh(arg)
|
|
49
|
+
mag[:,ii,1]=0.0
|
|
50
|
+
mag[:,ii,2]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
51
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
52
|
+
# Normalization of the spins
|
|
53
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
54
|
+
elif DWInfo['easy_axis']=='y':
|
|
55
|
+
#---------------------------------------------------------------
|
|
56
|
+
# Loop over the atoms in the system
|
|
57
|
+
#---------------------------------------------------------------
|
|
58
|
+
for jj in range(0,Mensemble):
|
|
59
|
+
for ii in range(0,Natom):
|
|
60
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
61
|
+
mag[:,ii,0]=0.0
|
|
62
|
+
mag[:,ii,1]=np.tanh(arg)
|
|
63
|
+
mag[:,ii,2]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
64
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
65
|
+
# Normalization of the spins
|
|
66
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
67
|
+
elif DWInfo['easy_axis']=='z':
|
|
68
|
+
#---------------------------------------------------------------
|
|
69
|
+
# Loop over the atoms in the system
|
|
70
|
+
#---------------------------------------------------------------
|
|
71
|
+
for jj in range(0,Mensemble):
|
|
72
|
+
for ii in range(0,Natom):
|
|
73
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
74
|
+
mag[:,ii,0]=0.0
|
|
75
|
+
mag[:,ii,1]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
76
|
+
mag[:,ii,2]=np.tanh(arg)
|
|
77
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
78
|
+
# Normalization of the spins
|
|
79
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
80
|
+
elif DWInfo['DWtype']=='Neel':
|
|
81
|
+
if DWInfo['easy_axis']=='x':
|
|
82
|
+
#---------------------------------------------------------------
|
|
83
|
+
# Loop over the atoms in the system
|
|
84
|
+
#---------------------------------------------------------------
|
|
85
|
+
for jj in range(0,Mensemble):
|
|
86
|
+
for ii in range(0,Natom):
|
|
87
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
88
|
+
mag[:,ii,0]=np.tanh(arg)
|
|
89
|
+
mag[:,ii,1]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
90
|
+
mag[:,ii,2]=0.0
|
|
91
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
92
|
+
# Normalization of the spins
|
|
93
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
94
|
+
elif DWInfo['easy_axis']=='y':
|
|
95
|
+
#---------------------------------------------------------------
|
|
96
|
+
# Loop over the atoms in the system
|
|
97
|
+
#---------------------------------------------------------------
|
|
98
|
+
for jj in range(0,Mensemble):
|
|
99
|
+
for ii in range(0,Natom):
|
|
100
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
101
|
+
mag[jj,ii,0]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
102
|
+
mag[jj,ii,1]=np.tanh(arg)
|
|
103
|
+
mag[jj,ii,2]=0
|
|
104
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
105
|
+
# Normalization of the spins
|
|
106
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
107
|
+
elif DWInfo['easy_axis']=='z':
|
|
108
|
+
#---------------------------------------------------------------
|
|
109
|
+
# Loop over the atoms in the system
|
|
110
|
+
#---------------------------------------------------------------
|
|
111
|
+
for jj in range(0,Mensemble):
|
|
112
|
+
for ii in range(0,Natom):
|
|
113
|
+
arg=(DWInfo['center']-coord[ii,DWInfo['plane']])/DWInfo['width']
|
|
114
|
+
mag[jj,ii,0]=DWInfo['chirality']*1.0/np.cosh(arg)
|
|
115
|
+
mag[jj,ii,1]=0.0
|
|
116
|
+
mag[jj,ii,2]=np.tanh(arg)
|
|
117
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
118
|
+
# Normalization of the spins
|
|
119
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
120
|
+
# Setup a vortex domain wall type, i.e. a 2D object
|
|
121
|
+
elif DWInfo['type']=='vortex':
|
|
122
|
+
# For the vortex wall one must introduce a rotation like term
|
|
123
|
+
#-----------------------------------------------------------------------
|
|
124
|
+
# Loop over the atoms in the system
|
|
125
|
+
#-----------------------------------------------------------------------
|
|
126
|
+
for ii in range(0,Natom):
|
|
127
|
+
r_x=coord[ii,0]-DWInfo['center'][0]
|
|
128
|
+
r_y=coord[ii,1]-DWInfo['center'][1]
|
|
129
|
+
mod_r2=np.sqrt(r_x**2+r_y**2)
|
|
130
|
+
arg=mod_r2/DWInfo['radius']
|
|
131
|
+
if mod_r2>tol:
|
|
132
|
+
theta=np.arctan2(r_x,r_y)
|
|
133
|
+
else:
|
|
134
|
+
theta=0.0
|
|
135
|
+
mag[:,ii,0]=DWInfo['chirality']*np.cos(theta)*np.tanh(arg)
|
|
136
|
+
mag[:,ii,1]=DWInfo['chirality']*np.sin(theta)*np.tanh(arg)
|
|
137
|
+
mag[:,ii,2]=DWInfo['polarity']*1.0/np.cosh(arg)
|
|
138
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
139
|
+
# Normalization of the spins
|
|
140
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
141
|
+
return mag
|
|
142
|
+
|
|
143
|
+
################################################################################
|
|
144
|
+
# @brief Writes a restartfile with a skyrmion profile.
|
|
145
|
+
# @details Generates a skyrmion profile making use of the skyrmion profiles defined in
|
|
146
|
+
# Nat. Commun. 7, 13613 (2016):
|
|
147
|
+
#
|
|
148
|
+
# @f$m_x = \cos(m\phi+\gamma)\sin(\theta(r))@f$
|
|
149
|
+
#
|
|
150
|
+
# @f$m_y = \sin(m\phi+\gamma)\sin(\theta(r))@f$
|
|
151
|
+
#
|
|
152
|
+
# @f$m_z = \cos(\theta(r))@f$
|
|
153
|
+
#
|
|
154
|
+
# With the out of plane angle \f$\theta\f$ being given by
|
|
155
|
+
# @f$\theta(r)=\pi + \arcsin(\tanh((r+c)/w)) + \arcsin(\tanh((r-c)/w))@f$
|
|
156
|
+
#
|
|
157
|
+
# with @f$c@f$ being the center of the skyrmion and @f$w@f$ the radius.
|
|
158
|
+
# The polar angle @f$\phi@f$ is determined from the skyrmion center, @f$\gamma@f$
|
|
159
|
+
# determined the type of skyrmion with @f$\gamma=0@f$ implies a Neel Skyrmion and
|
|
160
|
+
# @f$\gamma=\frac{\pi}{2}@f$ is a Bloch Skyrmion.
|
|
161
|
+
# The skyrmion is assumed to have its core parallel to the z-axis.
|
|
162
|
+
#
|
|
163
|
+
# @author Jonathan Chico
|
|
164
|
+
################################################################################
|
|
165
|
+
def write_skyrmion(Natom,Mensemble,coord,SkxInfo):
|
|
166
|
+
""" Generates a skyrmion profile making use of the skyrmion profiles defined in
|
|
167
|
+
Nat. Commun. 7, 13613 (2016):
|
|
168
|
+
* .math: m_x = \cos(m\phi+\gamma)\sin(\theta(r))
|
|
169
|
+
* .math: m_y = \sin(m\phi+\gamma)\sin(\theta(r))
|
|
170
|
+
* .math: m_z = \cos(\theta(r))
|
|
171
|
+
"""
|
|
172
|
+
import numpy as np
|
|
173
|
+
tol=1e-9
|
|
174
|
+
# Magnetization of the system
|
|
175
|
+
mag=np.zeros([Mensemble,Natom,3],dtype=np.float64)
|
|
176
|
+
#---------------------------------------------------------------------------
|
|
177
|
+
# Loop over the atoms in the system
|
|
178
|
+
#---------------------------------------------------------------------------
|
|
179
|
+
for jj in range(0,Mensemble):
|
|
180
|
+
for ii in range(0,Natom):
|
|
181
|
+
# Define the factors for the in-plane phi angle
|
|
182
|
+
r_x=coord[ii,0]-SkxInfo['center'][0]
|
|
183
|
+
r_y=coord[ii,1]-SkxInfo['center'][1]
|
|
184
|
+
mod_r=np.sqrt(r_x*r_x+r_y*r_y)
|
|
185
|
+
# The distance from the center of the skyrmion to which the DW walls are set
|
|
186
|
+
rad=SkxInfo['width']*0.5
|
|
187
|
+
r_p=(mod_r+rad)/SkxInfo['width']
|
|
188
|
+
r_n=(mod_r-rad)/SkxInfo['width']
|
|
189
|
+
# Out of plane angle
|
|
190
|
+
theta = (np.pi+np.arcsin(np.tanh(r_p))+np.arcsin(np.tanh(r_n))+SkxInfo['polarity'])
|
|
191
|
+
# In-plane skyrmion profile angle
|
|
192
|
+
if mod_r>tol:
|
|
193
|
+
phi=np.arctan2(r_y,r_x)
|
|
194
|
+
else:
|
|
195
|
+
phi=0.0
|
|
196
|
+
# Magnetization per site
|
|
197
|
+
mag[jj,ii,0]=SkxInfo['handness']*np.sin(theta)*np.cos(SkxInfo['order']*phi+SkxInfo['type'])
|
|
198
|
+
mag[jj,ii,1]=SkxInfo['handness']*np.sin(theta)*np.sin(SkxInfo['order']*phi+SkxInfo['type'])
|
|
199
|
+
mag[jj,ii,2]=np.cos(theta)
|
|
200
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
201
|
+
# Normalization of the spins
|
|
202
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
203
|
+
return mag
|
|
204
|
+
|
|
205
|
+
################################################################################
|
|
206
|
+
# @brief Function to generate a generalized spin spiral configuration
|
|
207
|
+
# @details This function creates a generalized spin spiral via Rodrigues rotations
|
|
208
|
+
# @f$ \mathbf{v}_{rot}= \mathbf{v}\cos\theta +\left(\mathbf{v}\times\mathbf{k}\right)\sin\theta+\mathbf{k}\left(\mathbf{k}\cdot\mathbf{v}\right)\left(1-\cos\theta\right)@f$
|
|
209
|
+
# First a rotation is done to generate the cone angle, this is done by generating an
|
|
210
|
+
# axis that is perpendicular to the \textbf{pitch vector} (that is @f$v@f$ in the Rodrigues formula)
|
|
211
|
+
# which is dubbed the \textbf{cone axis}.
|
|
212
|
+
# The pitch vector is then rotated by that axis by an angle @f$\theta@f$, i.e. the cone angle.
|
|
213
|
+
# The obtained vector is then the initial spin direction, that will be rotated by
|
|
214
|
+
# the pitch vector, with an angle given by @f$\theta= \mathbf{q}\cdot\mathbf{r}@f$
|
|
215
|
+
# with @f$\mathbf{q}@f$ being the spiral wavevector.
|
|
216
|
+
# @author Jonathan Chico
|
|
217
|
+
################################################################################
|
|
218
|
+
def create_spiral(Natom,Mensemble,coord,HLInfo):
|
|
219
|
+
import numpy as np
|
|
220
|
+
# Transform lists to np arrays to avoid problems
|
|
221
|
+
rot_vector=np.asarray(HLInfo['pitch_vector'],dtype=np.float64)
|
|
222
|
+
prop_vector=np.asarray(HLInfo['prop_vector'],dtype=np.float64)
|
|
223
|
+
# Magnetization of the system
|
|
224
|
+
mag=np.zeros([Mensemble,Natom,3],dtype=np.float64)
|
|
225
|
+
#---------------------------------------------------------------------------
|
|
226
|
+
# First do a rotation to find the rotates spin for the conical phase
|
|
227
|
+
#---------------------------------------------------------------------------
|
|
228
|
+
# First create a vector perpendicular to the rotation axis
|
|
229
|
+
test_r=np.random.rand(3)
|
|
230
|
+
# Normalize the vector
|
|
231
|
+
test_r=test_r/np.sqrt(test_r.dot(test_r))
|
|
232
|
+
# Axis which one will use to rotate the spins to get the conical phase
|
|
233
|
+
cone_axis=np.cross(rot_vector,test_r)
|
|
234
|
+
#---------------------------------------------------------------------------
|
|
235
|
+
# Rotate the spin first to find the needed cone angle using Rodriges rotation
|
|
236
|
+
#---------------------------------------------------------------------------
|
|
237
|
+
init_spin=rot_vector*np.cos(HLInfo['cone_angle'])+\
|
|
238
|
+
np.cross(cone_axis,rot_vector)*np.sin(HLInfo['cone_angle'])+\
|
|
239
|
+
cone_axis*(cone_axis.dot(rot_vector))*(1-np.cos(HLInfo['cone_angle']))
|
|
240
|
+
#---------------------------------------------------------------------------
|
|
241
|
+
# Loop over the ensembles and atoms of the system
|
|
242
|
+
#---------------------------------------------------------------------------
|
|
243
|
+
for jj in range(0,Mensemble):
|
|
244
|
+
for ii in range(0,Natom):
|
|
245
|
+
#
|
|
246
|
+
theta=prop_vector.dot(coord[ii,:])*2.0*np.pi*HLInfo['handness']
|
|
247
|
+
#-------------------------------------------------------------------
|
|
248
|
+
# Do a Rodrigues rotation to get the helical spiral state
|
|
249
|
+
#-------------------------------------------------------------------
|
|
250
|
+
mag[jj,ii,:]=init_spin*np.cos(theta)+\
|
|
251
|
+
np.cross(rot_vector,init_spin)*np.sin(theta)+\
|
|
252
|
+
rot_vector*(rot_vector.dot(init_spin))*(1-np.cos(theta))
|
|
253
|
+
mod=np.sqrt(mag[jj,ii].dot(mag[jj,ii]))
|
|
254
|
+
# Normalization of the spins
|
|
255
|
+
mag[jj,ii,:]=mag[jj,ii,:]/mod
|
|
256
|
+
return mag
|
|
257
|
+
|
|
258
|
+
################################################################################
|
|
259
|
+
# @brief Function to generate the coordinated for a given lattice following the
|
|
260
|
+
# same structure than in \c UppASD.
|
|
261
|
+
# @details Routine taken from the \c UppASD \c geometry.f90
|
|
262
|
+
#
|
|
263
|
+
# @author Anders Bergman and Johan Hellsvik.
|
|
264
|
+
# @note Adapted to python by Jonathan Chico
|
|
265
|
+
################################################################################
|
|
266
|
+
def create_coord(cell,ncell,Bas,block_size,mom):
|
|
267
|
+
import numpy as np
|
|
268
|
+
tol=1e-9
|
|
269
|
+
|
|
270
|
+
NA=len(Bas)
|
|
271
|
+
|
|
272
|
+
detmatrix=cell[0,0]*cell[1,1]*cell[2,2]-cell[0,0]*cell[1,2]*cell[2,1]+\
|
|
273
|
+
cell[0,1]*cell[1,2]*cell[2,0]-cell[0,1]*cell[1,0]*cell[2,2]+\
|
|
274
|
+
cell[0,2]*cell[1,0]*cell[2,1]-cell[0,2]*cell[1,1]*cell[2,0]
|
|
275
|
+
|
|
276
|
+
invmatrix=np.zeros([3,3],dtype=np.float64)
|
|
277
|
+
if (abs(detmatrix)>tol):
|
|
278
|
+
invmatrix[0,0]=(cell[1,1]*cell[2,2]-cell[2,1]*cell[1,2])/detmatrix
|
|
279
|
+
invmatrix[0,1]=(cell[0,2]*cell[2,1]-cell[2,2]*cell[0,1])/detmatrix
|
|
280
|
+
invmatrix[0,2]=(cell[0,1]*cell[1,2]-cell[1,1]*cell[0,2])/detmatrix
|
|
281
|
+
invmatrix[1,0]=(cell[1,2]*cell[2,0]-cell[2,2]*cell[1,0])/detmatrix
|
|
282
|
+
invmatrix[1,1]=(cell[0,0]*cell[2,2]-cell[2,0]*cell[0,2])/detmatrix
|
|
283
|
+
invmatrix[1,2]=(cell[0,2]*cell[1,0]-cell[1,2]*cell[0,0])/detmatrix
|
|
284
|
+
invmatrix[2,0]=(cell[1,0]*cell[2,1]-cell[2,0]*cell[1,1])/detmatrix
|
|
285
|
+
invmatrix[2,1]=(cell[0,1]*cell[2,0]-cell[2,1]*cell[0,0])/detmatrix
|
|
286
|
+
invmatrix[2,2]=(cell[0,0]*cell[1,1]-cell[1,0]*cell[0,1])/detmatrix
|
|
287
|
+
|
|
288
|
+
icvec=np.zeros([3],dtype=np.float64)
|
|
289
|
+
bsf=np.zeros([3],dtype=np.float64)
|
|
290
|
+
for I0 in range(0,NA):
|
|
291
|
+
icvec[0]=Bas[I0,0]*invmatrix[0,0]+Bas[I0,1]*invmatrix[1,0]+Bas[I0,2]*invmatrix[2,0]
|
|
292
|
+
icvec[1]=Bas[I0,0]*invmatrix[0,1]+Bas[I0,1]*invmatrix[1,1]+Bas[I0,2]*invmatrix[2,1]
|
|
293
|
+
icvec[2]=Bas[I0,0]*invmatrix[0,2]+Bas[I0,1]*invmatrix[1,2]+Bas[I0,2]*invmatrix[2,2]
|
|
294
|
+
bsf[0]=np.floor(icvec[0]+1e-7)
|
|
295
|
+
bsf[1]=np.floor(icvec[1]+1e-7)
|
|
296
|
+
bsf[2]=np.floor(icvec[2]+1e-7)
|
|
297
|
+
for mu in range(0,3):
|
|
298
|
+
Bas[I0,mu]=Bas[I0,mu]-bsf[0]*cell[0,mu]-bsf[1]*cell[1,mu]-bsf[2]*cell[2,mu]
|
|
299
|
+
|
|
300
|
+
ii=0
|
|
301
|
+
coord=np.zeros([NA*ncell[0]*ncell[1]*ncell[2],3],dtype=np.float64)
|
|
302
|
+
mom_mag=np.zeros([NA*ncell[0]*ncell[1]*ncell[2]],dtype=np.float64)
|
|
303
|
+
for II3 in range(0, ncell[2],block_size):
|
|
304
|
+
for II2 in range(0, ncell[1],block_size):
|
|
305
|
+
for II1 in range(0,ncell[0],block_size):
|
|
306
|
+
for I3 in range(II3, min(II3+block_size,ncell[2])):
|
|
307
|
+
for I2 in range(II2,min(II2+block_size,ncell[1])):
|
|
308
|
+
for I1 in range(II1, min(II1+block_size,ncell[0])):
|
|
309
|
+
for I0 in range(0, NA):
|
|
310
|
+
mom_mag[ii]=mom[I0]
|
|
311
|
+
for mu in range(0,3):
|
|
312
|
+
coord[ii,mu]=I1*cell[0,mu]+I2*cell[1,mu]+I3*cell[2,mu]+Bas[I0,mu]
|
|
313
|
+
ii=ii+1
|
|
314
|
+
return coord, mom_mag
|