/******************************************************************************* * * VITESS and McStas, neutron ray-tracing packages * Copyright 1997-2005, All rights reserved * Hahn-Meitner-Institut Berlin, Germany * Risoe National Laboratory, Roskilde, Denmark * Institut Laue Langevin, Grenoble, France * * Component: Vitess_ChopperFermi * * %I * Written by: Geza Zsigmond * Date: Sep 2004 * Origin: VITESS module 'chopper_fermi' * Version: $Revision: 1.6 $ * Release: McStas 1.9 * Modified by: adapted for McStas by K. Lieutenant, Mar 2005; * * Fermi chopper with absorbing walls using the VITESS module 'chopper_fermi' * * %D * This component simulates a Fermi chopper with absorbing walls. The rotation axis is * vertical (y-axis), i.e. the path length through the channels is given by the length * 'depth' along the z-axis. * The shape of the channels can be straight, curved with circular, or curved with ideal * (i.e. close to a parabolic) shape. This is determined by the parameter 'GeomOption'. * * Geometry for straight and circular channels: * The geometry of the chopper consists of a rectangular shaped object with a channel * system. In transmission position, there are 'Nchannels' slits along the x-axis, * separated by absorbing walls of thickness 'wallwidth' giving a total width 'width'. * The rectangular channel system is surrounded by a so-called shadowing cylinder * (cf component manual). * * Geometry for parabolic channels: * In this case, the Fermi chopper is supposed to be a full cylinder, i.e. the central * channels are longer than those on the edges (cf. figure in the component manual). * The other features are the same as for the other options. * * Apart from the frequency of rotation, the phase of the chopper at t=0 has to be given; * phase = 0 means transmission orientation. * * The option 'zerotime' may be used to reset the time at the chopper position. The * consequence is that only 1 pulse is generated instead of several. * * Examples: * straight Fermi chopper, 18000 rpm, 20 channels a 0.9 mm separated by 0.1 mm walls, * 16 mm channel length, minimal shadowing cylinder, phased to be open at 1 ms, * generation of only 1 pulse, normal precision (for short wavelength neutrons) * Vitess_ChopperFermi(GeomOption=0, zerotime=1, Nchannels=20, Ngates=4, * freq=300.0, height=0.06, width=0.0201, * depth=0.016, r_curv=0.0, diameter=0.025691, Phase=-108.0, * wallwidth=0.0001, sGeomFileName="FC_geom_str.dat") * * Fermi chopper with circular channels, 12000 rpm, optimized for 6 Ang, several pulses, * highest accuracy (because of long wavelength neutrons used), rest as above * Vitess_ChopperFermi(GeomOption=2, zerotime=0, Nchannels=20, Ngates=8, * freq=200.0, height=0.06, width=0.0201, * depth=0.016, r_curv=0.2623, diameter=0.025691, Phase=-72.0, * wallwidth=0.0001, sGeomFileName="FC_geom_circ.dat") * * %VALIDATION * Apr 2005: extensive external test, most problems solved (cf. 'Bugs' and source header) * Validated by: K. Lieutenant * * limitations: * slow, especially for a high number of channels * * %BUGS * reduction of transmission by a large shadowing cylinder underestimated * * %P * GeomOption: [1] option: 0:straight 1:parabolic 2:circular * zerotime: [1] option: 1:'set time to zero' 0: 'do not' * Nchannels: [1] number of channels of the Fermi chopper * Ngates: [1] number of gates defining the channel: 4=default, 6 or 8 for long wavelengths * freq: [Hz] number of rotations per second * height: [m] height of the Fermi chopper * width: [m] total width of the Fermi chopper * depth: [m] channel length of the Fermi chopper * r_curv: [m] radius of curvature of the curved Fermi chopper * diameter: [m] diameter of the shadowing cylinder * Phase: [deg] dephasing angle at zero time * wallwidth: [m] thickness of walls separating the channels * sGeomFileName: [str] name of output file for geometry information * * OUTPUT PARAMETERS: * Option: [-] 1: straight FC, 2: curved FC * CurvGeomOption:[-] 1: ideal shape (nearly parabolic) 2: circular * TOF: [ms] TOF of neutron under consideration * WL: [Ang] wavelength of neutron * radius_of_curv:[cm] radius of curvature (curved FC) * main_depth: [cm] max. channel length due to diameter and total_width * shift_y: [cm] shift to channel actually written to geometry file * angle_channel: [rad] half of the curvature of a curved Fermi chopper * phase0: [rad] chopper phase at TOF of neutron to chopper centre * y_ch: [cm] position of gates perpendicular to flight direction * x_ch: [cm] position of gates along flight direction * coef_pi: [-] number of half-rotation to reach identical state * GeomFilePtr: [-] pointer to geometry file name * Pos: [cm] position of neutron * Dir: [-] flight direction of neutron * Neutrons: [-] neutron parameter set at end of chopper * pos_ch: [cm] centre position of the Fermi chopper * omega: [1/s] angular frequency of the chopper * optimal_wl: [Ang] wavelength of highest transmission of curved FC * * * %Link * straight VITESS Fermi chopper * %Link * curved VITESS Fermi chopper * * %E *******************************************************************************/ DEFINE COMPONENT Vitess_ChopperFermi DEFINITION PARAMETERS (sGeomFileName) SETTING PARAMETERS (int GeomOption=0, int zerotime=0, int Nchannels=20, int Ngates=4, freq=300.0, height=0.05, width=0.04, depth=0.03, r_curv=0.5, diameter=0.071, Phase=0.0, wallwidth=0.0002) OUTPUT PARAMETERS (Option, CurvGeomOption, TOF, WL, radius_of_curv, main_depth, shift_y, angle_channel, phase0, y_ch, x_ch, coef_pi, XFILEName, GeomFilePtr, Pos, Dir, Neutrons, pos_ch, omega, optimal_wl) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) POLARISATION PARAMETERS (sx, sy, sz) SHARE %{ %include "general.c" %include "intersection.c" %include "vitess-lib" %} DECLARE %{ %include "chopper_fermi.h" /* instance variables */ double omega = 0.0, /* rotation frequency */ optimal_wl = 0.0; /* optimal wavelength */ VectorType pos_ch={0.0,0.0,0.0}; /* centre pos. of the FC in the frame of the exit of the prev. comp. [cm] */ #define MCSTAS_SHARE %include "chopper_fermi.c" /* include functions */ #undef MCSTAS_SHARE %} INITIALIZE %{ double x,y,z; coords_get(POS_R_COMP_INDEX(INDEX_CURRENT_COMP), &x, &y, &z); pos_ch[0] = -100.0 * z; pos_ch[1] = -100.0 * x; pos_ch[2] = -100.0 * y; McInitVt(); /* transformation of units */ height *= 100.0; /* m -> cm */ width *= 100.0; depth *= 100.0; diameter *= 100.0; r_curv *= 100.0; wallwidth *= 100.0; omega = freq*2*PI/1000.0; /* 1/s -> 2pi/ms */ Phase *= DEG2RAD; /* checks and completion of input data */ CurvGeomOption = (int) GeomOption; if (GeomOption > 0 && omega*r_curv==0) { printf("Error: 'omega*r_curv' must not be zero for curved Fermi chopper"); exit(-1);} switch(GeomOption) { case 0: Option=1; optimal_wl=0.0; break; case 1: Option=2; optimal_wl=LAMBDA_FROM_V(2.0*omega*r_curv); break; case 2: Option=2; optimal_wl=LAMBDA_FROM_V(2.0*omega*r_curv); break; default: printf("Wrong option! Good options: 0-straight, 1-parabolic, 2-circular"); } ChopperFermiInit(0, NULL); %} TRACE %{ int i=0; InputNeutrons[i] = mcstas2vitess(x, y, z, vx, vy, vz, t, sx, sy, sz, p); #define MCSTAS_TRACE %include "chopper_fermi.c" #undef MCSTAS_TRACE vitess2mcstas(Neutrons, &x, &y, &z, &vx, &vy, &vz, &t, &sx, &sy, &sz, &p); %} FINALLY %{ ChopperFermiCleanup(); McCleanupVt(); %} MCDISPLAY %{ double index=0; double xpos, zpos, ymin, ymax, rad, w_ch; w_ch = (width - (Nchannels+1) * wallwidth) / Nchannels; rad = diameter/2.0; ymin = -height/2.0; ymax = height/2.0; magnify("xz"); /* cylinder top/center/bottom */ circle("xz", 0,ymax,0,rad); circle("xz", 0,0 ,0,rad); circle("xz", 0,ymin,0,rad); /* vertical lines to make a kind of volume */ line( 0 ,ymin,-rad, 0 ,ymax,-rad); line( 0 ,ymin, rad, 0 ,ymax, rad); line(-rad,ymin, 0 ,-rad,ymax, 0 ); line( rad,ymin, 0 , rad,ymax, 0 ); /* slit package */ index = -Nchannels/2; zpos = depth/2; for (index = -Nchannels/2; index < Nchannels/2; index++) { xpos = index*w_ch; multiline(5, xpos, ymin, -zpos, xpos, ymax, -zpos, xpos, ymax, +zpos, xpos, ymin, +zpos, xpos, ymin, -zpos); } /* cylinder inner sides containing slit package */ xpos = Nchannels*w_ch/2; zpos = sqrt(rad*rad - xpos*xpos); multiline(5, xpos, ymin, -zpos, xpos, ymax, -zpos, xpos, ymax, +zpos, xpos, ymin, +zpos, xpos, ymin, -zpos); xpos *= -1; multiline(5, xpos, ymin, -zpos, xpos, ymax, -zpos, xpos, ymax, +zpos, xpos, ymin, +zpos, xpos, ymin, -zpos); %} END