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