CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rz_poly.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include "rz_poly.h"
3 
4 using namespace std;
5 using namespace magfieldparam;
6 
7 //_______________________________________________________________________________
8 rz_poly::rz_poly(int N)
9 {
10  int nz, nr = 0, nv, nt;
11  poly_term v3;
12 
13  if (N < 2) N = 2;
14  data.reserve(N);
15 
16  v3.coeff = 1.;
17  v3.np[0] = 0;
18  v3.np[1] = 1;
19 
20  data.push_back(poly_vect(1, v3));
21 
22  for (int m = 2; m <=N; ++m) {
23  nz = m;
24  nr = 0;
25  nv = 0;
26  v3.coeff = 1./m;
27  v3.np[0] = nr;
28  v3.np[1] = nz;
29 
30  nt = (m + 2) / 2;
31  poly_vect v3x(nt, v3);
32 
33  while (nz >= 2) {
34  nz -= 2;
35  nr += 2;
36  nv += 1;
37  v3x[nv].coeff = -v3x[nv-1].coeff*(nz+1)*(nz+2)/(nr*nr);
38  v3x[nv].np[0] = nr;
39  v3x[nv].np[1] = nz;
40  }
41  data.push_back(v3x);
42  }
43  max_nr = nr+1;
44  max_nz = N +1;
45  r_pow = new double [max_nr];
46  z_pow = new double [max_nz];
47  fill(r_pow, r_pow+max_nr, 1.);
48  fill(z_pow, z_pow+max_nz, 1.);
49 
50  n_active = data.size();
51  is_off = new bool [n_active];
52  fill(is_off, is_off+n_active, false);
53 }
54 
55 //_______________________________________________________________________________
56 rz_poly::rz_poly(const rz_poly& S)
57 {
58  data = S.data;
59  max_nr = S.max_nr;
60  max_nz = S.max_nz;
61  n_active = S.n_active;
62 
63  if (max_nr) {
64  r_pow = new double [max_nr];
65  copy(S.r_pow, S.r_pow+max_nr, r_pow);
66  } else r_pow = 0;
67 
68  if (max_nz) {
69  z_pow = new double [max_nz];
70  copy(S.z_pow, S.z_pow+max_nz, z_pow);
71  } else z_pow = 0;
72 
73  if (S.is_off) {
74  is_off = new bool [data.size()];
75  copy(S.is_off, S.is_off+data.size(), is_off);
76  } else is_off = 0;
77 }
78 
79 //_______________________________________________________________________________
80 rz_poly::~rz_poly()
81 {
82  if (is_off) delete [] is_off;
83  if (r_pow) delete [] r_pow;
84  if (z_pow) delete [] z_pow;
85 }
86 
87 //_______________________________________________________________________________
88 void rz_poly::SetOFF(int npoly)
89 {
90  if ((npoly < 0) || (npoly >= (int)data.size())) return;
91  if (is_off[npoly]) return;
92  is_off[npoly] = true;
93  --n_active;
94 }
95 
96 //_______________________________________________________________________________
97 void rz_poly::SetON(int npoly)
98 {
99  if ((npoly < 0) || (npoly >= (int)data.size())) return;
100  if (is_off[npoly]) {
101  is_off[npoly] = false;
102  ++n_active;
103  }
104 }
105 
106 //_______________________________________________________________________________
108 {
109  if (!data.size()) {
110  cout << "The \"rz_poly\" object is NOT initialized!" << endl;
111  return;
112  }
113 
114  for (unsigned int ip = 0; ip < data.size(); ++ip) {
115  cout << "Polynomial " << ip << " (size=" << data[ip].size() << ", status=";
116  if (is_off[ip]) cout << "OFF):" << endl;
117  else cout << "ON):" << endl;
118  for (unsigned int it = 0; it < data[ip].size(); ++it) {
119  cout << "\tnr=" << data[ip][it].np[0]
120  << "\tnz=" << data[ip][it].np[1]
121  << "\tcoeff=" << data[ip][it].coeff
122  << endl;
123  }
124  }
125 }
126 
127 //_______________________________________________________________________________
128 rz_poly rz_poly::Diff(int nvar, bool keep_empty)
129 {
130 //Return the derivative of original polynomial by variable nvar.
131 //If keep_empty=true, resulting polynomial may contain zero basis terms,
132 //otherwise the resulting polynomial will be compressed, so that corresponding
133 //basis terms will be shifted relatively to the original polynomial.
134 //
135  poly_term v3;
136  rz_poly p_out;
137  p_out.data.reserve(data.size());
138 
139  bool *tmp_mask = new bool [data.size()];
140  unsigned int ind_tmp = 0;
141  int tmp_act = 0;
142 
143  for (unsigned int ip = 0; ip < data.size(); ++ip) {
144  poly_vect v3x;
145  v3x.reserve(data[ip].size());
146  for (unsigned int it = 0; it < data[ip].size(); ++it) {
147  v3 = data[ip][it];
148  v3.coeff = data[ip][it].coeff * data[ip][it].np[nvar];
149  if (v3.coeff != 0) {
150  v3.np[nvar] = data[ip][it].np[nvar] - 1;
151  v3x.push_back(v3);
152  }
153  }
154  if (v3x.size() || keep_empty) {
155  v3x.resize(v3x.size());
156  p_out.data.push_back(v3x);
157  tmp_mask[ind_tmp] = is_off[ip];
158  ++ind_tmp;
159  if (! is_off[ip]) ++tmp_act;
160  }
161  }
162 
163  p_out.data.resize(p_out.data.size());
164  p_out.max_nr = max_nr;
165  p_out.max_nz = max_nz;
166 
167  if (nvar == 0) --p_out.max_nr; else --p_out.max_nz;
168 
169  p_out.r_pow = new double [p_out.max_nr];
170  copy(r_pow, r_pow+p_out.max_nr, p_out.r_pow);
171  p_out.z_pow = new double [p_out.max_nz];
172  copy(z_pow, z_pow+p_out.max_nz, p_out.z_pow);
173 
174  p_out.n_active = tmp_act;
175  p_out.is_off = new bool [p_out.data.size()];
176  copy(tmp_mask, tmp_mask+p_out.data.size(), p_out.is_off);
177 
178  delete [] tmp_mask;
179 
180  return p_out;
181 }
182 
183 //_______________________________________________________________________________
184 rz_poly rz_poly::Int(int nvar)
185 {
186 //Return the integral of original polynomial by variable nvar
187 //
188  rz_poly p_out;
189  p_out.data = data;
190  for (unsigned int ip = 0; ip < data.size(); ++ip) {
191  for (unsigned int it = 0; it < data[ip].size(); ++it) {
192  p_out.data[ip][it].coeff /= ++p_out.data[ip][it].np[nvar];
193  }
194  }
195 
196  p_out.max_nr = max_nr;
197  p_out.max_nz = max_nz;
198 
199  if (nvar == 0) ++p_out.max_nr; else ++p_out.max_nz;
200 
201  p_out.r_pow = new double [p_out.max_nr];
202  copy(r_pow, r_pow+max_nr, p_out.r_pow);
203  p_out.z_pow = new double [p_out.max_nz];
204  copy(z_pow, z_pow+max_nz, p_out.z_pow);
205 
206  if (nvar == 0) p_out.r_pow[max_nr] = p_out.r_pow[max_nr-1] * r_pow[1];
207  else p_out.z_pow[max_nz] = p_out.z_pow[max_nz-1] * z_pow[1];
208 
209  p_out.n_active = n_active;
210  p_out.is_off = new bool [data.size()];
211  copy(is_off, is_off+data.size(), p_out.is_off);
212 
213  return p_out;
214 }
215 
216 //_______________________________________________________________________________
218 {
219 //Multiply the polynomial by a constant. Skips terms that are switched off
220 
221  for (unsigned int ip = 0; ip < data.size(); ++ip) {
222  if (is_off[ip]) continue;
223  for (unsigned int it = 0; it < data[ip].size(); ++it) {
224  data[ip][it].coeff *= C;
225  }
226  }
227  return *this;
228 }
229 
230 //_______________________________________________________________________________
232 {
233 //Multiply the polynomial by an array. Skips terms that are switched off
234 
235  for (unsigned int ip = 0; ip < data.size(); ++ip) {
236  if (is_off[ip]) continue;
237  for (unsigned int it = 0; it < data[ip].size(); ++it) {
238  data[ip][it].coeff *= *C;
239  }
240  ++C;
241  }
242  return *this;
243 }
244 
245 //_______________________________________________________________________________
246 double rz_poly::GetSVal(double r, double z, double *C)
247 {
248 //Return value of a polynomial, ignoring terms, that are switched off
249 
250  if (r_pow == 0) return 0.;
251 
252  double term, rez = 0.;
253  int ip, it;
254 
255  if (r != r_pow[1]) for (ip = 1; ip < max_nr; ++ip) r_pow[ip] = r*r_pow[ip-1];
256  if (z != z_pow[1]) for (ip = 1; ip < max_nz; ++ip) z_pow[ip] = z*z_pow[ip-1];
257 
258  for (ip = 0; ip < (int)data.size(); ++ip) {
259  if (is_off[ip]) continue;
260  term = 0.;
261  for (it = 0; it < (int)data[ip].size(); ++it) {
262  term += data[ip][it].coeff
263  * r_pow[data[ip][it].np[0]]
264  * z_pow[data[ip][it].np[1]];
265  }
266  rez += *C * term;
267  ++C;
268  }
269 
270  return rez;
271 }
272 
273 //_______________________________________________________________________________
274 double *rz_poly::GetVVal(double r, double z, double *rez_out)
275 {
276 //return an array of doubleype with values of the basis functions in the point
277 //(r,z). In a case if rez_out != 0, the rez_out array must be long enough to fit
278 //in n_active elements. In a case if rez_out == 0, a new array of n_active length
279 //is created; it is in user's responsibility to free the memory after all;
280 //
281  if (r_pow == 0) return 0;
282 
283  double term;
284  int ip, it;
285 
286  double *rez;
287  if (rez_out) rez = rez_out;
288  else rez = new double [n_active];
289 
290  double *pnt = rez;
291 
292  if (r != r_pow[1]) for (ip = 1; ip < max_nr; ++ip) r_pow[ip] = r*r_pow[ip-1];
293  if (z != z_pow[1]) for (ip = 1; ip < max_nz; ++ip) z_pow[ip] = z*z_pow[ip-1];
294 
295  for (ip = 0; ip < (int)data.size(); ++ip) {
296  if (is_off[ip]) continue;
297  term = 0.;
298  for (it = 0; it < (int)data[ip].size(); ++it) {
299  term += data[ip][it].coeff
300  * r_pow[data[ip][it].np[0]]
301  * z_pow[data[ip][it].np[1]];
302  }
303  *pnt = term;
304  ++pnt;
305  }
306 
307  return rez;
308 }
309 
310 //_______________________________________________________________________________
311 double *rz_poly::Expand(double *C)
312 {
313 //Take C[n_active] - reduced vector of coefficients and return pointer to
314 //expanded vector of coefficients of the data.size() length. It is in user's
315 //responsibility to free the memory after all;
316 //
317  double *rez = new double [data.size()];
318  for (int ip = 0; ip < (int)data.size(); ++ip) {
319  if (is_off[ip]) rez[ip] = 0.;
320  else {
321  rez[ip] = *C;
322  ++C;
323  }
324  }
325  return rez;
326 }
327 
std::vector< poly_term > poly_vect
Definition: rz_poly.h:23
Basic3DVector & operator*=(T t)
Scaling by a scalar value (multiplication)
Definition: DDAxes.h:10
int nt
Definition: AMPTWrapper.h:32
tuple cout
Definition: gather_cfg.py:41
tuple size
Write out results.