/******************************************************************************* * * McStas, neutron ray-tracing package * Copyright 1997-2002, All rights reserved * Risoe National Laboratory, Roskilde, Denmark * Institut Laue Langevin, Grenoble, France * * Component: Guide * * %I * Written by: Kristian Nielsen * Date: September 2 1998 * Version: $Revision: 1.24 $ * Origin: Risoe * Release: McStas 1.6 * * Neutron guide. * * %D * Models a rectangular guide tube centered on the Z axis. The entrance lies * in the X-Y plane. * For details on the geometry calculation see the description in the McStas * reference manual. * * Example: Guide(w1=0.1, h1=0.1, w2=0.1, h2=0.1, l=2.0, * R0=0.99, Qc=0.021, alpha=6.07, m=2, W=0.003 * * %VALIDATION * May 2005: extensive internal test, no bugs found * Validated by: K. Lieutenant * * %BUGS * This component does not work with gravitation on. Use component Guide_gravity then. * * %P * INPUT PARAMETERS: * * w1: (m) Width at the guide entry * h1: (m) Height at the guide entry * w2: (m) Width at the guide exit * h2: (m) Height at the guide exit * l: (m) length of guide * R0: (1) Low-angle reflectivity * Qc: (AA-1) Critical scattering vector * alpha: (AA) Slope of reflectivity * m: (1) m-value of material. Zero means completely absorbing. * W: (AA-1) Width of supermirror cut-off * * %D * Example values: m=4 Qc=0.0219 W=1/300 alpha=6.49 R0=1 * * %E *******************************************************************************/ DEFINE COMPONENT Guide DEFINITION PARAMETERS () SETTING PARAMETERS (w1, h1, w2, h2, l, R0=0.99, Qc=0.0219, alpha=6.07, m=2, W=0.003) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) INITIALIZE %{ if (mcgravitation) fprintf(stderr,"WARNING: Guide: %s: " "This component produces wrong results with gravitation !\n" "Use Guide_gravity.\n", NAME_CURRENT_COMP); %} TRACE %{ double t1,t2; /* Intersection times. */ double av,ah,bv,bh,cv1,cv2,ch1,ch2,d; /* Intermediate values */ double vdotn_v1,vdotn_v2,vdotn_h1,vdotn_h2; /* Dot products. */ int i; /* Which mirror hit? */ double q; /* Q [1/AA] of reflection */ double vlen2,nlen2; /* Vector lengths squared */ /* ToDo: These could be precalculated. */ double ww = .5*(w2 - w1), hh = .5*(h2 - h1); double whalf = .5*w1, hhalf = .5*h1; double lwhalf = l*whalf, lhhalf = l*hhalf; /* Propagate neutron to guide entrance. */ PROP_Z0; if(x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) ABSORB; for(;;) { /* Compute the dot products of v and n for the four mirrors. */ av = l*vx; bv = ww*vz; ah = l*vy; bh = hh*vz; vdotn_v1 = bv + av; /* Left vertical */ vdotn_v2 = bv - av; /* Right vertical */ vdotn_h1 = bh + ah; /* Lower horizontal */ vdotn_h2 = bh - ah; /* Upper horizontal */ /* Compute the dot products of (O - r) and n as c1+c2 and c1-c2 */ cv1 = -whalf*l - z*ww; cv2 = x*l; ch1 = -hhalf*l - z*hh; ch2 = y*l; /* Compute intersection times. */ t1 = (l - z)/vz; i = 0; if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) { t1 = t2; i = 1; } if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) { t1 = t2; i = 2; } if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) { t1 = t2; i = 3; } if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) { t1 = t2; i = 4; } if(i == 0) break; /* Neutron left guide. */ PROP_DT(t1); switch(i) { case 1: /* Left vertical mirror */ nlen2 = l*l + ww*ww; q = V2Q*(-2)*vdotn_v1/sqrt(nlen2); d = 2*vdotn_v1/nlen2; vx = vx - d*l; vz = vz - d*ww; break; case 2: /* Right vertical mirror */ nlen2 = l*l + ww*ww; q = V2Q*(-2)*vdotn_v2/sqrt(nlen2); d = 2*vdotn_v2/nlen2; vx = vx + d*l; vz = vz - d*ww; break; case 3: /* Lower horizontal mirror */ nlen2 = l*l + hh*hh; q = V2Q*(-2)*vdotn_h1/sqrt(nlen2); d = 2*vdotn_h1/nlen2; vy = vy - d*l; vz = vz - d*hh; break; case 4: /* Upper horizontal mirror */ nlen2 = l*l + hh*hh; q = V2Q*(-2)*vdotn_h2/sqrt(nlen2); d = 2*vdotn_h2/nlen2; vy = vy + d*l; vz = vz - d*hh; break; } /* Now compute reflectivity. */ if(m == 0) ABSORB; if(q > Qc) { double arg = (q-m*Qc)/W; if(arg < 10) p *= .5*(1-tanh(arg))*(1-alpha*(q-Qc)); else ABSORB; /* Cutoff ~ 1E-10 */ } p *= R0; SCATTER; } %} MCDISPLAY %{ double x; int i; magnify("xy"); multiline(5, -w1/2.0, -h1/2.0, 0.0, w1/2.0, -h1/2.0, 0.0, w1/2.0, h1/2.0, 0.0, -w1/2.0, h1/2.0, 0.0, -w1/2.0, -h1/2.0, 0.0); multiline(5, -w2/2.0, -h2/2.0, (double)l, w2/2.0, -h2/2.0, (double)l, w2/2.0, h2/2.0, (double)l, -w2/2.0, h2/2.0, (double)l, -w2/2.0, -h2/2.0, (double)l); line(-w1/2.0, -h1/2.0, 0, -w2/2.0, -h2/2.0, (double)l); line( w1/2.0, -h1/2.0, 0, w2/2.0, -h2/2.0, (double)l); line( w1/2.0, h1/2.0, 0, w2/2.0, h2/2.0, (double)l); line(-w1/2.0, h1/2.0, 0, -w2/2.0, h2/2.0, (double)l); %} END