CMS 3D CMS Logo

rz_harm_poly.cc
Go to the documentation of this file.
1 #include <typeinfo>
2 #include "rz_harm_poly.h"
3 #include <cstdlib>
4 
5 using namespace magfieldparam;
6 
8 // //
9 // Harmonic homogeneous polynomials in cylindrical system. //
10 // //
12 
13 //_______________________________________________________________________________
14 unsigned rz_harm_poly::Cnt = 0; //Number of the "rz_harm_poly" objects
15 double rz_harm_poly::phival = -11111.;//Last phi value used
16 bool rz_harm_poly::phi_set = false; //TRUE if phi value is set
17 unsigned rz_harm_poly::MaxM = 0; //Max. M among "rz_harm_poly" objects
18 
19 unsigned rz_harm_poly::TASize = 0; //TrigArr size
20 trig_pair *rz_harm_poly::TrigArr = nullptr; //Array with angular data
21 
22 //_______________________________________________________________________________
24 {
25 //Constructor for rz_harm_poly of length N. The polynomial P(r,z) is normalized
26 //in such a way that dP/dz(r=0,z)=z^(N-1)
27 //
28  unsigned nz = N, nr = 0, nv = 0;
29  poly2d_term v3(1./N, nr, nz);
30 
31  data = std::vector<poly2d_term>((N + 2) / 2, v3);
32 
33  while (nz >= 2) {
34  nz -= 2;
35  nr += 2;
36  nv += 1;
37  data[nv].coeff = -data[nv-1].coeff*(nz+1)*(nz+2)/(nr*nr);
38  data[nv].np[0] = nr;
39  data[nv].np[1] = nz;
40  }
41  max_pwr = N;
42  if (max_pwr > NPwr) {
43  NPwr = max_pwr;
44  rz_set = false;
45  phi_set = false;
46  }
47  L = N;
48  M = 0;
49  poly2d_base_set.insert(this);
50  ++Cnt;
51 }
52 
53 //_______________________________________________________________________________
55 {
56  if (--Cnt) {
57  if (std::abs(M) >= int(MaxM)) { //a number of objects still left
58  M = 0;
59  MaxM = GetMaxM();
60  }
61  } else { //last instance -> memory cleanup
62  if (TrigArr) delete [] TrigArr;
63  TrigArr = nullptr;
64  TASize = 0;
65  MaxM = 0;
66  phival = -11111.;
67  phi_set = false;
68  }
69 }
70 
71 //_______________________________________________________________________________
73 {
74 //Return max abs(M) for all rz_harm_poly objects created
75 //
76  int M_cur, M_max = 0;
77  std::set<poly2d_base*>::iterator it;
78  for (it = poly2d_base_set.begin(); it != poly2d_base_set.end(); ++it) {
79  if (typeid(**it) == typeid(rz_harm_poly)) {
80  M_cur = std::abs(((rz_harm_poly*)(*it))->M);
81  if (M_cur > M_max) M_max = M_cur;
82  }
83  }
84  return M_max;
85 }
86 
87 //_______________________________________________________________________________
88 void rz_harm_poly::SetPhi(const double phi)
89 {
90 //Set value of the angle argument, adjust the TrigArr size if neccessary
91 //and fill TrigArr if the phi value is changed
92 //
93  if (MaxM >= TASize) { SetTrigArrSize(MaxM+1); FillTrigArr(phi);}
94  else if (phi != phival) FillTrigArr(phi);
95  phival = phi;
96  phi_set = true;
97 }
98 
99 //_______________________________________________________________________________
100 void rz_harm_poly::SetTrigArrSize(const unsigned N)
101 {
102 //Increase TrigArr size if neccessary
103 //
104  if (N <= TASize) return;
105  if (TrigArr) delete [] TrigArr;
106  TrigArr = new trig_pair [N];
107  (*TrigArr) = trig_pair(1., 0.);
108  TASize = N;
109  phi_set = false;
110 }
111 
112 //_______________________________________________________________________________
113 void rz_harm_poly::FillTrigArr(const double phi)
114 {
115 //Fill TrigArr with trig_pair(jp*phi)
116  if (!TrigArr) return;
117  trig_pair tp(phi);
118  TrigArr[1] = tp;
119  for (unsigned jp = 2; jp <= MaxM; ++jp) TrigArr[jp] = TrigArr[jp-1].Add(tp);
120 }
121 
122 //_______________________________________________________________________________
123 void rz_harm_poly::PrintTrigArr(std::ostream &out, const std::streamsize prec)
124 {
125  out << "TrigArr: TASize = " << TASize
126  << "\tMaxM = " << MaxM << std::endl;
127  if (TrigArr) {
128  if (MaxM < TASize) {
129  unsigned jm;
130  std::streamsize old_prec = out.precision(), wdt = prec+7;
131  out.precision(prec);
132  out << "M: ";
133  for (jm = 0; jm <= MaxM; ++jm) {
134  out << std::setw(wdt) << std::left << jm;
135  }
136  out << "|\nCos_M: ";
137  for (jm = 0; jm <= MaxM; ++jm) {
138  out << std::setw(wdt) << std::left << TrigArr[jm].CosPhi;
139  }
140  out << "|\nSin_M: ";
141  for (jm = 0; jm <= MaxM; ++jm) {
142  out << std::setw(wdt) << std::left << TrigArr[jm].SinPhi;
143  }
144  out << "|" << std::endl;
145  out.precision(old_prec);
146  } else {
147  out << "\tTrigArr size is not adjusted." << std::endl;
148  }
149  } else {
150  out << "\tTrigArr is not allocated." << std::endl;
151  }
152 }
153 
154 //_______________________________________________________________________________
156 {
157 //Return a polynomial with increased M
158 //
159  rz_harm_poly p_out; p_out.data.reserve(2*L);
160  unsigned it;
161  poly2d_term term;
162 
163  //In 2 passes (for-cycles) to get terms in z-descending order
164  for(it = 0; it < data.size(); ++it) {
165  term = data[it];
166  if (term.np[0]) {
167  term.coeff *= int(term.np[0]) - M;
168  --term.np[0];
169  ++term.np[1];
170  p_out.data.push_back(term);
171  }
172  }
173  for(it = 0; it < data.size(); ++it) {
174  term = data[it];
175  if (term.np[1]) {
176  term.coeff *= -(int)term.np[1];
177  --term.np[1];
178  ++term.np[0];
179  p_out.data.push_back(term);
180  }
181  }
182  p_out.Collect();
183  if (!p_out.data.empty()) {
184  p_out.L = L;
185  p_out.M = M+1;
186  if (std::abs(p_out.M) > int(MaxM)) MaxM = std::abs(p_out.M);
187  p_out.Scale(1./sqrt(double((L-M)*(L+M+1))));
188  }
189  return p_out;
190 }
191 
192 //_______________________________________________________________________________
194 {
195 //Return a polynomial with decreased M
196 //
197  rz_harm_poly p_out; p_out.data.reserve(2*L);
198  unsigned it;
199  poly2d_term term;
200 
201  //In 2 passes (for-cycles) to get terms in z-descending order
202  for(it = 0; it < data.size(); ++it) {
203  term = data[it];
204  if (term.np[0]) {
205  term.coeff *= -int(term.np[0]) - M;
206  --term.np[0];
207  ++term.np[1];
208  p_out.data.push_back(term);
209  }
210  }
211  for(it = 0; it < data.size(); ++it) {
212  term = data[it];
213  if (term.np[1]) {
214  term.coeff *= term.np[1];
215  --term.np[1];
216  ++term.np[0];
217  p_out.data.push_back(term);
218  }
219  }
220  p_out.Collect();
221  if (!p_out.data.empty()) {
222  p_out.L = L;
223  p_out.M = M-1;
224  if (std::abs(p_out.M) > int(MaxM)) MaxM = std::abs(p_out.M);
225  p_out.Scale(1./sqrt(double((L+M)*(L-M+1))));
226  }
227  return p_out;
228 }
229 
static void FillTrigArr(const double phi)
std::vector< poly2d_term > data
Definition: poly2d_base.h:68
static std::set< poly2d_base * > poly2d_base_set
Definition: poly2d_base.h:59
static void SetPhi(const double phi)
Definition: rz_harm_poly.cc:88
void Scale(const double C)
Definition: poly2d_base.cc:296
static trig_pair * TrigArr
Definition: rz_harm_poly.h:50
T sqrt(T t)
Definition: SSEVec.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define N
Definition: blowfish.cc:9
static unsigned NPwr
Definition: poly2d_base.h:54
static void PrintTrigArr(std::ostream &out=std::cout, const std::streamsize prec=5)
static void SetTrigArrSize(const unsigned N)