OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
37 void 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
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