1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the handling of Frame Order."""
24
25
26 import dep_check
27
28
29 from math import cos, pi, sin, sqrt
30 from numpy import cross, dot, sinc, transpose
31 from numpy.linalg import norm
32 if dep_check.scipy_module:
33 from scipy.integrate import quad
34
35
36 from float import isNaN
37 from maths_fns import order_parameters
38 from maths_fns.coord_transform import spherical_to_cartesian
39 from maths_fns.kronecker_product import kron_prod, transpose_23
40 from maths_fns.pseudo_ellipse import pec
41 from maths_fns.rotation_matrix import euler_to_R_zyz, two_vect_to_R
42
43
45 """Generate the 1st degree Frame Order matrix for the pseudo-ellipse.
46
47 @param matrix: The Frame Order matrix, 1st degree to be populated.
48 @type matrix: numpy 3D, rank-2 array
49 @param theta_x: The cone opening angle along x.
50 @type theta_x: float
51 @param theta_y: The cone opening angle along y.
52 @type theta_y: float
53 @param sigma_max: The maximum torsion angle.
54 @type sigma_max: float
55 """
56
57
58 fact = 1.0 / (2.0 * sigma_max * pec(theta_x, theta_y))
59
60
61 matrix[0, 0] = fact * quad(part_int_daeg1_pseudo_ellipse_xx, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]
62 matrix[1, 1] = fact * quad(part_int_daeg1_pseudo_ellipse_yy, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]
63 matrix[2, 2] = fact * quad(part_int_daeg1_pseudo_ellipse_zz, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]
64
65
67 """Generate the rotated 2nd degree Frame Order matrix for the free rotor model.
68
69 The rotor axis is assumed to be parallel to the z-axis in the eigenframe.
70
71
72 @param matrix: The Frame Order matrix, 2nd degree to be populated.
73 @type matrix: numpy 9D, rank-2 array
74 @param R: The rotation matrix to be populated.
75 @type R: numpy 3D, rank-2 array
76 @param z_axis: The molecular frame z-axis from which the rotor axis is rotated from.
77 @type z_axis: numpy 3D, rank-1 array
78 @param axis: The storage structure for the axis.
79 @type axis: numpy 3D, rank-1 array
80 @param theta_axis: The axis polar angle.
81 @type theta_axis: float
82 @param phi_axis: The axis azimuthal angle.
83 @type phi_axis: float
84 """
85
86
87 for i in range(9):
88 for j in range(9):
89 matrix[i, j] = 0.0
90
91
92 matrix[0, 0] = 0.5
93 matrix[1, 1] = 0.5
94 matrix[3, 3] = 0.5
95 matrix[4, 4] = 0.5
96 matrix[8, 8] = 1
97
98
99 matrix[0, 4] = matrix[4, 0] = 0.5
100
101
102 matrix[1, 3] = matrix[3, 1] = -0.5
103
104
105 spherical_to_cartesian([1.0, theta_axis, phi_axis], axis)
106
107
108 two_vect_to_R(z_axis, axis, R)
109
110
111 return rotate_daeg(matrix, R)
112
113
115 """Generate the rotated 2nd degree Frame Order matrix for the isotropic cone.
116
117 The cone axis is assumed to be parallel to the z-axis in the eigenframe.
118
119 @param matrix: The Frame Order matrix, 2nd degree to be populated.
120 @type matrix: numpy 9D, rank-2 array
121 @param R: The rotation matrix to be populated.
122 @type R: numpy 3D, rank-2 array
123 @param eigen_alpha: The eigenframe rotation alpha Euler angle.
124 @type eigen_alpha: float
125 @param eigen_beta: The eigenframe rotation beta Euler angle.
126 @type eigen_beta: float
127 @param eigen_gamma: The eigenframe rotation gamma Euler angle.
128 @type eigen_gamma: float
129 @param cone_theta: The cone opening angle.
130 @type cone_theta: float
131 @param sigma_max: The maximum torsion angle.
132 @type sigma_max: float
133 """
134
135
136 populate_2nd_eigenframe_iso_cone(matrix, cone_theta, sigma_max)
137
138
139 euler_to_R_zyz(eigen_alpha, eigen_beta, eigen_gamma, R)
140
141
142 return rotate_daeg(matrix, R)
143
144
146 """Generate the rotated 2nd degree Frame Order matrix for the free rotor isotropic cone.
147
148 The cone axis is assumed to be parallel to the z-axis in the eigenframe. In this model, the three order parameters are defined as::
149
150 S1 = S2,
151 S3 = 0
152
153
154 @param matrix: The Frame Order matrix, 2nd degree to be populated.
155 @type matrix: numpy 9D, rank-2 array
156 @param R: The rotation matrix to be populated.
157 @type R: numpy 3D, rank-2 array
158 @param z_axis: The molecular frame z-axis from which the cone axis is rotated from.
159 @type z_axis: numpy 3D, rank-1 array
160 @param cone_axis: The storage structure for the cone axis.
161 @type cone_axis: numpy 3D, rank-1 array
162 @param theta_axis: The cone axis polar angle.
163 @type theta_axis: float
164 @param phi_axis: The cone axis azimuthal angle.
165 @type phi_axis: float
166 @param s1: The cone order parameter.
167 @type s1: float
168 """
169
170
171 spherical_to_cartesian([1.0, theta_axis, phi_axis], cone_axis)
172
173
174 populate_2nd_eigenframe_iso_cone_free_rotor(matrix, s1)
175
176
177 two_vect_to_R(z_axis, cone_axis, R)
178
179
180 return rotate_daeg(matrix, R)
181
182
184 """Generate the rotated 2nd degree Frame Order matrix for the torsionless isotropic cone.
185
186 The cone axis is assumed to be parallel to the z-axis in the eigenframe.
187
188
189 @param matrix: The Frame Order matrix, 2nd degree to be populated.
190 @type matrix: numpy 9D, rank-2 array
191 @param R: The rotation matrix to be populated.
192 @type R: numpy 3D, rank-2 array
193 @param z_axis: The molecular frame z-axis from which the cone axis is rotated from.
194 @type z_axis: numpy 3D, rank-1 array
195 @param cone_axis: The storage structure for the cone axis.
196 @type cone_axis: numpy 3D, rank-1 array
197 @param theta_axis: The cone axis polar angle.
198 @type theta_axis: float
199 @param phi_axis: The cone axis azimuthal angle.
200 @type phi_axis: float
201 @param cone_theta: The cone opening angle.
202 @type cone_theta: float
203 """
204
205
206 for i in range(9):
207 for j in range(9):
208 matrix[i, j] = 0.0
209
210
211 cos_tmax = cos(cone_theta)
212 cos_tmax2 = cos_tmax**2
213
214
215 matrix[0, 0] = (3.0*cos_tmax2 + 6.0*cos_tmax + 15.0) / 24.0
216 matrix[1, 1] = (cos_tmax2 + 10.0*cos_tmax + 13.0) / 24.0
217 matrix[2, 2] = (4.0*cos_tmax2 + 10.0*cos_tmax + 10.0) / 24.0
218 matrix[3, 3] = matrix[1, 1]
219 matrix[4, 4] = matrix[0, 0]
220 matrix[5, 5] = matrix[2, 2]
221 matrix[6, 6] = matrix[2, 2]
222 matrix[7, 7] = matrix[2, 2]
223 matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0
224
225
226 matrix[0, 4] = matrix[4, 0] = (cos_tmax2 - 2.0*cos_tmax + 1.0) / 24.0
227 matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0
228 matrix[4, 8] = matrix[8, 4] = matrix[0, 8]
229
230
231 matrix[1, 3] = matrix[3, 1] = matrix[0, 4]
232 matrix[2, 6] = matrix[6, 2] = -matrix[0, 8]
233 matrix[5, 7] = matrix[7, 5] = -matrix[0, 8]
234
235
236 spherical_to_cartesian([1.0, theta_axis, phi_axis], cone_axis)
237
238
239 two_vect_to_R(z_axis, cone_axis, R)
240
241
242 return rotate_daeg(matrix, R)
243
244
246 """Generate the 2nd degree Frame Order matrix for the pseudo-ellipse.
247
248 @param matrix: The Frame Order matrix, 2nd degree to be populated.
249 @type matrix: numpy 9D, rank-2 array
250 @param R: The rotation matrix to be populated.
251 @type R: numpy 3D, rank-2 array
252 @param eigen_alpha: The eigenframe rotation alpha Euler angle.
253 @type eigen_alpha: float
254 @param eigen_beta: The eigenframe rotation beta Euler angle.
255 @type eigen_beta: float
256 @param eigen_gamma: The eigenframe rotation gamma Euler angle.
257 @type eigen_gamma: float
258 @param theta_x: The cone opening angle along x.
259 @type theta_x: float
260 @param theta_y: The cone opening angle along y.
261 @type theta_y: float
262 @param sigma_max: The maximum torsion angle.
263 @type sigma_max: float
264 """
265
266
267 fact = 12.0 * pec(theta_x, theta_y)
268
269
270 if fact == 0.0:
271 fact = 1e100
272 else:
273 fact = 1.0 / fact
274
275
276 if sigma_max == 0.0:
277 fact2 = 1e100
278 else:
279 fact2 = fact / (2.0 * sigma_max)
280
281
282 matrix[0, 0] = fact * (4.0*pi*(sinc(2.0*sigma_max/pi) + 2.0) + quad(part_int_daeg2_pseudo_ellipse_00, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
283 matrix[1, 1] = fact * (4.0*pi*sinc(2.0*sigma_max/pi) + quad(part_int_daeg2_pseudo_ellipse_11, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
284 matrix[2, 2] = fact * 2.0*sinc(sigma_max/pi) * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_22, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
285 matrix[3, 3] = matrix[1, 1]
286 matrix[4, 4] = fact * (4.0*pi*(sinc(2.0*sigma_max/pi) + 2.0) + quad(part_int_daeg2_pseudo_ellipse_44, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
287 matrix[5, 5] = fact * 2.0*sinc(sigma_max/pi) * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_55, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
288 matrix[6, 6] = matrix[2, 2]
289 matrix[7, 7] = matrix[5, 5]
290 matrix[8, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_88, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
291
292
293 matrix[0, 4] = fact * (4.0*pi*(2.0 - sinc(2.0*sigma_max/pi)) + quad(part_int_daeg2_pseudo_ellipse_04, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
294 matrix[4, 0] = fact * (4.0*pi*(2.0 - sinc(2.0*sigma_max/pi)) + quad(part_int_daeg2_pseudo_ellipse_40, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
295 matrix[0, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_08, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
296 matrix[8, 0] = fact * (8.0*pi + quad(part_int_daeg2_pseudo_ellipse_80, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
297 matrix[4, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_48, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
298 matrix[8, 4] = fact * (8.0*pi - quad(part_int_daeg2_pseudo_ellipse_84, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
299
300
301 matrix[1, 3] = matrix[3, 1] = fact * (4.0*pi*sinc(2.0*sigma_max/pi) + quad(part_int_daeg2_pseudo_ellipse_13, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
302 matrix[2, 6] = matrix[6, 2] = -fact * 4.0 * sinc(sigma_max/pi) * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_26, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
303 matrix[5, 7] = matrix[7, 5] = -fact * 4.0 * sinc(sigma_max/pi) * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_57, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0])
304
305
306 euler_to_R_zyz(eigen_alpha, eigen_beta, eigen_gamma, R)
307
308
309 return rotate_daeg(matrix, R)
310
311
313 """Generate the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
314
315 @param matrix: The Frame Order matrix, 2nd degree to be populated.
316 @type matrix: numpy 9D, rank-2 array
317 @param R: The rotation matrix to be populated.
318 @type R: numpy 3D, rank-2 array
319 @param eigen_alpha: The eigenframe rotation alpha Euler angle.
320 @type eigen_alpha: float
321 @param eigen_beta: The eigenframe rotation beta Euler angle.
322 @type eigen_beta: float
323 @param eigen_gamma: The eigenframe rotation gamma Euler angle.
324 @type eigen_gamma: float
325 @param theta_x: The cone opening angle along x.
326 @type theta_x: float
327 @param theta_y: The cone opening angle along y.
328 @type theta_y: float
329 """
330
331
332 fact = 1.0 / (6.0 * pec(theta_x, theta_y))
333
334
335 matrix[0, 0] = fact * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
336 matrix[1, 1] = matrix[3, 3] = fact * 3.0/2.0 * quad(part_int_daeg2_pseudo_ellipse_free_rotor_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]
337 matrix[4, 4] = fact * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
338 matrix[8, 8] = fact * (4.0*pi - 2.0*quad(part_int_daeg2_pseudo_ellipse_free_rotor_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
339
340
341 matrix[0, 4] = matrix[0, 0]
342 matrix[4, 0] = matrix[4, 4]
343 matrix[0, 8] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
344 matrix[8, 0] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_80, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
345 matrix[4, 8] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
346 matrix[8, 4] = matrix[8, 0]
347
348
349 matrix[1, 3] = matrix[3, 1] = -matrix[1, 1]
350
351
352 euler_to_R_zyz(eigen_alpha, eigen_beta, eigen_gamma, R)
353
354
355 return rotate_daeg(matrix, R)
356
357
359 """Generate the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
360
361 @param matrix: The Frame Order matrix, 2nd degree to be populated.
362 @type matrix: numpy 9D, rank-2 array
363 @param R: The rotation matrix to be populated.
364 @type R: numpy 3D, rank-2 array
365 @param eigen_alpha: The eigenframe rotation alpha Euler angle.
366 @type eigen_alpha: float
367 @param eigen_beta: The eigenframe rotation beta Euler angle.
368 @type eigen_beta: float
369 @param eigen_gamma: The eigenframe rotation gamma Euler angle.
370 @type eigen_gamma: float
371 @param theta_x: The cone opening angle along x.
372 @type theta_x: float
373 @param theta_y: The cone opening angle along y.
374 @type theta_y: float
375 """
376
377
378 fact = 1.0 / (6.0 * pec(theta_x, theta_y))
379
380
381 matrix[0, 0] = fact * (6.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
382 matrix[1, 1] = fact * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
383 matrix[2, 2] = fact * (5.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
384 matrix[3, 3] = matrix[1, 1]
385 matrix[4, 4] = fact * (6.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
386 matrix[5, 5] = fact * (5.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_55, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
387 matrix[6, 6] = matrix[2, 2]
388 matrix[7, 7] = matrix[5, 5]
389 matrix[8, 8] = fact * quad(part_int_daeg2_pseudo_ellipse_torsionless_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]
390
391
392 matrix[0, 4] = matrix[4, 0] = fact * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_04, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
393 matrix[0, 8] = matrix[8, 0] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
394 matrix[4, 8] = matrix[8, 4] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0])
395
396
397 matrix[1, 3] = matrix[3, 1] = matrix[0, 4]
398 matrix[2, 6] = matrix[6, 2] = -matrix[0, 8]
399 matrix[5, 7] = matrix[7, 5] = -matrix[4, 8]
400
401
402 euler_to_R_zyz(eigen_alpha, eigen_beta, eigen_gamma, R)
403
404
405 return rotate_daeg(matrix, R)
406
407
409 """Generate the rotated 2nd degree Frame Order matrix for the rotor model.
410
411 The cone axis is assumed to be parallel to the z-axis in the eigenframe.
412
413
414 @param matrix: The Frame Order matrix, 2nd degree to be populated.
415 @type matrix: numpy 9D, rank-2 array
416 @param R: The rotation matrix to be populated.
417 @type R: numpy 3D, rank-2 array
418 @param z_axis: The molecular frame z-axis from which the rotor axis is rotated from.
419 @type z_axis: numpy 3D, rank-1 array
420 @param axis: The storage structure for the axis.
421 @type axis: numpy 3D, rank-1 array
422 @param theta_axis: The axis polar angle.
423 @type theta_axis: float
424 @param phi_axis: The axis azimuthal angle.
425 @type phi_axis: float
426 @param smax: The maximum torsion angle.
427 @type smax: float
428 """
429
430
431 for i in range(9):
432 for j in range(9):
433 matrix[i, j] = 0.0
434
435
436 sinc_smax = sinc(smax/pi)
437 sinc_2smax = sinc(2.0*smax/pi)
438
439
440 matrix[0, 0] = (sinc_2smax + 1.0) / 2.0
441 matrix[1, 1] = matrix[0, 0]
442 matrix[2, 2] = sinc_smax
443 matrix[3, 3] = matrix[0, 0]
444 matrix[4, 4] = matrix[0, 0]
445 matrix[5, 5] = matrix[2, 2]
446 matrix[6, 6] = matrix[2, 2]
447 matrix[7, 7] = matrix[2, 2]
448 matrix[8, 8] = 1.0
449
450
451 matrix[0, 4] = matrix[4, 0] = -(sinc_2smax - 1.0) / 2.0
452
453
454 matrix[1, 3] = matrix[3, 1] = -matrix[0, 4]
455
456
457 spherical_to_cartesian([1.0, theta_axis, phi_axis], axis)
458
459
460 two_vect_to_R(z_axis, axis, R)
461
462
463 return rotate_daeg(matrix, R)
464
465
467 """Convert the frame order matrix (daeg) to the rotational superoperator.
468
469 @param daeg: The second degree frame order matrix, daeg. This must be in the Kronecker product layout.
470 @type daeg: numpy 9D, rank-2 array or numpy 3D, rank-4 array
471 @param Rsuper: The rotational superoperator structure to be populated.
472 @type Rsuper: numpy 5D, rank-2 array
473 """
474
475
476 transpose_23(daeg)
477
478
479 orig_shape = daeg.shape
480 daeg.shape = (3, 3, 3, 3)
481
482
483 Rsuper[0, 0] = daeg[0, 0, 0, 0] - daeg[2, 0, 2, 0]
484 Rsuper[1, 0] = daeg[0, 1, 0, 1] - daeg[2, 1, 2, 1]
485 Rsuper[2, 0] = daeg[0, 0, 0, 1] - daeg[2, 0, 2, 1]
486 Rsuper[3, 0] = daeg[0, 0, 0, 2] - daeg[2, 0, 2, 2]
487 Rsuper[4, 0] = daeg[0, 1, 0, 2] - daeg[2, 1, 2, 2]
488
489
490 Rsuper[0, 1] = daeg[1, 0, 1, 0] - daeg[2, 0, 2, 0]
491 Rsuper[1, 1] = daeg[1, 1, 1, 1] - daeg[2, 1, 2, 1]
492 Rsuper[2, 1] = daeg[1, 0, 1, 1] - daeg[2, 0, 2, 1]
493 Rsuper[3, 1] = daeg[1, 0, 1, 2] - daeg[2, 0, 2, 2]
494 Rsuper[4, 1] = daeg[1, 1, 1, 2] - daeg[2, 1, 2, 2]
495
496
497 Rsuper[0, 2] = daeg[0, 0, 1, 0] + daeg[1, 0, 0, 0]
498 Rsuper[1, 2] = daeg[0, 1, 1, 1] + daeg[1, 1, 0, 1]
499 Rsuper[2, 2] = daeg[0, 0, 1, 1] + daeg[1, 0, 0, 1]
500 Rsuper[3, 2] = daeg[0, 0, 1, 2] + daeg[1, 0, 0, 2]
501 Rsuper[4, 2] = daeg[0, 1, 1, 2] + daeg[1, 1, 0, 2]
502
503
504 Rsuper[0, 3] = daeg[0, 0, 2, 0] + daeg[2, 0, 0, 0]
505 Rsuper[1, 3] = daeg[0, 1, 2, 1] + daeg[2, 1, 0, 1]
506 Rsuper[2, 3] = daeg[0, 0, 2, 1] + daeg[2, 0, 0, 1]
507 Rsuper[3, 3] = daeg[0, 0, 2, 2] + daeg[2, 0, 0, 2]
508 Rsuper[4, 3] = daeg[0, 1, 2, 2] + daeg[2, 1, 0, 2]
509
510
511 Rsuper[0, 4] = daeg[1, 0, 2, 0] + daeg[2, 0, 1, 0]
512 Rsuper[1, 4] = daeg[1, 1, 2, 1] + daeg[2, 1, 1, 1]
513 Rsuper[2, 4] = daeg[1, 0, 2, 1] + daeg[2, 0, 1, 1]
514 Rsuper[3, 4] = daeg[1, 0, 2, 2] + daeg[2, 0, 1, 2]
515 Rsuper[4, 4] = daeg[1, 1, 2, 2] + daeg[2, 1, 1, 2]
516
517
518 daeg.shape = orig_shape
519
520
521 transpose_23(daeg)
522
523
525 """The theta-sigma partial integral of the 1st degree Frame Order matrix element xx for the pseudo-ellipse.
526
527 @param phi: The azimuthal tilt-torsion angle.
528 @type phi: float
529 @param x: The cone opening angle along x.
530 @type x: float
531 @param y: The cone opening angle along y.
532 @type y: float
533 @param smax: The maximum torsion angle.
534 @type smax: float
535 @return: The theta-sigma partial integral.
536 @rtype: float
537 """
538
539
540 tmax = tmax_pseudo_ellipse(phi, x, y)
541
542
543 return sin(smax) * (2 * (1 - cos(tmax)) * sin(phi)**2 + cos(phi)**2 * sin(tmax)**2)
544
545
547 """The theta-sigma partial integral of the 1st degree Frame Order matrix element yy for the pseudo-ellipse.
548
549 @param phi: The azimuthal tilt-torsion angle.
550 @type phi: float
551 @param x: The cone opening angle along x.
552 @type x: float
553 @param y: The cone opening angle along y.
554 @type y: float
555 @param smax: The maximum torsion angle.
556 @type smax: float
557 @return: The theta-sigma partial integral.
558 @rtype: float
559 """
560
561
562 tmax = tmax_pseudo_ellipse(phi, x, y)
563
564
565 return sin(smax) * (2.0 * cos(phi)**2 * (1.0 - cos(tmax)) + sin(phi)**2 * sin(tmax)**2)
566
567
569 """The theta-sigma partial integral of the 1st degree Frame Order matrix element zz for the pseudo-ellipse.
570
571 @param phi: The azimuthal tilt-torsion angle.
572 @type phi: float
573 @param x: The cone opening angle along x.
574 @type x: float
575 @param y: The cone opening angle along y.
576 @type y: float
577 @param smax: The maximum torsion angle.
578 @type smax: float
579 @return: The theta-sigma partial integral.
580 @rtype: float
581 """
582
583
584 tmax = tmax_pseudo_ellipse(phi, x, y)
585
586
587 return smax * sin(tmax)**2
588
589
591 """The theta-sigma partial integral of the 2nd degree Frame Order matrix element 11 for the pseudo-ellipse.
592
593 @param phi: The azimuthal tilt-torsion angle.
594 @type phi: float
595 @param x: The cone opening angle along x.
596 @type x: float
597 @param y: The cone opening angle along y.
598 @type y: float
599 @param smax: The maximum torsion angle.
600 @type smax: float
601 @return: The theta-sigma partial integral.
602 @rtype: float
603 """
604
605
606 tmax = tmax_pseudo_ellipse(phi, x, y)
607
608
609 cos_tmax = cos(tmax)
610 sin_tmax2 = sin(tmax)**2
611 cos_phi2 = cos(phi)**2
612
613
614 a = sinc(2.0*smax/pi) * (2.0 * sin_tmax2 * cos_phi2 * ((2.0*cos_phi2 - 1.0)*cos(tmax) - 6.0*(cos_phi2 - 1.0)) - 2.0*cos_tmax * (2.0*cos_phi2*(4.0*cos_phi2 - 5.0) + 3.0))
615 b = 2.0*cos_phi2*cos_tmax*(sin_tmax2 + 2.0) - 6.0*cos_tmax
616
617
618 return a + b
619
620
622 """The theta-sigma partial integral of the 2nd degree Frame Order matrix element 22 for the pseudo-ellipse.
623
624 @param phi: The azimuthal tilt-torsion angle.
625 @type phi: float
626 @param x: The cone opening angle along x.
627 @type x: float
628 @param y: The cone opening angle along y.
629 @type y: float
630 @param smax: The maximum torsion angle.
631 @type smax: float
632 @return: The theta-sigma partial integral.
633 @rtype: float
634 """
635
636
637 tmax = tmax_pseudo_ellipse(phi, x, y)
638
639
640 cos_tmax = cos(tmax)
641 sin_tmax2 = sin(tmax)**2
642 cos_phi2 = cos(phi)**2
643 sin_phi2 = sin(phi)**2
644
645
646 a = sinc(2.0*smax/pi) * (2.0 * sin_tmax2 * cos_phi2 * ((2.0*sin_phi2 - 1.0)*cos(tmax) - 6.0*sin_phi2) + 2.0*cos_tmax * (2.0*cos_phi2*(4.0*cos_phi2 - 5.0) + 3.0))
647 b = 2.0*cos_phi2*cos_tmax*(sin_tmax2 + 2.0) - 6.0*cos_tmax
648
649
650 return a + b
651
652
654 """The theta-sigma partial integral of the 2nd degree Frame Order matrix element 33 for the pseudo-ellipse.
655
656 @param phi: The azimuthal tilt-torsion angle.
657 @type phi: float
658 @param x: The cone opening angle along x.
659 @type x: float
660 @param y: The cone opening angle along y.
661 @type y: float
662 @param smax: The maximum torsion angle.
663 @type smax: float
664 @return: The theta-sigma partial integral.
665 @rtype: float
666 """
667
668
669 tmax = tmax_pseudo_ellipse(phi, x, y)
670
671
672 return cos(tmax) * cos(phi)**2 * (sin(tmax)**2 + 2.0)
673
674
676 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
677
678 @param phi: The azimuthal tilt-torsion angle.
679 @type phi: float
680 @param x: The cone opening angle along x.
681 @type x: float
682 @param y: The cone opening angle along y.
683 @type y: float
684 @param smax: The maximum torsion angle.
685 @type smax: float
686 @return: The theta-sigma partial integral.
687 @rtype: float
688 """
689
690
691 tmax = tmax_pseudo_ellipse(phi, x, y)
692
693
694 cos_tmax = cos(tmax)
695 cos_phi2 = cos(phi)**2
696 sin_phi2 = sin(phi)**2
697
698
699 a = sinc(2.0*smax/pi) * ((4.0*cos_phi2*((1.0 - cos_phi2)*cos_tmax + 3.0*(cos_phi2-1)) + 3.0)*sin(tmax)**2 - 16.0*cos_phi2*sin_phi2*cos_tmax) + 3.0*sin(tmax)**2
700
701
702 return a
703
704
706 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
707
708 @param phi: The azimuthal tilt-torsion angle.
709 @type phi: float
710 @param x: The cone opening angle along x.
711 @type x: float
712 @param y: The cone opening angle along y.
713 @type y: float
714 @param smax: The maximum torsion angle.
715 @type smax: float
716 @return: The theta-sigma partial integral.
717 @rtype: float
718 """
719
720
721 tmax = tmax_pseudo_ellipse(phi, x, y)
722
723
724 cos_tmax = cos(tmax)
725 sin_tmax2 = sin(tmax)**2
726 sinc_2smax = sinc(2.0*smax/pi)
727 cos_sin_phi2 = cos(phi)**2*sin(phi)**2
728
729
730 return sinc_2smax * (sin_tmax2 * (4*cos_sin_phi2*cos_tmax - 12*cos_sin_phi2 + 3) - 16*cos_sin_phi2*cos_tmax) - 3.0*sin_tmax2
731
732
734 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
735
736 @param phi: The azimuthal tilt-torsion angle.
737 @type phi: float
738 @param x: The cone opening angle along x.
739 @type x: float
740 @param y: The cone opening angle along y.
741 @type y: float
742 @param smax: The maximum torsion angle.
743 @type smax: float
744 @return: The theta-sigma partial integral.
745 @rtype: float
746 """
747
748
749 tmax = tmax_pseudo_ellipse(phi, x, y)
750
751
752 cos_tmax = cos(tmax)
753 cos_phi2 = cos(phi)**2
754
755
756 a = 2.0*cos_phi2*cos_tmax**3 + 3.0*(1.0 - cos_phi2)*cos_tmax**2
757
758
759 return a
760
761
763 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
764
765 @param phi: The azimuthal tilt-torsion angle.
766 @type phi: float
767 @param x: The cone opening angle along x.
768 @type x: float
769 @param y: The cone opening angle along y.
770 @type y: float
771 @param smax: The maximum torsion angle.
772 @type smax: float
773 @return: The theta-sigma partial integral.
774 @rtype: float
775 """
776
777
778 tmax = tmax_pseudo_ellipse(phi, x, y)
779
780
781 return cos(phi)**2 * (cos(tmax)**3 - 3.0*cos(tmax))
782
783
785 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
786
787 @param phi: The azimuthal tilt-torsion angle.
788 @type phi: float
789 @param x: The cone opening angle along x.
790 @type x: float
791 @param y: The cone opening angle along y.
792 @type y: float
793 @param smax: The maximum torsion angle.
794 @type smax: float
795 @return: The theta-sigma partial integral.
796 @rtype: float
797 """
798
799
800 tmax = tmax_pseudo_ellipse(phi, x, y)
801
802
803 cos_tmax = cos(tmax)
804 sin_tmax2 = sin(tmax)**2
805 cos_phi2 = cos(phi)**2
806 sin_phi2 = sin(phi)**2
807
808
809 a = sinc(2.0*smax/pi) * (2.0 * sin_tmax2 * sin_phi2 * ((2.0*cos_phi2 - 1.0)*cos(tmax) - 6.0*cos_phi2) + 2.0*cos_tmax * (2.0*sin_phi2*(4.0*sin_phi2 - 5.0) + 3.0))
810 b = 2.0*sin_phi2*cos_tmax*(sin_tmax2 + 2.0) - 6.0*cos_tmax
811
812
813 return a + b
814
815
817 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
818
819 @param phi: The azimuthal tilt-torsion angle.
820 @type phi: float
821 @param x: The cone opening angle along x.
822 @type x: float
823 @param y: The cone opening angle along y.
824 @type y: float
825 @param smax: The maximum torsion angle.
826 @type smax: float
827 @return: The theta-sigma partial integral.
828 @rtype: float
829 """
830
831
832 tmax = tmax_pseudo_ellipse(phi, x, y)
833
834
835 cos_tmax = cos(tmax)
836 sin_tmax2 = sin(tmax)**2
837 cos_phi2 = cos(phi)**2
838 sin_phi2 = sin(phi)**2
839
840
841 a = sinc(2.0*smax/pi) * (2.0 * sin_tmax2 * sin_phi2 * ((2.0*sin_phi2 - 1.0)*cos(tmax) + 6.0*cos_phi2) - 2.0*cos_tmax * (2.0*sin_phi2*(4.0*sin_phi2 - 5.0) + 3.0))
842 b = 2.0*sin_phi2*cos_tmax*(sin_tmax2 + 2.0) - 6.0*cos_tmax
843
844
845 return a + b
846
847
849 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
850
851 @param phi: The azimuthal tilt-torsion angle.
852 @type phi: float
853 @param x: The cone opening angle along x.
854 @type x: float
855 @param y: The cone opening angle along y.
856 @type y: float
857 @param smax: The maximum torsion angle.
858 @type smax: float
859 @return: The theta-sigma partial integral.
860 @rtype: float
861 """
862
863
864 tmax = tmax_pseudo_ellipse(phi, x, y)
865
866
867 return cos(tmax) * sin(phi)**2 * (sin(tmax)**2 + 2.0)
868
869
871 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
872
873 @param phi: The azimuthal tilt-torsion angle.
874 @type phi: float
875 @param x: The cone opening angle along x.
876 @type x: float
877 @param y: The cone opening angle along y.
878 @type y: float
879 @param smax: The maximum torsion angle.
880 @type smax: float
881 @return: The theta-sigma partial integral.
882 @rtype: float
883 """
884
885
886 tmax = tmax_pseudo_ellipse(phi, x, y)
887
888
889 cos_tmax = cos(tmax)
890 sin_phi2 = sin(phi)**2
891
892
893 return 2.0*sin_phi2*cos_tmax**3 + 3.0*(1.0 - sin_phi2)*cos_tmax**2
894
895
897 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
898
899 @param phi: The azimuthal tilt-torsion angle.
900 @type phi: float
901 @param x: The cone opening angle along x.
902 @type x: float
903 @param y: The cone opening angle along y.
904 @type y: float
905 @param smax: The maximum torsion angle.
906 @type smax: float
907 @return: The theta-sigma partial integral.
908 @rtype: float
909 """
910
911
912 tmax = tmax_pseudo_ellipse(phi, x, y)
913
914
915 return sin(phi)**2 * (cos(tmax)**3 - 3.0*cos(tmax))
916
917
919 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
920
921 @param phi: The azimuthal tilt-torsion angle.
922 @type phi: float
923 @param x: The cone opening angle along x.
924 @type x: float
925 @param y: The cone opening angle along y.
926 @type y: float
927 @param smax: The maximum torsion angle.
928 @type smax: float
929 @return: The theta-sigma partial integral.
930 @rtype: float
931 """
932
933
934 tmax = tmax_pseudo_ellipse(phi, x, y)
935
936
937 cos_tmax = cos(tmax)
938 sin_tmax2 = sin(tmax)**2
939 cos_phi2 = cos(phi)**2
940
941
942 return sinc(2.0*smax/pi) * (2.0*(1.0 - 2.0*cos_phi2)*cos_tmax*(sin_tmax2 + 2.0)) + 2.0*cos_tmax**3 - 6.0*cos_tmax
943
944
946 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
947
948 @param phi: The azimuthal tilt-torsion angle.
949 @type phi: float
950 @param x: The cone opening angle along x.
951 @type x: float
952 @param y: The cone opening angle along y.
953 @type y: float
954 @param smax: The maximum torsion angle.
955 @type smax: float
956 @return: The theta-sigma partial integral.
957 @rtype: float
958 """
959
960
961 tmax = tmax_pseudo_ellipse(phi, x, y)
962
963
964 cos_tmax = cos(tmax)
965 sin_tmax2 = sin(tmax)**2
966 cos_phi2 = cos(phi)**2
967
968
969 return sinc(2.0*smax/pi) * (2.0*(1.0 - 2.0*cos_phi2)*cos_tmax*(sin_tmax2 + 2.0)) - 2.0*cos_tmax**3 + 6.0*cos_tmax
970
971
973 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the pseudo-ellipse.
974
975 @param phi: The azimuthal tilt-torsion angle.
976 @type phi: float
977 @param x: The cone opening angle along x.
978 @type x: float
979 @param y: The cone opening angle along y.
980 @type y: float
981 @param smax: The maximum torsion angle.
982 @type smax: float
983 @return: The theta-sigma partial integral.
984 @rtype: float
985 """
986
987
988 tmax = tmax_pseudo_ellipse(phi, x, y)
989
990
991 return cos(tmax)**3
992
993
995 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
996
997 @param phi: The azimuthal tilt-torsion angle.
998 @type phi: float
999 @param x: The cone opening angle along x.
1000 @type x: float
1001 @param y: The cone opening angle along y.
1002 @type y: float
1003 @return: The theta-sigma partial integral.
1004 @rtype: float
1005 """
1006
1007
1008 tmax = tmax_pseudo_ellipse(phi, x, y)
1009
1010
1011 return cos(phi)**2*cos(tmax)**3 + 3.0*sin(phi)**2*cos(tmax)
1012
1013
1015 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1016
1017 @param phi: The azimuthal tilt-torsion angle.
1018 @type phi: float
1019 @param x: The cone opening angle along x.
1020 @type x: float
1021 @param y: The cone opening angle along y.
1022 @type y: float
1023 @return: The theta-sigma partial integral.
1024 @rtype: float
1025 """
1026
1027
1028 tmax = tmax_pseudo_ellipse(phi, x, y)
1029
1030
1031 return cos(phi)**2*(2.0*cos(tmax)**3 - 6.0*cos(tmax))
1032
1033
1035 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1036
1037 @param phi: The azimuthal tilt-torsion angle.
1038 @type phi: float
1039 @param x: The cone opening angle along x.
1040 @type x: float
1041 @param y: The cone opening angle along y.
1042 @type y: float
1043 @return: The theta-sigma partial integral.
1044 @rtype: float
1045 """
1046
1047
1048 tmax = tmax_pseudo_ellipse(phi, x, y)
1049
1050
1051 return sin(tmax)**2
1052
1053
1055 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1056
1057 @param phi: The azimuthal tilt-torsion angle.
1058 @type phi: float
1059 @param x: The cone opening angle along x.
1060 @type x: float
1061 @param y: The cone opening angle along y.
1062 @type y: float
1063 @return: The theta-sigma partial integral.
1064 @rtype: float
1065 """
1066
1067
1068 tmax = tmax_pseudo_ellipse(phi, x, y)
1069
1070
1071 return sin(phi)**2*cos(tmax)**3 + 3*cos(phi)**2*cos(tmax)
1072
1073
1075 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1076
1077 @param phi: The azimuthal tilt-torsion angle.
1078 @type phi: float
1079 @param x: The cone opening angle along x.
1080 @type x: float
1081 @param y: The cone opening angle along y.
1082 @type y: float
1083 @return: The theta-sigma partial integral.
1084 @rtype: float
1085 """
1086
1087
1088 tmax = tmax_pseudo_ellipse(phi, x, y)
1089
1090
1091 return sin(phi)**2*(2.0*cos(tmax)**3 - 6.0*cos(tmax))
1092
1093
1095 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1096
1097 @param phi: The azimuthal tilt-torsion angle.
1098 @type phi: float
1099 @param x: The cone opening angle along x.
1100 @type x: float
1101 @param y: The cone opening angle along y.
1102 @type y: float
1103 @return: The theta-sigma partial integral.
1104 @rtype: float
1105 """
1106
1107
1108 tmax = tmax_pseudo_ellipse(phi, x, y)
1109
1110
1111 return cos(tmax)**3 - 3.0*cos(tmax)
1112
1113
1115 """The theta-sigma partial integral of the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse.
1116
1117 @param phi: The azimuthal tilt-torsion angle.
1118 @type phi: float
1119 @param x: The cone opening angle along x.
1120 @type x: float
1121 @param y: The cone opening angle along y.
1122 @type y: float
1123 @return: The theta-sigma partial integral.
1124 @rtype: float
1125 """
1126
1127
1128 tmax = tmax_pseudo_ellipse(phi, x, y)
1129
1130
1131 return cos(tmax)**3
1132
1133
1135 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1136
1137 @param phi: The azimuthal tilt-torsion angle.
1138 @type phi: float
1139 @param x: The cone opening angle along x.
1140 @type x: float
1141 @param y: The cone opening angle along y.
1142 @type y: float
1143 @return: The theta partial integral.
1144 @rtype: float
1145 """
1146
1147
1148 tmax = tmax_pseudo_ellipse(phi, x, y)
1149
1150
1151 return (2*cos(phi)**4*cos(tmax) + 6*cos(phi)**2*sin(phi)**2)*sin(tmax)**2 - (6*sin(phi)**4 + 2*cos(phi)**4)*cos(tmax)
1152
1153
1155 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1156
1157 @param phi: The azimuthal tilt-torsion angle.
1158 @type phi: float
1159 @param x: The cone opening angle along x.
1160 @type x: float
1161 @param y: The cone opening angle along y.
1162 @type y: float
1163 @return: The theta partial integral.
1164 @rtype: float
1165 """
1166
1167
1168 tmax = tmax_pseudo_ellipse(phi, x, y)
1169
1170
1171 return (2*cos(phi)**2*sin(phi)**2*cos(tmax) - 6*cos(phi)**2*sin(phi)**2)*sin(tmax)**2 - 8*cos(phi)**2*sin(phi)**2*cos(tmax)
1172
1173
1175 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1176
1177 @param phi: The azimuthal tilt-torsion angle.
1178 @type phi: float
1179 @param x: The cone opening angle along x.
1180 @type x: float
1181 @param y: The cone opening angle along y.
1182 @type y: float
1183 @return: The theta partial integral.
1184 @rtype: float
1185 """
1186
1187
1188 tmax = tmax_pseudo_ellipse(phi, x, y)
1189
1190
1191 return 2*cos(phi)**2*cos(tmax)**3 - 6*cos(phi)**2*cos(tmax)
1192
1193
1195 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1196
1197 @param phi: The azimuthal tilt-torsion angle.
1198 @type phi: float
1199 @param x: The cone opening angle along x.
1200 @type x: float
1201 @param y: The cone opening angle along y.
1202 @type y: float
1203 @return: The theta partial integral.
1204 @rtype: float
1205 """
1206
1207
1208 tmax = tmax_pseudo_ellipse(phi, x, y)
1209
1210
1211 return (2*cos(phi)**2*sin(phi)**2*cos(tmax) + 3*sin(phi)**4 + 3*cos(phi)**4)*sin(tmax)**2 - 8*cos(phi)**2*sin(phi)**2*cos(tmax)
1212
1213
1215 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1216
1217 @param phi: The azimuthal tilt-torsion angle.
1218 @type phi: float
1219 @param x: The cone opening angle along x.
1220 @type x: float
1221 @param y: The cone opening angle along y.
1222 @type y: float
1223 @return: The theta partial integral.
1224 @rtype: float
1225 """
1226
1227
1228 tmax = tmax_pseudo_ellipse(phi, x, y)
1229
1230
1231 return (2*sin(phi)**2 - 2)*cos(tmax)**3 - 3*sin(phi)**2*cos(tmax)**2
1232
1233
1235 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1236
1237 @param phi: The azimuthal tilt-torsion angle.
1238 @type phi: float
1239 @param x: The cone opening angle along x.
1240 @type x: float
1241 @param y: The cone opening angle along y.
1242 @type y: float
1243 @return: The theta partial integral.
1244 @rtype: float
1245 """
1246
1247
1248 tmax = tmax_pseudo_ellipse(phi, x, y)
1249
1250
1251 return (2*sin(phi)**4*cos(tmax) + 6*cos(phi)**2*sin(phi)**2)*sin(tmax)**2 - (2*sin(phi)**4 + 6*cos(phi)**4)*cos(tmax)
1252
1253
1255 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1256
1257 @param phi: The azimuthal tilt-torsion angle.
1258 @type phi: float
1259 @param x: The cone opening angle along x.
1260 @type x: float
1261 @param y: The cone opening angle along y.
1262 @type y: float
1263 @return: The theta partial integral.
1264 @rtype: float
1265 """
1266
1267
1268 tmax = tmax_pseudo_ellipse(phi, x, y)
1269
1270
1271 return 2*sin(phi)**2*cos(tmax)**3 - 6*sin(phi)**2*cos(tmax)
1272
1273
1275 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1276
1277 @param phi: The azimuthal tilt-torsion angle.
1278 @type phi: float
1279 @param x: The cone opening angle along x.
1280 @type x: float
1281 @param y: The cone opening angle along y.
1282 @type y: float
1283 @return: The theta partial integral.
1284 @rtype: float
1285 """
1286
1287
1288 tmax = tmax_pseudo_ellipse(phi, x, y)
1289
1290
1291 return (2*cos(phi)**2 - 2)*cos(tmax)**3 - 3*cos(phi)**2*cos(tmax)**2
1292
1293
1295 """The theta partial integral of the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse.
1296
1297 @param phi: The azimuthal tilt-torsion angle.
1298 @type phi: float
1299 @param x: The cone opening angle along x.
1300 @type x: float
1301 @param y: The cone opening angle along y.
1302 @type y: float
1303 @return: The theta partial integral.
1304 @rtype: float
1305 """
1306
1307
1308 tmax = tmax_pseudo_ellipse(phi, x, y)
1309
1310
1311 return 2 - 2*cos(tmax)**3
1312
1313
1315 """Populate the 1st degree Frame Order matrix in the eigenframe for an isotropic cone.
1316
1317 The cone axis is assumed to be parallel to the z-axis in the eigenframe.
1318
1319 @param matrix: The Frame Order matrix, 1st degree.
1320 @type matrix: numpy 3D, rank-2 array
1321 @param angle: The cone angle.
1322 @type angle: float
1323 """
1324
1325
1326 for i in range(3):
1327 for j in range(3):
1328 matrix[i, j] = 0.0
1329
1330
1331 matrix[2, 2] = (cos(angle) + 1.0) / 2.0
1332
1333
1335 """Populate the 2nd degree Frame Order matrix in the eigenframe for the isotropic cone.
1336
1337 The cone axis is assumed to be parallel to the z-axis in the eigenframe.
1338
1339
1340 @param matrix: The Frame Order matrix, 2nd degree.
1341 @type matrix: numpy 9D, rank-2 array
1342 @param tmax: The cone opening angle.
1343 @type tmax: float
1344 @param smax: The maximum torsion angle.
1345 @type smax: float
1346 """
1347
1348
1349 for i in range(9):
1350 for j in range(9):
1351 matrix[i, j] = 0.0
1352
1353
1354 sinc_smax = sinc(smax/pi)
1355 sinc_2smax = sinc(2.0*smax/pi)
1356 cos_tmax = cos(tmax)
1357 cos_tmax2 = cos_tmax**2
1358
1359
1360 fact_sinc_2smax = sinc_2smax*(cos_tmax2 + 4.0*cos_tmax + 7.0) / 24.0
1361 fact_cos_tmax2 = (cos_tmax2 + cos_tmax + 4.0) / 12.0
1362 fact_cos_tmax = (cos_tmax + 1.0) / 4.0
1363
1364
1365 matrix[0, 0] = fact_sinc_2smax + fact_cos_tmax2
1366 matrix[1, 1] = fact_sinc_2smax + fact_cos_tmax
1367 matrix[2, 2] = sinc_smax * (2.0*cos_tmax2 + 5.0*cos_tmax + 5.0) / 12.0
1368 matrix[3, 3] = matrix[1, 1]
1369 matrix[4, 4] = matrix[0, 0]
1370 matrix[5, 5] = matrix[2, 2]
1371 matrix[6, 6] = matrix[2, 2]
1372 matrix[7, 7] = matrix[2, 2]
1373 matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0
1374
1375
1376 matrix[0, 4] = matrix[4, 0] = -fact_sinc_2smax + fact_cos_tmax2
1377 matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0
1378 matrix[4, 8] = matrix[8, 4] = matrix[0, 8]
1379
1380
1381 matrix[1, 3] = matrix[3, 1] = fact_sinc_2smax - fact_cos_tmax
1382 matrix[2, 6] = matrix[6, 2] = sinc_smax * (cos_tmax2 + cos_tmax - 2.0) / 6.0
1383 matrix[5, 7] = matrix[7, 5] = matrix[2, 6]
1384
1385
1387 """Populate the 2nd degree Frame Order matrix in the eigenframe for the free rotor isotropic cone.
1388
1389 The cone axis is assumed to be parallel to the z-axis in the eigenframe. In this model, the three order parameters are defined as::
1390
1391 S1 = S2,
1392 S3 = 0
1393
1394 This is in the Kronecker product form.
1395
1396
1397 @param matrix: The Frame Order matrix, 2nd degree.
1398 @type matrix: numpy 9D, rank-2 array
1399 @param s1: The cone order parameter.
1400 @type s1: float
1401 """
1402
1403
1404 for i in range(9):
1405 for j in range(9):
1406 matrix[i, j] = 0.0
1407
1408
1409 matrix[0, 0] = matrix[4, 4] = (s1 + 2.0) / 6.0
1410 matrix[0, 4] = matrix[4, 0] = matrix[0, 0]
1411
1412
1413 matrix[8, 8] = (2.0*s1 + 1.0) / 3.0
1414
1415
1416 matrix[0, 8] = matrix[8, 0] = (1.0 - s1) / 3.0
1417 matrix[4, 8] = matrix[8, 4] = matrix[0, 8]
1418
1419
1420 theta = order_parameters.iso_cone_S_to_theta(s1)
1421
1422
1423 matrix[1, 1] = matrix[3, 3] = (cos(theta) + 1.0) / 4.0
1424 matrix[1, 3] = matrix[3, 1] = -matrix[1, 1]
1425
1426
1428 """Calculate the reduction in the alignment tensor caused by the Frame Order matrix.
1429
1430 This is both the forward rotation notation and Kronecker product arrangement.
1431
1432 @param D: The Frame Order matrix, 2nd degree to be populated.
1433 @type D: numpy 9D, rank-2 array
1434 @param A: The full alignment tensor in {Axx, Ayy, Axy, Axz, Ayz} notation.
1435 @type A: numpy 5D, rank-1 array
1436 @param red_tensor: The structure in {Axx, Ayy, Axy, Axz, Ayz} notation to place the reduced
1437 alignment tensor.
1438 @type red_tensor: numpy 5D, rank-1 array
1439 """
1440
1441
1442 red_tensor[0] = (D[0, 0] - D[0, 8])*A[0]
1443 red_tensor[0] = red_tensor[0] + (D[0, 4] - D[0, 8])*A[1]
1444 red_tensor[0] = red_tensor[0] + (D[0, 1] + D[0, 3])*A[2]
1445 red_tensor[0] = red_tensor[0] + (D[0, 2] + D[0, 6])*A[3]
1446 red_tensor[0] = red_tensor[0] + (D[0, 5] + D[0, 7])*A[4]
1447
1448
1449 red_tensor[1] = (D[4, 0] - D[4, 8])*A[0]
1450 red_tensor[1] = red_tensor[1] + (D[4, 4] - D[4, 8])*A[1]
1451 red_tensor[1] = red_tensor[1] + (D[4, 1] + D[4, 3])*A[2]
1452 red_tensor[1] = red_tensor[1] + (D[4, 2] + D[4, 6])*A[3]
1453 red_tensor[1] = red_tensor[1] + (D[4, 5] + D[4, 7])*A[4]
1454
1455
1456 red_tensor[2] = (D[1, 0] - D[1, 8])*A[0]
1457 red_tensor[2] = red_tensor[2] + (D[1, 4] - D[1, 8])*A[1]
1458 red_tensor[2] = red_tensor[2] + (D[1, 1] + D[1, 3])*A[2]
1459 red_tensor[2] = red_tensor[2] + (D[1, 2] + D[1, 6])*A[3]
1460 red_tensor[2] = red_tensor[2] + (D[1, 5] + D[1, 7])*A[4]
1461
1462
1463 red_tensor[3] = (D[2, 0] - D[2, 8])*A[0]
1464 red_tensor[3] = red_tensor[3] + (D[2, 4] - D[2, 8])*A[1]
1465 red_tensor[3] = red_tensor[3] + (D[2, 1] + D[2, 3])*A[2]
1466 red_tensor[3] = red_tensor[3] + (D[2, 2] + D[2, 6])*A[3]
1467 red_tensor[3] = red_tensor[3] + (D[2, 5] + D[2, 7])*A[4]
1468
1469
1470 red_tensor[4] = (D[5, 0] - D[5, 8])*A[0]
1471 red_tensor[4] = red_tensor[4] + (D[5, 4] - D[5, 8])*A[1]
1472 red_tensor[4] = red_tensor[4] + (D[5, 1] + D[5, 3])*A[2]
1473 red_tensor[4] = red_tensor[4] + (D[5, 2] + D[5, 6])*A[3]
1474 red_tensor[4] = red_tensor[4] + (D[5, 5] + D[5, 7])*A[4]
1475
1476
1478 """Calculate the reduction in the alignment tensor caused by the Frame Order matrix.
1479
1480 This is both the forward rotation notation and Kronecker product arrangement. This simplification is due to the symmetry in motion of the pseudo-elliptic and isotropic cones. All element of the frame order matrix where an index appears only once are zero.
1481
1482 @param D: The Frame Order matrix, 2nd degree to be populated.
1483 @type D: numpy 9D, rank-2 array
1484 @param A: The full alignment tensor in {Axx, Ayy, Axy, Axz, Ayz} notation.
1485 @type A: numpy 5D, rank-1 array
1486 @param red_tensor: The structure in {Axx, Ayy, Axy, Axz, Ayz} notation to place the reduced
1487 alignment tensor.
1488 @type red_tensor: numpy 5D, rank-1 array
1489 """
1490
1491
1492 red_tensor[0] = (D[0, 0] - D[0, 8])*A[0] + (D[0, 4] - D[0, 8])*A[1]
1493 red_tensor[1] = (D[4, 0] - D[4, 8])*A[0] + (D[4, 4] - D[4, 8])*A[1]
1494 red_tensor[2] = (D[1, 1] + D[1, 3])*A[2]
1495 red_tensor[3] = (D[2, 2] + D[2, 6])*A[3]
1496 red_tensor[4] = (D[5, 5] + D[5, 7])*A[4]
1497
1498
1500 """Rotate the given frame order matrix.
1501
1502 It is assumed that the frame order matrix is in the Kronecker product form.
1503
1504
1505 @param matrix: The Frame Order matrix, 2nd degree to be populated.
1506 @type matrix: numpy 9D, rank-2 array
1507 @param R: The rotation matrix to be populated.
1508 @type R: numpy 3D, rank-2 array
1509 """
1510
1511
1512 R_kron = kron_prod(R, R)
1513
1514
1515 matrix_rot = dot(R_kron, dot(matrix, transpose(R_kron)))
1516
1517
1518 return matrix_rot
1519
1520
1522 """The pseudo-ellipse tilt-torsion polar angle.
1523
1524 @param phi: The azimuthal tilt-torsion angle.
1525 @type phi: float
1526 @param theta_x: The cone opening angle along x.
1527 @type theta_x: float
1528 @param theta_y: The cone opening angle along y.
1529 @type theta_y: float
1530 @return: The theta max angle for the given phi angle.
1531 @rtype: float
1532 """
1533
1534
1535 if theta_x == 0.0:
1536 return 0.0
1537 elif theta_y == 0.0:
1538 return 0.0
1539
1540
1541 return theta_x * theta_y / sqrt((cos(phi)*theta_y)**2 + (sin(phi)*theta_x)**2)
1542