LevelS C++ support library  3.82
wigner.h
Go to the documentation of this file.
1 /*
2  * This file is part of libcxxsupport.
3  *
4  * libcxxsupport is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * libcxxsupport is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with libcxxsupport; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
21  * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
22  * (DLR).
23  */
24 
25 /*! \file wigner.h
26  * Several C++ classes for calculating Wigner matrices
27  *
28  * Copyright (C) 2009-2011 Max-Planck-Society
29  * \author Martin Reinecke and others (see individual classes)
30  */
31 
32 #ifndef PLANCK_WIGNER_H
33 #define PLANCK_WIGNER_H
34 
35 #include <cmath>
36 #include "arr.h"
37 
38 #include "sse_utils_cxx.h"
39 
40 /*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
41  in a way that cannot easily be parallelised, but is fairly efficient on
42  scalar machines. */
44  {
45  private:
46  double pq;
47  arr<double> sqt;
48  arr2<double> d;
49  int n;
50 
51  void do_line0 (double *l1, int j);
52  void do_line (const double *l1, double *l2, int j, int k);
53 
54  public:
56 
57  const arr2<double> &recurse ();
58  };
59 
60 /*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
61  recursion in a way that cannot easily be parallelised, but is fairly
62  efficient on scalar machines. */
64  {
65  private:
66  double p,q;
67  arr<double> sqt;
68  arr2<double> d;
69  int n;
70 
71  void do_line0 (double *l1, int j);
72  void do_line (const double *l1, double *l2, int j, int k);
73 
74  public:
75  wigner_d_risbo_scalar(int lmax, double ang);
76 
77  const arr2<double> &recurse ();
78  };
79 
80 /*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
81  in a way that can be OpenMP-parallelised. This approach uses more memory
82  and is slightly slower than wigner_d_halfpi_risbo_scalar. */
84  {
85  private:
86  double pq;
87  arr<double> sqt;
88  arr2<double> d,dd;
89  int n;
90 
91  public:
93 
94  const arr2<double> &recurse ();
95  };
96 
97 /*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
98  recursion in a way that can be OpenMP-parallelised. This approach uses more
99  memory and is slightly slower than wigner_d_risbo_scalar. */
101  {
102  private:
103  double p,q;
104  arr<double> sqt;
105  arr2<double> d, dd;
106  int n;
107 
108  public:
109  wigner_d_risbo_openmp(int lmax, double ang);
110 
111  const arr2<double> &recurse ();
112  };
113 
114 /*! Class for calculation of the Wigner matrix elements by l-recursion.
115  For details, see Prezeau & Reinecke 2010, http://arxiv.org/pdf/1002.1050 */
117  {
118  protected:
119  typedef double dbl3[3];
120 
121  // members set in the constructor and kept fixed afterwards
122  double fsmall, fbig, eps;
123  int lmax;
124  arr<long double> logsum, lc05, ls05;
125  arr<double> flm1, flm2, cf, costh, xl;
126  arr<bool> thetaflip;
127 
128  // members depending on m and m'
129  int m1, m2, am1, am2, mlo, mhi, cosPow, sinPow;
130  long double prefactor;
131  arr<dbl3> fx;
132  bool preMinus;
133 
134  // members depending on theta
135  arr<double> result;
136 
137  enum { large_exponent2=90, minscale=-4, maxscale=14 };
138 
139  public:
140  /*! Constructs an object that can compute Wigner matrix elements up
141  to a maximum \a l value of \a lmax_, at the colatitudes provided
142  in \a thetas. The generator will be allowed to regard values with
143  absolute magnitudes smaller than \a epsilon as zero; a typical value
144  is 1e-30. */
145  wignergen_scalar (int lmax_, const arr<double> &thetas, double epsilon);
146 
147  /*! Prepares the object to produce Wigner matrix elements with \a m=m1_
148  and \a m'=m2_ in subsequent calls to calc(). This operation is not cheap
149  so it is recommended to use calc() for many different colatitudes after
150  every call to prepare(), if possible. */
151  void prepare (int m1_, int m2_);
152 
153  /*! Computes the Wigner matrix elements for the values of \a m and \a m'
154  set by the preceding call to prepare(), for all \a l up to \a lmax
155  (set in the constructor), and for the \a nth colatitude passed to the
156  constructor. On return, \a firstl contains the index of the first
157  matrix element larger than \a epsilon; all values with smaller indices
158  in the result array are undefined. */
159  const arr<double> &calc (int nth, int &firstl);
160  void calc (int nth, int &firstl, arr<double> &resx) const;
161  };
162 
163 class wignergen: public wignergen_scalar
164  {
165 #ifdef __SSE2__
166  private:
167  arr_align<V2df,16> result2;
168 
169  public:
170  wignergen (int lmax_, const arr<double> &thetas, double epsilon)
171  : wignergen_scalar (lmax_,thetas,epsilon), result2(lmax_+1) {}
172 
174  const arr_align<V2df,16> &calc (int nth1, int nth2, int &firstl);
175  void calc (int nth1, int nth2, int &firstl, arr_align<V2df,16> &resx) const;
176 #else
177  public:
178  wignergen (int lmax_, const arr<double> &thetas, double epsilon)
179  : wignergen_scalar (lmax_,thetas,epsilon) {}
180 #endif
181  };
182 
183 class wigner_estimator
184  {
185  private:
186  int lmax, m1, m2, mbig;
187  double xlmax, epsPow, cosm1m2;
188 
189  public:
190  wigner_estimator (int lmax_, double epsPow_);
191 
192  void prepare_m (int m1_, int m2_);
193  bool canSkip (double theta) const;
194  };
195 
196 #endif
Definition: arr.h:329
void prepare(int m1_, int m2_)
Definition: wigner.cc:311
wignergen_scalar(int lmax_, const arr< double > &thetas, double epsilon)
Definition: wigner.cc:265
const arr< double > & calc(int nth, int &firstl)
Definition: wigner.cc:361

Generated on Thu Jul 28 2022 17:32:06 for LevelS C++ support library