File: Pol_Bfield.comp

package info (click to toggle)
mccode 3.5.19%2Bds5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,113,256 kB
  • sloc: ansic: 40,697; python: 25,137; yacc: 8,438; sh: 5,405; javascript: 4,596; lex: 1,632; cpp: 742; perl: 296; lisp: 273; makefile: 226; fortran: 132
file content (236 lines) | stat: -rw-r--r-- 8,109 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/**************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright 1997-2006, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: Pol_Bfield
*
* %I
* Written by: Erik B Knudsen, Peter Christiansen and Peter Willendrup
* Date: July 2011
* Origin: RISOE
*
* Magnetic field component.
*
* %D
*
* Region with a definable magnetic field.
*
* The component is nestable if the concentric flag is set (the default). This means that it may have a
* construction like the following:
* // START MAGNETIC FIELD
* COMPONENT msf =
* Pol_Bfield(xwidth=0.08, yheight=0.08, zdepth=0.2, Bx=0, By=-0.678332e-4, Bz=0)
*      AT (0, 0, 0) RELATIVE armMSF
*
* // OTHER COMPONENTS INSIDE THE MAGNETIC FIELD CAN BE PLACED HERE
*
* // STOP MAGNETIC FIELD
* COMPONENT msf_stop = Pol_simpleBfield_stop(magnet_comp_stop=msf)
*      AT (0, 0, 0) RELATIVE armMSF
*
* Note that if you have objects within the magnetic field that extend outside it you may get
* wrong results, because propagation within the field will then possibly extend outside, e.g.
* when using a tabled field. The evaluated field will then use the nearest defined field point
* _also_ outside the defintion area. If these outside-points have a non-zero field precession will
* continue - even after the neutron has left the field region.
*
* In between the two component instances the propagation routine
* PROP_DT also handles spin propagation.
* The current algorithm used for spin propagation is:
* SimpleNumMagnetPrecession
* in pol-lib.
*
* Example: Pol_Bfield(xwidth=0.1, yheight=0.1, zdepth=0.2, Bx=0, By=1, Bz=0)
*          Pol_Bfield(xwidth=0.1, yheight=0.1, zdepth=0.2, field_type=1)
*
* Functions supplied by the system are (the number is the ID of the function to be given as the field_type parameter:
* 1. Constant magnetic field: Constant field (Bx,By,Bz) within the region
* 2. Rotating magnetic_field: Field is initially (0,By,0) but after a length of zdepth
*      has rotated to (By,0,0)
* 3. Majorana magnetic_field: Field is initially (Bx,By,0) with By<<Bx, then linearly transforms to
*      (-Bx,By,0) at z=zdepth.
* 4. MSF field:
* 5. RF field: A radio frequency field is modeled by an implcit use of a roating frame.
* 6. Gradient field: Similar to Majorana by without an x-component to the field. I.e. it (0,By,0) at z=0, and
*    becomes (0,-By,0) AT z=zdepth.
*
* If the concentric parameter is set to 1 the magnetic field is turned on by an
* instance of this component, and turned off by an instance of Pol_simpleBfield_stop.
* Anything in between is considered inside the field.
* If concentric is zero the field is considered a closed component - neutrons are propagated
* through the field region, and no other components are permitted inside the field.
*
* %P
* INPUT PARAMETERS:
*
* xwidth: [m]               Width of opening.
* yheight: [m]              Height of opening.
* zdepth: [m]               Length of field.
* radius: [m]               Radius of field if it is cylindrical or spherical.
* Bx: [T]                   Parameter used for x composant of field.
* By: [T]                   Parameter used for y composant of field.
* Bz: [T]                   Parameter used for z composant of field.
* field_type: []            ID of function describing the magnetic field. 1:constant field, 2: rotating fiel, 3: majorana type field, 4: MSF, 5: RF-field, 6: gradient field.
* concentric: [ ]           Allow components and/or other fields inside field. Requires a subsequent Pol_simpleBfield_stop component.
*
* %E
****************************************************************************/

DEFINE COMPONENT Pol_Bfield

SETTING PARAMETERS (int field_type=0, xwidth=0, yheight=0,zdepth=0, radius=0, Bx=0, By=0, Bz=0, concentric=1)
/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */

SHARE
%{
  %include "pol-lib"

  double fmax(double, double);
  double fmin(double, double);
%}


