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  for (auto const& poly: poly2d_base_set) {
78  if (typeid(*poly) == typeid(rz_harm_poly)) {
79  M_cur = std::abs(static_cast<rz_harm_poly const*>(poly)->M);
80  if (M_cur > M_max) M_max = M_cur;
81  }
82  }
83  return M_max;
84 }
85 
86 //_______________________________________________________________________________
87 void rz_harm_poly::SetPhi(const double phi)
88 {
89 //Set value of the angle argument, adjust the TrigArr size if neccessary
90 //and fill TrigArr if the phi value is changed
91 //
92  if (MaxM >= TASize) { SetTrigArrSize(MaxM+1); FillTrigArr(phi);}
93  else if (phi != phival) FillTrigArr(phi);
94  phival = phi;
95  phi_set = true;
96 }
97 
98 //_______________________________________________________________________________
99 void rz_harm_poly::SetTrigArrSize(const unsigned N)
100 {
101 //Increase TrigArr size if neccessary
102 //
103  if (N <= TASize) return;
104  if (TrigArr) delete [] TrigArr;
105  TrigArr = new trig_pair [N];
106  (*TrigArr) = trig_pair(1., 0.);
107  TASize = N;
108  phi_set = false;
109 }
110 
111 //_______________________________________________________________________________
112 void rz_harm_poly::FillTrigArr(const double phi)
113 {
114 //Fill TrigArr with trig_pair(jp*phi)
115  if (!TrigArr) return;
116  trig_pair tp(phi);
117  TrigArr[1] = tp;
118  for (unsigned jp = 2; jp <= MaxM; ++jp) TrigArr[jp] = TrigArr[jp-1].Add(tp);
119 }
120 
121 //_______________________________________________________________________________
122 void rz_harm_poly::PrintTrigArr(std::ostream &out, const std::streamsize prec)
123 {
124  out << "TrigArr: TASize = " << TASize
125  << "\tMaxM = " << MaxM << std::endl;
126  if (TrigArr) {
127  if (MaxM < TASize) {
128  unsigned jm;
129  std::streamsize old_prec = out.precision(), wdt = prec+7;
130  out.precision(prec);
131  out << "M: ";
132  for (jm = 0; jm <= MaxM; ++jm) {
133  out << std::setw(wdt) << std::left << jm;
134  }
135  out << "|\nCos_M: ";
136  for (jm = 0; jm <= MaxM; ++jm) {
137  out << std::setw(wdt) << std::left << TrigArr[jm].CosPhi;
138  }
139  out << "|\nSin_M: ";
140  for (jm = 0; jm <= MaxM; ++jm) {
141  out << std::setw(wdt) << std::left << TrigArr[jm].SinPhi;
142  }
143  out << "|" << std::endl;
144  out.precision(old_prec);
145  } else {
146  out << "\tTrigArr size is not adjusted." << std::endl;
147  }
148  } else {
149  out << "\tTrigArr is not allocated." << std::endl;
150  }
151 }
152 
153 //_______________________________________________________________________________
155 {
156 //Return a polynomial with increased M
157 //
158  rz_harm_poly p_out; p_out.data.reserve(2*L);
159  unsigned it;
160  poly2d_term term;
161 
162  //In 2 passes (for-cycles) to get terms in z-descending order
163  for(it = 0; it < data.size(); ++it) {
164  term = data[it];
165  if (term.np[0]) {
166  term.coeff *= int(term.np[0]) - M;
167  --term.np[0];
168  ++term.np[1];
169  p_out.data.push_back(term);
170  }
171  }
172  for(it = 0; it < data.size(); ++it) {
173  term = data[it];
174  if (term.np[1]) {
175  term.coeff *= -(int)term.np[1];
176  --term.np[1];
177  ++term.np[0];
178  p_out.data.push_back(term);
179  }
180  }
181  p_out.Collect();
182  if (!p_out.data.empty()) {
183  p_out.L = L;
184  p_out.M = M+1;
185  if (std::abs(p_out.M) > int(MaxM)) MaxM = std::abs(p_out.M);
186  p_out.Scale(1./sqrt(double((L-M)*(L+M+1))));
187  }
188  return p_out;
189 }
190 
191 //_______________________________________________________________________________
193 {
194 //Return a polynomial with decreased M
195 //
196  rz_harm_poly p_out; p_out.data.reserve(2*L);
197  unsigned it;
198  poly2d_term term;
199 
200  //In 2 passes (for-cycles) to get terms in z-descending order
201  for(it = 0; it < data.size(); ++it) {
202  term = data[it];
203  if (term.np[0]) {
204  term.coeff *= -int(term.np[0]) - M;
205  --term.np[0];
206  ++term.np[1];
207  p_out.data.push_back(term);
208  }
209  }
210  for(it = 0; it < data.size(); ++it) {
211  term = data[it];
212  if (term.np[1]) {
213  term.coeff *= term.np[1];
214  --term.np[1];
215  ++term.np[0];
216  p_out.data.push_back(term);
217  }
218  }
219  p_out.Collect();
220  if (!p_out.data.empty()) {
221  p_out.L = L;
222  p_out.M = M-1;
223  if (std::abs(p_out.M) > int(MaxM)) MaxM = std::abs(p_out.M);
224  p_out.Scale(1./sqrt(double((L+M)*(L-M+1))));
225  }
226  return p_out;
227 }
228 
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:87
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
Definition: poly.h:10
#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)
Definition: rz_harm_poly.cc:99