OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
TrimCoilFit.cpp
Go to the documentation of this file.
1 //
2 // Class TrimCoilFit
3 // Abstract TrimCoilFit class
4 // General rational function fit
5 //
6 // Copyright (c) 2018 - 2019, Jochem Snuverink, Paul Scherrer Institut, Villigen PSI, Switzerland
7 // All rights reserved
8 //
9 // Implemented as part of the PhD thesis
10 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
11 // and the paper
12 // "Matching of turn pattern measurements for cyclotrons using multiobjective optimization"
13 // (https://doi.org/10.1103/PhysRevAccelBeams.22.064602)
14 //
15 // This file is part of OPAL.
16 //
17 // OPAL is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
24 //
25 #include "TrimCoils/TrimCoilFit.h"
26 
27 #include <cmath>
28 
30  double rmin,
31  double rmax,
32  const std::vector<double>& coefnum,
33  const std::vector<double>& coefdenom,
34  const std::vector<double>& coefnumphi,
35  const std::vector<double>& coefdenomphi):
36 
37  TrimCoil(bmax, rmin, rmax)
38 {
39  coefs.resize(4);
40  coefs[NUM] = coefnum;
41  coefs[DENOM] = coefdenom;
42  coefs[NUMPHI] = coefnumphi;
43  coefs[DENOMPHI] = coefdenomphi;
44 
45  // normal polynom if no denominator coefficients (denominator = 1)
46  if (coefs[DENOM].empty())
47  coefs[DENOM].push_back(1.0);
48  if (coefs[DENOMPHI].empty())
49  coefs[DENOMPHI].push_back(1.0);
50  // default constant nominator
51  if (coefs[NUM].empty())
52  coefs[NUM].push_back(1.0);
53  if (coefs[NUMPHI].empty())
54  coefs[NUMPHI].push_back(1.0);
55 }
56 
57 void TrimCoilFit::calculateRationalFunction(FunctionType type, double val, double& quot, double& der_quot) const
58 {
59  double num = 0.0; // numerator
60  double dnum = 0.0; // derivative of numerator
61  double powval = 1.0; // power of value
62 
63  const std::vector<double>& coefnum = coefs[type];
64  const std::vector<double>& coefdenom = coefs[type+1];
65 
66  // add constant
67  num += coefnum[0];
68  for (std::size_t i = 1; i < coefnum.size(); ++i) {
69  dnum += coefnum[i] * powval * i;
70  powval *= val;
71  num += coefnum[i] * powval;
72  }
73  double denom = 0.0; // denominator
74  double ddenom = 0.0; // derivative of denominator
75  powval = 1.0; // power of value
76 
77  // add constant
78  denom += coefdenom[0];
79  for (std::size_t i = 1; i < coefdenom.size(); ++i) {
80  ddenom += coefdenom[i] * powval * i;
81  powval *= val;
82  denom += coefdenom[i] * powval;
83  }
84 
85  quot = num / denom;
86  // derivative with quotient rule
87  der_quot = (dnum * denom - ddenom * num) / (denom*denom);
88 }
89 
90 void TrimCoilFit::calculateRationalFunction(FunctionType type, double val, double& quot, double& der_quot, double& der2_quot) const
91 {
92  double num = 0.0; // numerator
93  double d_num = 0.0; // derivative of numerator
94  double d2_num = 0.0; // second derivative of numerator
95  double powval = 1.0; // power of r
96 
97  const std::vector<double>& coefnum = coefs[type];
98  const std::vector<double>& coefdenom = coefs[type+1];
99 
100  unsigned int order = coefnum.size();
101 
102  // add constant and first term
103  num += coefnum[0];
104  if (order > 1) {
105  num += coefnum[1] * val;
106  d_num += coefnum[1];
107  }
108  for (std::size_t i = 2; i < coefnum.size(); ++i) {
109  d2_num += coefnum[i] * powval * i * (i-1);
110  powval *= val; // r^(i-1)
111  d_num += coefnum[i] * powval * i;
112  num += coefnum[i] * powval * val;
113  }
114 
115  double denom = 0.0; // denominator
116  double d_denom = 0.0; // derivative of denominator
117  double d2_denom = 0.0; // derivative of denominator
118  powval = 1.0; // power of r
119  order = coefdenom.size();
120 
121  // add constant
122  denom += coefdenom[0];
123  if (order > 1) {
124  denom += coefdenom[1] * val;
125  d_denom += coefdenom[1];
126  }
127  for (std::size_t i = 2; i < coefdenom.size(); ++i) {
128  d2_denom += coefdenom[i] * powval * i * (i-1);
129  powval *= val;
130  d_denom += coefdenom[i] * powval * i;
131  denom += coefdenom[i] * powval * val;
132  }
133 
134  quot = num / denom;
135 
136  // derivative of phase with quotient rule (B - field)
137  der_quot = (d_num * denom - d_denom * num) / (denom*denom);
138 
139  // second derivitive of phase (dB/dr) with quotient rule
140  // (d2_num - 2*(num/denom)' * d_denom - (num/denom) * d2_denom) / denom
141  der2_quot = (d2_num - 2*der_quot*d_denom - quot * d2_denom) / denom;
142 }
boost::function< boost::tuple< double, bool >arguments_t)> type
Definition: function.hpp:21
void calculateRationalFunction(FunctionType, double value, double &quot, double &der_quot) const
calculate rational function and its first derivative
Definition: TrimCoilFit.cpp:57
std::vector< std::vector< double > > coefs
rational function coefficients
Definition: TrimCoilFit.h:58
TrimCoilFit()=delete