/*******************************************************************************
*
* McStas, version 1.0, released October 26, 1998
* Maintained by Kristian Nielsen and Kim Lefmann,
* Risoe National Laboratory, Roskilde, Denmark
*
* Component: Guide2.
*
* %Identification
* Written by: KN
* Date: September 2 1998, Modified by: KL, October 6, 1998
* Origin: McStas 1.0 (1998)
* Version: 1.0 (Obsolete)
* Modified by: EF, 2004. Obsoleted as other comps do the same task
*
* Models a rectangular guide with different vert. and horiz. m mirror values.
* See Channeled_guide component
* OBSOLETE: rather use optics/Guide_gravity or Guide_channeled
*
* %Description
* 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 (Guide component).
*
* Example values: mh=mv=4 Qc=0.02 W=1/300 alpha=6.49 R0=1
*
* %Parameters
* 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
* mh: (1) m-horizontal value of material
* mv: (1) m-vertical value of material
* W: (AA-1) Width of supermirror cut-off
*
* %End
*******************************************************************************/
DEFINE COMPONENT Guide2
DEFINITION PARAMETERS ()
SETTING PARAMETERS (w1, h1, w2, h2, l, R0=0.99, Qc=0.021, alpha=6.07, mh=2, mv=2, W=0.003)
STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p)
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(q > Qc)
{
double arg = (q - (i <= 2 ? mv : mh)*Qc)/W;
if(arg < 10)
p *= .5*(1-tanh(arg))*(1-alpha*(q-Qc));
else
ABSORB; /* Cutoff ~ 1E-10 */
}
p *= R0;
}
%}
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