JDFTx  1.2.0
Euler.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_FLUID_EULER_H
21 #define JDFTX_FLUID_EULER_H
22 
25 
33 #include <cmath>
34 #include <gsl/gsl_sf_gamma.h>
35 #include <gsl/gsl_sf_pow_int.h>
36 #include <core/matrix3.h>
37 
39 inline vector3<> polarUnitVector(double alpha, double beta)
40 { double sBeta = sin(beta);
41  return vector3<>(sBeta*cos(alpha), sBeta*sin(alpha), cos(beta));
42 }
43 
45 inline void getEulerAxis(const vector3<>& newZ, vector3<>& euler)
46 { euler[1] = acos(newZ[2]/newZ.length());
47  if(euler[1]*(M_PI-euler[1]) < 1e-6) //beta = 0 or pi
48  { euler[0] = 0.0; //alpha is meaningless
49  }
50  else
51  { euler[0] = atan2(newZ[1], newZ[0]);
52  }
53 }
54 
56 inline matrix3<> matrixFromEuler(const vector3<>& euler)
57 { return rotation(euler[0], 2) //R_Z(alpha)
58  * rotation(euler[1], 1) //R_Y(beta)
59  * rotation(euler[2], 2); //R_Z(gamma)
60 }
61 
64 { if(fabs(mat(2,2))>1.-1e-7) //beta is 0 or pi and only gamma+/-alpha is determined (set alpha=0 w.l.og)
65  return vector3<>(0., //alpha (set 0 w.l.o.g)
66  (mat(2,2)>0 ? 0. : M_PI), //beta
67  atan2(-mat(1,0),mat(1,1)) ); //gamma
68  else
69  return vector3<>( atan2(mat(1,2),-mat(0,2)), //alpha
70  acos(mat(2,2)), //beta
71  atan2(mat(2,1),mat(2,0)) ); //gamma
72 }
73 
74 
76 inline double wigner_d(const int j, const int m1, const int m2, const double beta)
77 { int t1 = j+m1;
78  int t2 = j-m2;
79  int t3 = m2-m1;
80  int t4 = 2*j + m1 - m2;
81 
82  int sMin = (-t3 < 0) ? 0 : -t3;
83  int sMax = (t2 < t1) ? t2 : t1;
84 
85  double cosbeta = cos(beta * 0.5);
86  double sinbeta = sin(beta * 0.5);
87  double a = 0.5*(gsl_sf_lnfact(t1) + gsl_sf_lnfact(t2) + gsl_sf_lnfact(j-m1) + gsl_sf_lnfact(j+m2));
88 
89  double result = 0.0;
90  double sign = (sMin % 2 ? -1.0 : 1.0);
91  for(int s = sMin; s <= sMax; s++)
92  { result += copysign(gsl_sf_pow_int(cosbeta, t4-2*s) * gsl_sf_pow_int(sinbeta, t3+2*s)
93  * exp(a - (gsl_sf_lnfact(t1 - s) + gsl_sf_lnfact(t2 - s) + gsl_sf_lnfact(t3 + s) + gsl_sf_lnfact(s))), sign);
94  sign = -sign;
95  }
96  return result;
97 }
98 
99 
101 
102 #endif // JDFTX_FLUID_EULER_H
void getEulerAxis(const vector3<> &newZ, vector3<> &euler)
Calculates euler[0]=alpha and euler[1]=beta given newZ, the direction of the Z-axis in the rotated fr...
Definition: Euler.h:45
vector3 eulerFromMatrix(const matrix3<> &mat)
Calculate euler angles from rotation matrices.
Definition: Euler.h:63
ScalarField exp(const ScalarField &)
Elementwise exponential (preserve input)
vector3 polarUnitVector(double alpha, double beta)
Get the position of the new Z-axis, given alpha and beta (does not depend on gamma) ...
Definition: Euler.h:39
matrix3 matrixFromEuler(const vector3<> &euler)
Calculate rotation matrices from euler angles.
Definition: Euler.h:56
double wigner_d(const int j, const int m1, const int m2, const double beta)
Wigner d-function d^j_{m1 m2}(beta) for ZYZ Euler angles.
Definition: Euler.h:76