DECLARE
%{
  /* Larmor frequency and scalar product threshold*/
  double Bprms[8];
  int shape;
%}

INITIALIZE
%{
  enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY};
  enum field_functions ff=field_type;
  /* these default field functions are part of pol-lib */
  if (ff==constant){
    double *t=Bprms;
    t[0]=Bx;t[1]=By;t[2]=Bz;
  } else if (ff==rotating){
    double *t=Bprms;
    t[0]=By;t[1]=zdepth;
  } else if (ff==majorana){
    double *t=Bprms;
    t[0]=Bx; t[1]=By; t[2]=zdepth;
  } 

  if(xwidth && yheight && zdepth){
      shape=BOX;
  }else if (xwidth && yheight && !zdepth){
      shape=WINDOW;
  }else if(radius && yheight){
      shape=CYLINDER;
  }else if (radius) {
      shape=SPHERE;
  }else{
      shape=NONE;
  }

  if(shape == WINDOW && !concentric){
      printf("Warning (%s): Magnetic field has window shape and concentric==0 => Field volume == 0.\n",NAME_CURRENT_COMP);
  }
  if(shape == NONE) {
      printf("Warning (%s): Magnetic field has no geometry. Full Z=0-plane is used as boundary.\n",NAME_CURRENT_COMP);
  }

%}

TRACE
%{
    double t0,t1;
    int hit;
    enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY};

    /*enter through whatever object we are*/
    switch (shape){
        case BOX:
            hit=box_intersect(&t0,&t1,x,y,z,vx,vy,vz,xwidth,yheight,zdepth);
            /*terminate neutrons which miss the component*/
            if(!hit) ABSORB;
            /*If we do hit - propagate to the start of the field unless the neutron is already there.*/
            if(t0>FLT_EPSILON) {
                PROP_DT(t0);
                t1-=t0;
            }else if (t0<-FLT_EPSILON && concentric){
                PROP_DT(t1);
            }
            break;
        case CYLINDER:
            hit=cylinder_intersect(&t0,&t1,x,y,z,vx,vy,vz,radius,yheight);
            /*terminate neutrons which miss the component*/
            if(!hit)ABSORB;
            /*If we do hit - propagate to the start of the field unless the neutron is already there.*/
            if(t0>FLT_EPSILON) {
                PROP_DT(t0);
                t1-=t0;
            }else if (t0<-FLT_EPSILON && concentric){
                PROP_DT(t1);
            }
            break;
        case WINDOW:
            PROP_Z0;
            if (2*x>xwidth || 2*x<-xwidth || 2*y>yheight || 2*y<-yheight){
                /*terminate neutrons which miss the component*/
                ABSORB;
            }
            break;
        default:
            PROP_Z0;
    }
    mcmagnet_push(_particle, field_type,&(ROT_A_CURRENT_COMP),&(POS_A_CURRENT_COMP),0,Bprms);
#ifdef MCDEBUG
    mcmagnet_print_stack();
#endif

    /*does the field "close/stop" itself*/
    if (!concentric){
        switch (shape){
            case BOX:
                PROP_DT(t1);
                break;
            case CYLINDER:
                PROP_DT(t1);
                break;
            case WINDOW:
                PROP_Z0;
                /*terminate neutrons which miss the exit window*/
                if (2*x>xwidth || 2*x<-xwidth || 2*y>yheight || 2*y<-yheight){
                    ABSORB;
                }
                break;
            default:
                PROP_Z0;
        }
        mcmagnet_pop(_particle);
    }
%}

MCDISPLAY
%{
    enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY};
    switch (shape){
        case BOX:
	  box(0,0,0,xwidth,yheight,zdepth,0, 0, 1, 0);
            break;
        case CYLINDER:
            circle("xz",0, yheight/2.0,0,radius);
            circle("xz",0,-yheight/2.0,0,radius);
            line(-radius,-yheight/2.0,0,-radius,yheight/2.0,0);
            line( radius,-yheight/2.0,0, radius,yheight/2.0,0);
            line(0,-yheight/2.0,-radius,0,yheight/2.0,-radius);
            line(0,-yheight/2.0, radius,0,yheight/2.0, radius);
            break;
        case SPHERE:
            circle("xz",0,0,0,radius);
            circle("xy",0,0,0,radius);
            circle("yz",0,0,0,radius);
            break;
        case WINDOW:
            rectangle("xy",0,0,0,xwidth,yheight);
            break;
    }
%}

END