| [729] | 1 | #ifndef LAMBDABUILDER_SEEN | 
|---|
|  | 2 | #define LAMBDABUILDER_SEEN | 
|---|
|  | 3 |  | 
|---|
|  | 4 | #include <math.h> | 
|---|
|  | 5 | #include "ndatablock.h" | 
|---|
|  | 6 | #include "tvector.h" | 
|---|
|  | 7 | #include "alm.h" | 
|---|
|  | 8 |  | 
|---|
| [864] | 9 |  | 
|---|
|  | 10 | namespace SOPHYA { | 
|---|
|  | 11 |  | 
|---|
| [729] | 12 | /*! | 
|---|
|  | 13 | generate Legendre polynomials : use in two steps : | 
|---|
|  | 14 |  | 
|---|
|  | 15 | a) instanciate Legendre(\f$x\f$, \f$lmax\f$) ; \f$x\f$ is the value for wich Legendre polynomials will be required (usually equal to \f$\cos \theta\f$) and \f$lmax\f$ is the MAXIMUM value of the order of polynomials wich will be required in the following code (all polynomials, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula). | 
|---|
|  | 16 |  | 
|---|
|  | 17 | b) get the value of Legendre polynomial for a particular value of \f$l\f$ by calling the method getPl. | 
|---|
|  | 18 | */ | 
|---|
|  | 19 | class Legendre { | 
|---|
|  | 20 |  | 
|---|
|  | 21 | public : | 
|---|
|  | 22 | Legendre(); | 
|---|
|  | 23 | Legendre(r_8 x, int_4 lmax); | 
|---|
|  | 24 | inline r_8 getPl(int_4 l) | 
|---|
|  | 25 | { | 
|---|
|  | 26 | if (l>lmax_) | 
|---|
|  | 27 | { | 
|---|
|  | 28 | throw (" illegal call of Legendre::getPl with index greater than lmax, which Legendre Class was instanciated with : instanciate Legendre with a greater lmax... "); | 
|---|
|  | 29 | } | 
|---|
|  | 30 | return Pl_(l); | 
|---|
|  | 31 | } | 
|---|
|  | 32 |  | 
|---|
|  | 33 | private : | 
|---|
|  | 34 | /*! compute all \f$P_l(x,l_{max})\f$ for \f$l=1,l_{max}\f$ */ | 
|---|
|  | 35 | void array_init(int_4 lmax); | 
|---|
|  | 36 |  | 
|---|
|  | 37 | r_8 x_; | 
|---|
|  | 38 | int_4 lmax_; | 
|---|
|  | 39 | TVector<r_8> Pl_; | 
|---|
|  | 40 | }; | 
|---|
|  | 41 |  | 
|---|
|  | 42 |  | 
|---|
|  | 43 |  | 
|---|
|  | 44 | /*! | 
|---|
|  | 45 | This class generate the coefficients : | 
|---|
|  | 46 | \f[ | 
|---|
|  | 47 | \lambda_l^m=\sqrt{\frac{2l+1}{4\pi}\frac{(l-m)!}{(l+m)!}} | 
|---|
|  | 48 | P_l^m(\cos{\theta}) | 
|---|
|  | 49 | \f] | 
|---|
|  | 50 | where \f$P_l^m\f$ are the associated Legendre polynomials.  The above coefficients contain the theta-dependance of spheric harmonics : | 
|---|
|  | 51 | \f[ | 
|---|
|  | 52 | Y_{lm}(\cos{\theta})=\lambda_l^m(\cos{\theta}) e^{im\phi}. | 
|---|
|  | 53 | \f] | 
|---|
|  | 54 |  | 
|---|
|  | 55 | Each object has a fixed theta (radians), and maximum l and m to be calculated | 
|---|
|  | 56 | (lmax and mmax). | 
|---|
|  | 57 | use the class in two steps : | 
|---|
|  | 58 | a) instanciate  LambdaLMBuilder(\f$\theta\f$, \f$lmax\f$, \f$mmax\f$) ;  \f$lmax\f$ and \f$mmax\f$ are  MAXIMUM values for which \f$\lambda_l^m\f$ will be required in the following code (all coefficients, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula). | 
|---|
|  | 59 | b) get the values of coefficients for  particular values of \f$l\f$ and \f$m\f$ by calling the method lamlm. | 
|---|
|  | 60 | */ | 
|---|
|  | 61 | class LambdaLMBuilder { | 
|---|
|  | 62 |  | 
|---|
|  | 63 | public: | 
|---|
|  | 64 |  | 
|---|
|  | 65 | LambdaLMBuilder() {} | 
|---|
|  | 66 | LambdaLMBuilder(r_8 theta,int_4 lmax, int_4 mmax); | 
|---|
| [864] | 67 | virtual ~LambdaLMBuilder() {}; | 
|---|
| [729] | 68 |  | 
|---|
|  | 69 | /*! return the value of the coefficient \f$  \lambda_l^m \f$ */ | 
|---|
|  | 70 | inline double lamlm(int l, int m) const { return lambda_(l,m); } | 
|---|
|  | 71 |  | 
|---|
|  | 72 | private: | 
|---|
|  | 73 | /*! compute a static array of coefficients independant from theta (common to all instances of the LambdaBuilder Class */ | 
|---|
|  | 74 | void updateArrayRecurrence(int_4 lmax); | 
|---|
|  | 75 |  | 
|---|
|  | 76 | void array_init(int lmax, int mmax); | 
|---|
|  | 77 |  | 
|---|
|  | 78 |  | 
|---|
|  | 79 | static TriangularMatrix<r_8>* a_recurrence_; | 
|---|
|  | 80 | TriangularMatrix<r_8> lambda_; | 
|---|
|  | 81 |  | 
|---|
|  | 82 | protected : | 
|---|
|  | 83 |  | 
|---|
|  | 84 | /*! compute  static arrays of coefficients independant from theta (common to all instances of the derived  classes */ | 
|---|
|  | 85 | void updateArrayLamNorm(); | 
|---|
|  | 86 |  | 
|---|
|  | 87 | static  TriangularMatrix<r_8>* lam_fact_; | 
|---|
|  | 88 | static  TVector<r_8>*  normal_l_; | 
|---|
|  | 89 | int_4 lmax_; | 
|---|
|  | 90 | int_4 mmax_; | 
|---|
|  | 91 | r_8 cth_; | 
|---|
|  | 92 | r_8 sth_; | 
|---|
|  | 93 |  | 
|---|
|  | 94 | }; | 
|---|
|  | 95 |  | 
|---|
|  | 96 |  | 
|---|
|  | 97 |  | 
|---|
|  | 98 | /*! | 
|---|
|  | 99 |  | 
|---|
|  | 100 | This class generates the coefficients : | 
|---|
|  | 101 | \f[ | 
|---|
|  | 102 | _{w}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}} G^+_{lm} | 
|---|
|  | 103 | \f] | 
|---|
|  | 104 | \f[ | 
|---|
|  | 105 | _{x}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}G^-_{lm} | 
|---|
|  | 106 | \f] | 
|---|
|  | 107 | where | 
|---|
|  | 108 | \f[G^+_{lm}(\cos{\theta})=-\left( \frac{l-m^2}{\sin^2{\theta}}+\frac{1}{2}l\left(l-1\right)\right)P_l^m(\cos{\theta})+\left(l+m\right)\frac{\cos{\theta}}{\sin^2{\theta}}P^m_{l-1}(\cos{\theta}) | 
|---|
|  | 109 | \f] | 
|---|
|  | 110 | and | 
|---|
|  | 111 | \f[G^-_{lm}(\cos{\theta})=\frac{m}{\sin^2{\theta}}\left(\left(l-1\right)\cos{\theta}P^m_l(\cos{\theta})-\left(l+m\right)P^m_{l-1}(\cos{\theta})\right) | 
|---|
|  | 112 | \f] | 
|---|
|  | 113 | \f$P_l^m\f$ are the associated Legendre polynomials. | 
|---|
|  | 114 |  | 
|---|
|  | 115 | The coefficients express the theta-dependance of the \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ functions : | 
|---|
|  | 116 | \f[W_{lm}(\cos{\theta}) = \sqrt{\frac{(l+2)!}{2(l-2)!}}_w\lambda_l^m(\cos{\theta})e^{im\phi} | 
|---|
|  | 117 | \f] | 
|---|
|  | 118 | \f[X_{lm}(\cos{\theta}) = -i\sqrt{\frac{(l+2)!}{2(l-2)!}}_x\lambda_l^m(\cos{\theta})e^{im\phi} | 
|---|
|  | 119 | \f] | 
|---|
|  | 120 | where \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ are defined as : | 
|---|
|  | 121 |  | 
|---|
|  | 122 | \f[ | 
|---|
|  | 123 | W_{lm}(\cos{\theta})=-\frac{1}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left( | 
|---|
|  | 124 | _{+2}Y_l^m(\cos{\theta})+_{-2}Y_l^m(\cos{\theta})\right) | 
|---|
|  | 125 | \f] | 
|---|
|  | 126 | \f[X_{lm}(\cos{\theta})=-\frac{i}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left( | 
|---|
|  | 127 | _{+2}Y_l^m(\cos{\theta})-_{-2}Y_l^m(\cos{\theta})\right) | 
|---|
|  | 128 | \f] | 
|---|
|  | 129 |  | 
|---|
|  | 130 | */ | 
|---|
|  | 131 | class LambdaWXBuilder : public LambdaLMBuilder | 
|---|
|  | 132 | { | 
|---|
|  | 133 | public: | 
|---|
|  | 134 |  | 
|---|
|  | 135 |  | 
|---|
|  | 136 | LambdaWXBuilder() {} | 
|---|
|  | 137 |  | 
|---|
|  | 138 | LambdaWXBuilder(r_8 theta, int_4 lmax, int_4 mmax); | 
|---|
|  | 139 |  | 
|---|
|  | 140 | /*! return the value of the coefficients \f$ _{w}\lambda_l^m\f$ and \f$_{x}\lambda_l^m\f$ */ | 
|---|
|  | 141 | inline void lam_wx(int l, int m, r_8& w, r_8& x) const | 
|---|
|  | 142 | { | 
|---|
|  | 143 | w=lamWlm_(l,m); | 
|---|
|  | 144 | x=lamXlm_(l,m); | 
|---|
|  | 145 | } | 
|---|
|  | 146 |  | 
|---|
|  | 147 | private: | 
|---|
|  | 148 |  | 
|---|
|  | 149 | void array_init(); | 
|---|
|  | 150 |  | 
|---|
|  | 151 |  | 
|---|
|  | 152 | TriangularMatrix<r_8> lamWlm_; | 
|---|
|  | 153 | TriangularMatrix<r_8> lamXlm_; | 
|---|
|  | 154 |  | 
|---|
|  | 155 |  | 
|---|
|  | 156 | }; | 
|---|
|  | 157 |  | 
|---|
|  | 158 | /*! | 
|---|
|  | 159 |  | 
|---|
|  | 160 | This class generates the coefficients | 
|---|
|  | 161 | \f[ | 
|---|
|  | 162 | _{\pm}\lambda_l^m=2\sqrt{\frac{(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}\left( G^+_{lm} \mp G^-_{lm}\right) | 
|---|
|  | 163 | \f] | 
|---|
|  | 164 | where | 
|---|
|  | 165 | \f[G^+_{lm}(\cos{\theta})=-\left( \frac{l-m^2}{\sin^2{\theta}}+\frac{1}{2}l\left(l-1\right)\right)P_l^m(\cos{\theta})+\left(l+m\right)\frac{\cos{\theta}}{\sin^2{\theta}}P^m_{l-1}(\cos{\theta}) | 
|---|
|  | 166 | \f] | 
|---|
|  | 167 | and | 
|---|
|  | 168 | \f[G^-_{lm}(\cos{\theta})=\frac{m}{\sin^2{\theta}}\left(\left(l-1\right)\cos{\theta}P^m_l(\cos{\theta})-\left(l+m\right)P^m_{l-1}(\cos{\theta})\right) | 
|---|
|  | 169 | \f] | 
|---|
|  | 170 | and \f$P_l^m\f$ are the associated Legendre polynomials. | 
|---|
|  | 171 | The coefficients express the theta-dependance of the  spin-2 spherical harmonics : | 
|---|
|  | 172 | \f[_{\pm2}Y_l^m(\cos{\theta})=_\pm\lambda_l^m(\cos{\theta})e^{im\phi} | 
|---|
|  | 173 | \f] | 
|---|
|  | 174 | */ | 
|---|
|  | 175 | class LambdaPMBuilder : public LambdaLMBuilder | 
|---|
|  | 176 | { | 
|---|
|  | 177 | public: | 
|---|
|  | 178 |  | 
|---|
|  | 179 | LambdaPMBuilder() {} | 
|---|
|  | 180 |  | 
|---|
|  | 181 | LambdaPMBuilder(r_8 theta, int_4 lmax, int_4 mmax); | 
|---|
|  | 182 | /*! return the value of the coefficients \f$ _{+}\lambda_l^m\f$ and \f$_{-}\lambda_l^m\f$ */ | 
|---|
|  | 183 | inline void lam_pm(int l, int m, r_8& lambda_plus, r_8& lambda_moins) const | 
|---|
|  | 184 | { | 
|---|
|  | 185 | lambda_plus = lamPlm_(l,m); | 
|---|
|  | 186 | lambda_moins = lamMlm_(l,m); | 
|---|
|  | 187 | } | 
|---|
|  | 188 |  | 
|---|
|  | 189 | private: | 
|---|
|  | 190 | void array_init(); | 
|---|
|  | 191 |  | 
|---|
|  | 192 | TriangularMatrix<r_8> lamPlm_; | 
|---|
|  | 193 | TriangularMatrix<r_8> lamMlm_; | 
|---|
|  | 194 |  | 
|---|
| [864] | 195 | }; | 
|---|
| [729] | 196 |  | 
|---|
| [864] | 197 | } // Fin du namespace | 
|---|
| [729] | 198 |  | 
|---|
|  | 199 | #endif | 
|---|