OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
TrimCoilMirrored.cpp
Go to the documentation of this file.
1//
2// Class TrimCoilMirrored
3// Shape mirrored from TC-15 shape
4// http://accelconf.web.cern.ch/AccelConf/ipac2017/papers/thpab077.pdf
5//
6// Copyright (c) 2018 - 2019, Jochem Snuverink, Paul Scherrer Institut, Villigen PSI, Switzerland
7// All rights reserved
8//
9// This file is part of OPAL.
10//
11// OPAL is free software: you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation, either version 3 of the License, or
14// (at your option) any later version.
15//
16// You should have received a copy of the GNU General Public License
17// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
18//
20
21#include "Utility/IpplInfo.h"
23
24#include <cmath>
25
27 double rmin,
28 double rmax,
29 double bslope):
30 TrimCoil(bmax, rmin, rmax)
31{
32 // convert to m
33 const double mm2m = 0.001;
34 bslope_m = bslope / mm2m;
35}
36
37void TrimCoilMirrored::doApplyField(const double r, const double z, const double /*phi_rad*/, double *br, double *bz)
38{
40 // for some discussion on the formulas see
41 // http://doi.org/10.1103/PhysRevSTAB.14.054402
42 // https://gitlab.psi.ch/OPAL/src/issues/157
43 // https://gitlab.psi.ch/OPAL/src/issues/110
44
45 // unitless constants
46 const double Amax1 = 1;
47 const double Amax2 = 3;
48 const double Amin = -2;
49 const double x01 = 4;
50 const double x02 = 8;
51 const double h1 = 0.03;
52 const double h2 = 0.2;
53 const double justAnotherFudgeFactor = 1 / 2.78;
54 // helper variables
55 const double log10 = std::log(10);
56 const double const3 = -(Amax1 - Amin) * h1 * log10;
57 const double const4 = (Amax2 - Amin) * h2 * log10;
58
59 const double &tcr1 = rmin_m;
60 const double &tcr2 = rmax_m;
61 const double &slope = bslope_m;
62 const double &magnitude = bmax_m;
63
64 double part1;
65 double part2;
66
67 if (2 * r < (tcr2 + tcr1)) {
68 part1 = std::pow(10.0, ((r - tcr1) * slope - x01) * h1);
69 part2 = std::pow(10.0, -((r - tcr1) * slope - x02) * h2);
70 } else {
71 part1 = std::pow(10.0, ((tcr2 - r) * slope - x01) * h1);
72 part2 = std::pow(10.0, -((tcr2 - r) * slope - x02) * h2);
73 }
74
75 const double part1plusinv = 1 / (1 + part1);
76 const double part2plusinv = 1 / (1 + part2);
77
78 double part3 = const3 * slope * part1 * part1plusinv * part1plusinv;
79 double part4 = const4 * slope * part2 * part2plusinv * part2plusinv;
80
81 const double constmag = magnitude * justAnotherFudgeFactor;
82
83 double dr = constmag * (part3 + part4);
84 double btr = constmag * (Amin - 1 +
85 (Amax1 - Amin) * part1plusinv +
86 (Amax2 - Amin) * part2plusinv);
87
88 if (std::isnan(dr) || std::isinf(dr) ||
89 std::isnan(btr) || std::isinf(btr)) {
90 ERRORMSG("r = " << r << " m, tcr1 = " << tcr1 << " m, tcr2 = " << tcr2 << " m\n");
91 ERRORMSG("slope = " << slope << ", magnitude = " << magnitude << " kG\n");
92 ERRORMSG("part1 = " << part1 << ", part2 = " << part2 << "\n");
93 ERRORMSG("part3 = " << part3 << ", part4 = " << part4 << endl);
94 throw GeneralClassicException("TrimCoilMirrored::doApplyField",
95 "dr or btr yield results that are either nan or inf");
96 }
97
98 *bz -= btr;
99 *br -= dr * z;
100}
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
PETE_TUTree< FnLog10, typename T::PETE_Expr_t > log10(const PETE_Expr< T > &l)
Definition: PETE.h:735
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
constexpr double mm2m
Definition: Units.h:29
T isinf(T x)
isinf function with adjusted return type
Definition: matheval.hpp:70
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:66
double bmax_m
Maximum B field (kG)
Definition: TrimCoil.h:40
double rmax_m
Maximum radius (m)
Definition: TrimCoil.h:49
double rmin_m
Minimum radius (m)
Definition: TrimCoil.h:47
TrimCoilMirrored()=delete
double bslope_m
Slope in (1 / mm)
virtual void doApplyField(const double r, const double z, const double phi_rad, double *br, double *bz)
virtual implementation of applyField