OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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//
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
57void 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
90void 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