gfields
gfield_multipoles.cc
Go to the documentation of this file.
1 // CLHEP units
2 #include "CLHEP/Units/PhysicalConstants.h"
3 
4 // geant4 headers
5 #include "G4ThreeVector.hh"
6 
7 // gfields
8 #include "gfield_multipoles.h"
9 
10 // gemv
11 #include "gutilities.h"
12 
13 // c++
14 #include <iostream>
15 
16 using namespace std;
17 
18 // tells the DLL how to create a GFieldFactory
19 extern "C" GField *GFieldFactory(void) {
20  return static_cast<GField *>(new GField_MultipolesFactory);
21 }
22 
23 
24 // for now this implementation follows gemc
25 // reference of this implementation: https://uspas.fnal.gov/materials/12MSU/magnet_elements.pdf
26 void GField_MultipolesFactory::GetFieldValue(const G4double pos[4], G4double *bfield) const {
27 
28  G4ThreeVector x0(pos[0], pos[1], pos[2]);
29  G4ThreeVector x1(origin[0], origin[1], origin[2]);
30  G4ThreeVector x2;
31  G4ThreeVector x0_local;
32  if (rotaxis == 0) {
33  x2 = G4ThreeVector(0 * CLHEP::cm, 0 * CLHEP::cm, 1 * CLHEP::cm).rotateX(rotation_angle) + x1;
34  x0_local = (x0 - x1).rotateX(-rotation_angle);
35  } else if (rotaxis == 1) {
36  x2 = G4ThreeVector(0 * CLHEP::cm, 0 * CLHEP::cm, 1 * CLHEP::cm).rotateY(rotation_angle) + x1;
37  x0_local = (x0 - x1).rotateY(-rotation_angle);
38  } else if (rotaxis == 2) {
39  x2 = G4ThreeVector(0 * CLHEP::cm, 0 * CLHEP::cm, 1 * CLHEP::cm).rotateZ(rotation_angle) + x1;
40  x0_local = (x0 - x1).rotateZ(-rotation_angle);
41  }
42 
43  G4double r = (x2 - x1).cross(x1 - x0).mag() / (x2 - x1).mag(); //distance from x0 to line x1-x2
44  G4double phi = atan2(x0_local.y(), x0_local.x());
45 
46  G4ThreeVector B_local;
47  if (pole_number == 2) {
48  B_local.setX(0);
49  B_local.setY(strength);
50  B_local.setZ(0);
51  } else if (pole_number > 0) {
52  int a = pole_number / 2 - 1;
53  B_local.setX(strength * pow(r / CLHEP::m, a) * sin(a * phi));
54  B_local.setY(strength * pow(r / CLHEP::m, a) * cos(a * phi));
55  B_local.setZ(0);
56  } else {
57  cout << GFIELDLOGHEADER << "GField_MultipolesFactory::GetFieldValue: Pole number " + to_string(pole_number) + " not supported. Exiting." << endl;
59  }
60 
61  G4ThreeVector B_lab = B_local;
62  if (rotaxis == 0) { B_lab.rotateX(rotation_angle); }
63  else if (rotaxis == 1) { B_lab.rotateY(rotation_angle); }
64  else if (rotaxis == 2) { B_lab.rotateZ(rotation_angle); }
65 
66  bfield[0] = B_lab.x();
67  bfield[1] = B_lab.y();
68  bfield[2] = B_lab.z();
69 
70 // cout << " Pole number: " << pole_number << endl;
71 // cout << " Strength: " << strength << endl;
72 // cout << " Origin: " << origin[0] << " " << origin[1] << " " << origin[2] << endl;
73 // cout << " Rotation angle: " << rotation_angle << endl;
74 // cout << " Rotation axis: " << rotaxis << endl;
75 // cout << "B_lab.x() = " << B_lab.x() << endl;
76 // cout << "B_lab.y() = " << B_lab.y() << endl;
77 // cout << "B_lab.z() = " << B_lab.z() << endl;
78 // cout << " B Field x = " << bfield[0] << endl;
79 // cout << " B Field y = " << bfield[1] << endl;
80 // cout << " B Field z = " << bfield[2] << endl;
81 
82 }
83 
85  gfield_definitions = gfd;
86 
87  pole_number = get_field_parameter_int("pole_number");
88  origin[0] = get_field_parameter_double("vx");
89  origin[1] = get_field_parameter_double("vy");
90  origin[2] = get_field_parameter_double("vz");
91  rotation_angle = get_field_parameter_double("rotation_angle");
92  if( gfield_definitions.field_parameters["rotaxis"] == "X") {
93  rotaxis = 0;
94  } else if( gfield_definitions.field_parameters["rotaxis"] == "Y") {
95  rotaxis = 1;
96  } else if( gfield_definitions.field_parameters["rotaxis"] == "Z") {
97  rotaxis = 2;
98  } else {
99  cout << GFIELDLOGHEADER << "GField_MultipolesFactory::load_field_definitions: Rotation axis " + gfield_definitions.field_parameters["rotaxis"] + " not supported. Exiting." << endl;
101  }
102  strength = get_field_parameter_double("strength");
103 }
Factory class for creating and managing multipole magnetic fields.
void GetFieldValue(const G4double pos[4], G4double *bfield) const override
Calculates the magnetic field at a given position.
void load_field_definitions(GFieldDefinition gfd) override
Sets the field definition for the field.
Abstract base class representing a magnetic field.
Definition: gfield.h:69
#define EC__WRONG_FIELD_ROTATION
#define GFIELDLOGHEADER
#define EC__WRONG_POLE_NUMBER
GField * GFieldFactory(void)
Utility struct to load GFields from options.
Definition: gfield.h:17