From 36c83823bca0384e0bd9ddd54556622207b5d970 Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Tue, 17 Feb 2026 19:20:20 +0100 Subject: [PATCH] Apply formatter to optics --- mcstas-comps/optics/Absorber.comp | 28 +- mcstas-comps/optics/Arm.comp | 14 +- mcstas-comps/optics/Beamstop.comp | 46 +- mcstas-comps/optics/Bender.comp | 329 ++- mcstas-comps/optics/Collimator_linear.comp | 89 +- mcstas-comps/optics/Collimator_radial.comp | 245 +- mcstas-comps/optics/Derotator.comp | 12 +- mcstas-comps/optics/DiskChopper.comp | 207 +- .../optics/Elliptic_guide_gravity.comp | 2354 ++++++++--------- mcstas-comps/optics/FZP_simple.comp | 128 +- mcstas-comps/optics/FermiChopper.comp | 1103 ++++---- mcstas-comps/optics/Filter_gen.comp | 176 +- mcstas-comps/optics/Guide.comp | 205 +- mcstas-comps/optics/Guide_anyshape.comp | 106 +- mcstas-comps/optics/Guide_channeled.comp | 330 +-- mcstas-comps/optics/Guide_gravity.comp | 725 ++--- mcstas-comps/optics/Guide_simple.comp | 189 +- mcstas-comps/optics/Guide_tapering.comp | 898 +++---- mcstas-comps/optics/Guide_wavy.comp | 291 +- mcstas-comps/optics/He3_cell.comp | 130 +- mcstas-comps/optics/Mask.comp | 253 +- mcstas-comps/optics/Mirror.comp | 56 +- mcstas-comps/optics/Monochromator_curved.comp | 535 ++-- mcstas-comps/optics/Monochromator_flat.comp | 210 +- mcstas-comps/optics/Monochromator_pol.comp | 83 +- mcstas-comps/optics/PolAnalyser_ideal.comp | 66 +- mcstas-comps/optics/Pol_Bfield.comp | 232 +- mcstas-comps/optics/Pol_Bfield_stop.comp | 84 +- mcstas-comps/optics/Pol_FieldBox.comp | 64 +- mcstas-comps/optics/Pol_SF_ideal.comp | 69 +- mcstas-comps/optics/Pol_bender.comp | 451 ++-- mcstas-comps/optics/Pol_constBfield.comp | 55 +- mcstas-comps/optics/Pol_guide_mirror.comp | 327 ++- mcstas-comps/optics/Pol_guide_vmirror.comp | 576 ++-- mcstas-comps/optics/Pol_mirror.comp | 120 +- mcstas-comps/optics/Pol_tabled_field.comp | 194 +- mcstas-comps/optics/Refractor.comp | 563 ++-- mcstas-comps/optics/Rotator.comp | 57 +- mcstas-comps/optics/Selector.comp | 120 +- mcstas-comps/optics/Set_pol.comp | 57 +- mcstas-comps/optics/Slit.comp | 111 +- mcstas-comps/optics/V_selector.comp | 111 +- mcstas-comps/optics/Vitess_ChopperFermi.comp | 128 +- 43 files changed, 5969 insertions(+), 6158 deletions(-) diff --git a/mcstas-comps/optics/Absorber.comp b/mcstas-comps/optics/Absorber.comp index 2c5c666b7f..51390ec6a5 100644 --- a/mcstas-comps/optics/Absorber.comp +++ b/mcstas-comps/optics/Absorber.comp @@ -50,25 +50,27 @@ DECLARE INITIALIZE %{ - xw = xmax-xmin; - yh = ymax-ymin; - zt = zmax-zmin; - xm = (xmax+xmin)/2; - ym = (ymax+ymin)/2; - zm = (zmax+zmin)/2; - if (xw == 0 || yh == 0 || zt == 0) - { fprintf(stderr,"Absorber: %s: Error: Slab volume is zero!\n", NAME_CURRENT_COMP); exit(-1); } + xw = xmax - xmin; + yh = ymax - ymin; + zt = zmax - zmin; + xm = (xmax + xmin) / 2; + ym = (ymax + ymin) / 2; + zm = (zmax + zmin) / 2; + if (xw == 0 || yh == 0 || zt == 0) { + fprintf (stderr, "Absorber: %s: Error: Slab volume is zero!\n", NAME_CURRENT_COMP); + exit (-1); + } %} TRACE %{ - double t0,t1,xp,yp,zp; + double t0, t1, xp, yp, zp; xp = x - xm; yp = y - ym; zp = z - zm; - if (box_intersect(&t0, &t1, xp, yp, zp, vx, vy, vz, xw, yh, zt)) { - if (t1>=0) { - PROP_DT((t1+t0)/2); + if (box_intersect (&t0, &t1, xp, yp, zp, vx, vy, vz, xw, yh, zt)) { + if (t1 >= 0) { + PROP_DT ((t1 + t0) / 2); SCATTER; ABSORB; } @@ -77,7 +79,7 @@ TRACE MCDISPLAY %{ - box(xm, ym, zm, xw, yh, zt,0, 0, 1, 0); + box (xm, ym, zm, xw, yh, zt, 0, 0, 1, 0); %} END diff --git a/mcstas-comps/optics/Arm.comp b/mcstas-comps/optics/Arm.comp index 1eafb09a33..29a102761f 100644 --- a/mcstas-comps/optics/Arm.comp +++ b/mcstas-comps/optics/Arm.comp @@ -67,16 +67,14 @@ FINALLY MCDISPLAY %{ /* A bit ugly; hard-coded dimensions. */ - - line(0,0,0,0.2,0,0); - line(0,0,0,0,0.2,0); - line(0,0,0,0,0,0.2); + line (0, 0, 0, 0.2, 0, 0); + line (0, 0, 0, 0, 0.2, 0); + line (0, 0, 0, 0, 0, 0.2); - cone(0.2,0,0,0.01,0.02,1,0,0); - cone(0,0.2,0,0.01,0.02,0,1,0); - cone(0,0,0.2,0.01,0.02,0,0,1); - + cone (0.2, 0, 0, 0.01, 0.02, 1, 0, 0); + cone (0, 0.2, 0, 0.01, 0.02, 0, 1, 0); + cone (0, 0, 0.2, 0.01, 0.02, 0, 0, 1); %} END diff --git a/mcstas-comps/optics/Beamstop.comp b/mcstas-comps/optics/Beamstop.comp index b872f7a772..6cab5dd861 100644 --- a/mcstas-comps/optics/Beamstop.comp +++ b/mcstas-comps/optics/Beamstop.comp @@ -48,38 +48,42 @@ xwidth=0, yheight=0, radius=0) INITIALIZE %{ -if (xwidth > 0) { xmax = xwidth/2; xmin = -xmax; } - if (yheight > 0) { ymax = yheight/2; ymin = -ymax; } + if (xwidth > 0) { + xmax = xwidth / 2; + xmin = -xmax; + } + if (yheight > 0) { + ymax = yheight / 2; + ymin = -ymax; + } - if (xmin == 0 && xmax == 0 && ymin == 0 & ymax == 0 && radius == 0) - { fprintf(stderr,"Beamstop: %s: Error: give geometry\n", NAME_CURRENT_COMP); exit(-1); } + if (xmin == 0 && xmax == 0 && ymin == 0 & ymax == 0 && radius == 0) { + fprintf (stderr, "Beamstop: %s: Error: give geometry\n", NAME_CURRENT_COMP); + exit (-1); + } %} TRACE %{ - double Time = t; - ALLOW_BACKPROP; - PROP_Z0; - Time = t - Time; - if ((Time>=0) && ((radius!=0) && (x*x + y*y <= radius*radius)) - || ((Time>=0) && (radius==0) && (x>xmin && xymin && y= 0) && ((radius != 0) && (x * x + y * y <= radius * radius)) || ((Time >= 0) && (radius == 0) && (x > xmin && x < xmax && y > ymin && y < ymax))) { + SCATTER; + ABSORB; + } else { + RESTORE_NEUTRON (INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p); + } %} MCDISPLAY %{ - + if (radius != 0) - circle("xy", 0, 0, 0, radius); + circle ("xy", 0, 0, 0, radius); else - multiline(5, (double)xmin, (double)ymin, 0.0, - (double)xmax, (double)ymin, 0.0, - (double)xmax, (double)ymax, 0.0, - (double)xmin, (double)ymax, 0.0, + multiline (5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} diff --git a/mcstas-comps/optics/Bender.comp b/mcstas-comps/optics/Bender.comp index 762ae81522..14f316232f 100644 --- a/mcstas-comps/optics/Bender.comp +++ b/mcstas-comps/optics/Bender.comp @@ -104,165 +104,162 @@ SHARE DECLARE %{ -double bk; -double mWin; + double bk; + double mWin; %} INITIALIZE %{ -if (r <0) - { fprintf(stderr,"Bender: error: %s: to bend in the other direction\n", NAME_CURRENT_COMP); - fprintf(stderr," rotate comp on z-axis by 180 deg.\n"); exit(-1); } - - if (k*d > w) - { fprintf(stderr,"Bender: error: %s has (k*d > w).\n", NAME_CURRENT_COMP); - exit(-1); } - if (w*h*r*Win*k == 0) - { fprintf(stderr,"Bender: error: %s has one of w,h,r,Win,k null.\n", NAME_CURRENT_COMP); - exit(-1); } - /* width of one channel + thickness d of partition */ - mWin = Win; - if (l!= 0 && r != 0) mWin = (double)l/(double)r; - bk=(w+d)/k; - if (mcgravitation) fprintf(stderr,"WARNING: Bender: %s: " - "This component produces wrong results with gravitation !\n", - NAME_CURRENT_COMP); + if (r < 0) { + fprintf (stderr, "Bender: error: %s: to bend in the other direction\n", NAME_CURRENT_COMP); + fprintf (stderr, " rotate comp on z-axis by 180 deg.\n"); + exit (-1); + } + + if (k * d > w) { + fprintf (stderr, "Bender: error: %s has (k*d > w).\n", NAME_CURRENT_COMP); + exit (-1); + } + if (w * h * r * Win * k == 0) { + fprintf (stderr, "Bender: error: %s has one of w,h,r,Win,k null.\n", NAME_CURRENT_COMP); + exit (-1); + } + /* width of one channel + thickness d of partition */ + mWin = Win; + if (l != 0 && r != 0) + mWin = (double)l / (double)r; + bk = (w + d) / k; + if (mcgravitation) + fprintf (stderr, + "WARNING: Bender: %s: " + "This component produces wrong results with gravitation !\n", + NAME_CURRENT_COMP); %} TRACE %{ - int i,num,numa,numi; - double dru,ab,dab,R,Q,Ta,vpl; - double einmWin,ausmWin,zykmWin,aeumWin,innmWin,ref,innref,aeuref; - double einzei,auszei,zykzei; - - /* does the neutron hit the bender at the entrance? */ - PROP_Z0; - if ((fabs(x)bk-d) - { - double inn[] = {R0i, Qci, alphai, mi, Wi}; - /* reflection coefficient at the convex side */ - innmWin=acos((R-dab)/(R-bk+d)); - Q=2.0*V2K*vpl*sin(innmWin); - StdReflecFunc(Q, inn, &innref); - } - - /* divergence of the neutron at the exit */ - zykmWin=2.0*(aeumWin-innmWin); - ausmWin=fmod(mWin+einmWin+aeumWin-innmWin - *(1.0+SIGN(einmWin)),zykmWin)-zykmWin/2.0; - ausmWin+=innmWin*SIGN(ausmWin); - - /* number of reflections at the concave side */ - numa=(mWin+einmWin+aeumWin-innmWin*(1.0+SIGN(einmWin)))/zykmWin; - - /* number of reflections at the convex side */ - numi=numa; - if (ausmWin*einmWin<0) - { - if (ausmWin-einmWin>0) - numi++; - else - numi--; - } + int i, num, numa, numi; + double dru, ab, dab, R, Q, Ta, vpl; + double einmWin, ausmWin, zykmWin, aeumWin, innmWin, ref, innref, aeuref; + double einzei, auszei, zykzei; + + /* does the neutron hit the bender at the entrance? */ + PROP_Z0; + if ((fabs (x) < w / 2) && (fabs (y) < h / 2)) { + /*** reflections in the XZ-plane ***/ + + /* distance between neutron and concave side of the channel at the entrance */ + dru = floor ((w / 2 - x) / bk) * bk; + ab = w / 2.0 - x - dru; + + /* radius of the channel */ + R = r - dru; + + /* does the neutron hit the partition at the entrance? */ + if (ab < bk - d) { + double aeu[] = { R0a, Qca, alphaa, ma, Wa }; + /* velocity in the XZ-plane */ + vpl = sqrt (vx * vx + vz * vz); + + /* divergence of the neutron at the entrance */ + einmWin = atan (vx / vz); + + /* maximal distance between neutron and concave side of the channel */ + dab = R - cos (einmWin) * (R - ab); + + /* reflection angle at the concave side */ + aeumWin = acos ((R - dab) / R); + + /* reflection coefficient at the concave side */ + Q = 2.0 * V2K * vpl * sin (aeumWin); + StdReflecFunc (Q, aeu, &aeuref); + + /* does the neutron hit the convex side of the channel? */ + innmWin = 0.0; + innref = 1.0; + if (dab > bk - d) { + double inn[] = { R0i, Qci, alphai, mi, Wi }; + /* reflection coefficient at the convex side */ + innmWin = acos ((R - dab) / (R - bk + d)); + Q = 2.0 * V2K * vpl * sin (innmWin); + StdReflecFunc (Q, inn, &innref); + } + + /* divergence of the neutron at the exit */ + zykmWin = 2.0 * (aeumWin - innmWin); + ausmWin = fmod (mWin + einmWin + aeumWin - innmWin * (1.0 + SIGN (einmWin)), zykmWin) - zykmWin / 2.0; + ausmWin += innmWin * SIGN (ausmWin); + + /* number of reflections at the concave side */ + numa = (mWin + einmWin + aeumWin - innmWin * (1.0 + SIGN (einmWin))) / zykmWin; + + /* number of reflections at the convex side */ + numi = numa; + if (ausmWin * einmWin < 0) { + if (ausmWin - einmWin > 0) + numi++; + else + numi--; + } + + /* is the reflection coefficient too small? */ + if (((numa > 0) && (aeuref <= 0)) || ((numi > 0) && (innref <= 0))) + ABSORB; + + /* calculation of the neutron probability weight p */ + for (i = 1; i <= numa; i++) + p *= aeuref; + for (i = 1; i <= numi; i++) + p *= innref; + + /* time to cross the bender */ + Ta = (2 * numa * (tan (aeumWin) - tan (innmWin)) + tan (ausmWin) - tan (einmWin) - tan (innmWin) * (SIGN (ausmWin) - SIGN (einmWin))) * (R - dab) / vpl; + t += Ta; + + /* distance between neutron and concave side of channel at the exit */ + ab = R - (R - dab) / cos (ausmWin); + + /* calculation of the exit coordinates in the XZ-plane */ + x = w / 2.0 - ab - dru; + z = r * mWin; + vx = sin (ausmWin) * vpl; + vz = cos (ausmWin) * vpl; + + /*** reflections at top and bottom side (Y axis) ***/ + + if (vy != 0.0) { + double s[] = { R0s, Qcs, alphas, ms, Ws }; + /* reflection coefficent at the top and bottom side */ + Q = 2.0 * V2K * fabs (vy); + StdReflecFunc (Q, s, &ref); + + /* number of reflections at top and bottom */ + einzei = h / 2.0 / fabs (vy) + y / vy; + zykzei = h / fabs (vy); + num = (Ta + einzei) / zykzei; + + /* time between the last reflection and the exit */ + auszei = fmod (Ta + einzei, zykzei); /* is the reflection coefficient too small? */ - if (((numa>0) && (aeuref<=0)) || ((numi>0) && (innref<=0))) - ABSORB; - - /* calculation of the neutron probability weight p */ - for (i=1;i<=numa;i++) - p*=aeuref; - for (i=1;i<=numi;i++) - p*=innref; - - /* time to cross the bender */ - Ta=(2*numa*(tan(aeumWin)-tan(innmWin)) - +tan(ausmWin)-tan(einmWin) - -tan(innmWin)*(SIGN(ausmWin)-SIGN(einmWin))) - *(R-dab)/vpl; - t+=Ta; - - /* distance between neutron and concave side of channel at the exit */ - ab=R-(R-dab)/cos(ausmWin); - - /* calculation of the exit coordinates in the XZ-plane */ - x=w/2.0-ab-dru; - z=r*mWin; - vx=sin(ausmWin)*vpl; - vz=cos(ausmWin)*vpl; - - /*** reflections at top and bottom side (Y axis) ***/ - - if (vy!=0.0) - { - double s[] = {R0s, Qcs, alphas, ms, Ws}; - /* reflection coefficent at the top and bottom side */ - Q=2.0*V2K*fabs(vy); - StdReflecFunc(Q, s, &ref); - - /* number of reflections at top and bottom */ - einzei=h/2.0/fabs(vy)+y/vy; - zykzei=h/fabs(vy); - num=(Ta+einzei)/zykzei; - - /* time between the last reflection and the exit */ - auszei=fmod(Ta+einzei,zykzei); - - /* is the reflection coefficient too small? */ - if ((num>0) && (ref<=0)) - ABSORB; - - /* calculation of the probability weight p */ - for (i=1;i<=num;i++) { - p*=ref; - vy*=-1.0; } - - /* calculation of the exit coordinate */ - y=auszei*vy-vy*h/fabs(vy)/2.0; - } /* if (vy!=0.0) */ - SCATTER; - } /* if (dab>bk-d) */ - else - ABSORB; /* hit separating walls */ - } - else /* if ((fabs(x) 0) && (ref <= 0)) + ABSORB; + + /* calculation of the probability weight p */ + for (i = 1; i <= num; i++) { + p *= ref; + vy *= -1.0; + } + /* calculation of the exit coordinate */ + y = auszei * vy - vy * h / fabs (vy) / 2.0; + } /* if (vy!=0.0) */ + SCATTER; + } /* if (dab>bk-d) */ + else + ABSORB; /* hit separating walls */ + } else /* if ((fabs(x) 0) { xmax = xwidth/2; xmin = -xmax; } - if (yheight > 0) { ymax = yheight/2; ymin = -ymax; } + slope = tan (MIN2RAD * divergence); + slopeV = tan (MIN2RAD * divergenceV); + if (xwidth > 0) { + xmax = xwidth / 2; + xmin = -xmax; + } + if (yheight > 0) { + ymax = yheight / 2; + ymin = -ymax; + } if ((xmin >= xmax) || (ymin >= ymax)) { - printf("Collimator_linear: %s: Null slit opening area !\n" - "ERROR (xwidth,yheight,xmin,xmax,ymin,ymax). Exiting", - NAME_CURRENT_COMP); - exit(0); + printf ("Collimator_linear: %s: Null slit opening area !\n" + "ERROR (xwidth,yheight,xmin,xmax,ymin,ymax). Exiting", + NAME_CURRENT_COMP); + exit (0); } - %} TRACE %{ - double phi, dt; + double phi, dt; + + PROP_Z0; + if (x < xmin || x > xmax || y < ymin || y > ymax) + ABSORB; + dt = length / vz; + PROP_DT (dt); + if (x < xmin || x > xmax || y < ymin || y > ymax) + ABSORB; - PROP_Z0; - if (xxmax || yymax) + if (slope > 0.0) { + phi = fabs (vx / vz); + if (phi > slope) ABSORB; - dt = length/vz; - PROP_DT(dt); - if (xxmax || yymax) + else + p *= transmission * (1.0 - phi / slope); + SCATTER; + } + if (slopeV > 0) { + phi = fabs (vy / vz); + if (phi > slopeV) ABSORB; - - if(slope > 0.0) - { - phi = fabs(vx/vz); - if (phi > slope) - ABSORB; - else - p *= transmission*(1.0 - phi/slope); - SCATTER; - } - if (slopeV > 0) { - phi = fabs(vy/vz); - if (phi > slopeV) - ABSORB; - else - p *= transmission*(1.0 - phi/slopeV); - SCATTER; - } + else + p *= transmission * (1.0 - phi / slopeV); + SCATTER; + } %} MCDISPLAY @@ -102,15 +106,12 @@ MCDISPLAY double x; int i; - - for(x = xmin, i = 0; i <= 3; i++, x += (xmax - xmin)/3.0) - multiline(5, x, (double)ymin, 0.0, x, (double)ymax, 0.0, - x, (double)ymax, (double)length, x, (double)ymin, (double)length, - x, (double)ymin, 0.0); - line(xmin, ymin, 0, xmax, ymin, 0); - line(xmin, ymax, 0, xmax, ymax, 0); - line(xmin, ymin, length, xmax, ymin, length); - line(xmin, ymax, length, xmax, ymax, length); + for (x = xmin, i = 0; i <= 3; i++, x += (xmax - xmin) / 3.0) + multiline (5, x, (double)ymin, 0.0, x, (double)ymax, 0.0, x, (double)ymax, (double)length, x, (double)ymin, (double)length, x, (double)ymin, 0.0); + line (xmin, ymin, 0, xmax, ymin, 0); + line (xmin, ymax, 0, xmax, ymax, 0); + line (xmin, ymin, length, xmax, ymin, length); + line (xmin, ymax, length, xmax, ymax, length); %} END diff --git a/mcstas-comps/optics/Collimator_radial.comp b/mcstas-comps/optics/Collimator_radial.comp index f43005aba3..cb12eb738f 100644 --- a/mcstas-comps/optics/Collimator_radial.comp +++ b/mcstas-comps/optics/Collimator_radial.comp @@ -76,182 +76,190 @@ roc=0, verbose=0, approx=0, focusing = 0, yheight_inner = 0) DECLARE %{ -double width_of_slit; -double width_of_Soller; -double slit_theta; + double width_of_slit; + double width_of_Soller; + double slit_theta; %} INITIALIZE %{ -width_of_slit=0; -width_of_Soller=0; -slit_theta=0; + width_of_slit = 0; + width_of_Soller = 0; + slit_theta = 0; -if (radius <= 0) - exit(printf("Collimator_radial: %s: incorrect radius=%g\n", NAME_CURRENT_COMP, radius)); + if (radius <= 0) + exit (printf ("Collimator_radial: %s: incorrect radius=%g\n", NAME_CURRENT_COMP, radius)); if (length <= 0) - exit(printf("Collimator_radial: %s: invalid collimator length=%g\n", NAME_CURRENT_COMP, length)); - if (transmission <= 0 || transmission >1) - exit(printf("Collimator_radial: %s: invalid transmission=%g\n", NAME_CURRENT_COMP, transmission)); + exit (printf ("Collimator_radial: %s: invalid collimator length=%g\n", NAME_CURRENT_COMP, length)); + if (transmission <= 0 || transmission > 1) + exit (printf ("Collimator_radial: %s: invalid transmission=%g\n", NAME_CURRENT_COMP, transmission)); theta_max *= DEG2RAD; theta_min *= DEG2RAD; - roc *= DEG2RAD; - divergence*= MIN2RAD; + roc *= DEG2RAD; + divergence *= MIN2RAD; if (xwidth && !nchan) - nchan = ceil(radius*fabs(theta_max-theta_min)/xwidth); + nchan = ceil (radius * fabs (theta_max - theta_min) / xwidth); else if (!xwidth && nchan) - xwidth = radius*fabs(theta_max-theta_min)/nchan; + xwidth = radius * fabs (theta_max - theta_min) / nchan; /* determine total width [m] of Soller channels, containing nslit in xwidth */ if (nchan) { - width_of_Soller = radius*fabs(theta_max-theta_min)/nchan; - } - else width_of_Soller = 0; + width_of_Soller = radius * fabs (theta_max - theta_min) / nchan; + } else + width_of_Soller = 0; if (!nchan || !xwidth || xwidth > width_of_Soller) - nchan=xwidth=width_of_Soller=0; /* continuous collimator */ + nchan = xwidth = width_of_Soller = 0; /* continuous collimator */ /* determine width [m] of slits */ if (divergence) { - width_of_slit = length*tan(divergence); - if (xwidth) /* Soller */ - nslit = ceil(xwidth/width_of_slit); - else if (!nchan) /* continuous collimator */ - nslit = ceil(radius*fabs(theta_max-theta_min)/width_of_slit); + width_of_slit = length * tan (divergence); + if (xwidth) /* Soller */ + nslit = ceil (xwidth / width_of_slit); + else if (!nchan) /* continuous collimator */ + nslit = ceil (radius * fabs (theta_max - theta_min) / width_of_slit); } else { - if (!nchan && nslit) /* continuous collimator */ - width_of_slit = radius*fabs(theta_max-theta_min)/nslit; - else if (nchan && nslit) /* Soller */ - width_of_slit = xwidth/nslit; - divergence = atan2(width_of_slit,length); + if (!nchan && nslit) /* continuous collimator */ + width_of_slit = radius * fabs (theta_max - theta_min) / nslit; + else if (nchan && nslit) /* Soller */ + width_of_slit = xwidth / nslit; + divergence = atan2 (width_of_slit, length); } if (nslit <= 0) - printf("Collimator_radial: %s: number of channels must be positive nslit=%g.\n" - "WARNING Specify alternatively divergence, xwidth and nchan.\n", - NAME_CURRENT_COMP, nslit); + printf ("Collimator_radial: %s: number of channels must be positive nslit=%g.\n" + "WARNING Specify alternatively divergence, xwidth and nchan.\n", + NAME_CURRENT_COMP, nslit); if (verbose && nslit && width_of_slit) { - printf("Collimator_radial: %s: divergence %g [min] %s" - ". Total opening [%g:%g] [deg]\n", - NAME_CURRENT_COMP, divergence*RAD2MIN, - (roc ? "oscillating" : ""), - theta_min*RAD2DEG, theta_max*RAD2DEG); + printf ("Collimator_radial: %s: divergence %g [min] %s" + ". Total opening [%g:%g] [deg]\n", + NAME_CURRENT_COMP, divergence * RAD2MIN, (roc ? "oscillating" : ""), theta_min * RAD2DEG, theta_max * RAD2DEG); if (approx) - printf(" Using triangular approximation model"); + printf (" Using triangular approximation model"); else if (!nchan) - printf(" Using continuous model"); + printf (" Using continuous model"); else - printf(" Using %i Soller channels of width %g [cm]", - (int)nchan, width_of_Soller*100); + printf (" Using %i Soller channels of width %g [cm]", (int)nchan, width_of_Soller * 100); - printf(" with %i slits of width %g [mm] pitch %g [deg].\n", - (int)nslit, width_of_slit*1000, atan2(width_of_slit, radius)*RAD2DEG); + printf (" with %i slits of width %g [mm] pitch %g [deg].\n", (int)nslit, width_of_slit * 1000, atan2 (width_of_slit, radius) * RAD2DEG); } - if (!yheight_inner) yheight_inner = yheight; - + if (!yheight_inner) + yheight_inner = yheight; %} TRACE %{ - double intersect=0; + double intersect = 0; double t0, t1, t2, t3; if (width_of_slit && nslit) { /* determine intersection with inner and outer cylinders */ - intersect=cylinder_intersect(&t0,&t3,x,y,z,vx,vy,vz,radius,yheight_inner); - if (!intersect) ABSORB; - else if (t3 > t0 && !focusing) t0 = t3; - - intersect=cylinder_intersect(&t1,&t2,x,y,z,vx,vy,vz,radius+length,yheight); - if (!intersect) ABSORB; - else if (t2 > t1 && !focusing) t1 = t2; - + intersect = cylinder_intersect (&t0, &t3, x, y, z, vx, vy, vz, radius, yheight_inner); + if (!intersect) + ABSORB; + else if (t3 > t0 && !focusing) + t0 = t3; + + intersect = cylinder_intersect (&t1, &t2, x, y, z, vx, vy, vz, radius + length, yheight); + if (!intersect) + ABSORB; + else if (t2 > t1 && !focusing) + t1 = t2; + /* propagate/determine neutron position at ingoing cylinder */ if ((t0 > 0 && t1 > t0 && !focusing) || (t1 > 0 && t0 > t1 && focusing)) { - double input_chan=0; - double input_theta=0, output_theta=0; - double roc_theta=0; - double input_slit=0, output_slit=0; - if (!focusing) PROP_DT(t0); - if (focusing) PROP_DT(t1); + double input_chan = 0; + double input_theta = 0, output_theta = 0; + double roc_theta = 0; + double input_slit = 0, output_slit = 0; + if (!focusing) + PROP_DT (t0); + if (focusing) + PROP_DT (t1); /* apply ROC oscillation with a linear random distribution */ - if (roc) roc_theta = roc*randpm1()/2; else roc_theta=0; + if (roc) + roc_theta = roc * randpm1 () / 2; + else + roc_theta = 0; /* angle on the initial relevant cylinder */ - input_theta = atan2(x, z) + roc_theta; + input_theta = atan2 (x, z) + roc_theta; /* check if we are within min/max collimator input bounds */ if (input_theta >= theta_min && input_theta <= theta_max) { SCATTER; /* input Soller channel index */ if (width_of_Soller) { - input_chan = radius*(input_theta-theta_min)/width_of_Soller; - input_chan = input_chan-floor(input_chan); /* position within Soller [0:1] */ + input_chan = radius * (input_theta - theta_min) / width_of_Soller; + input_chan = input_chan - floor (input_chan); /* position within Soller [0:1] */ /* check if we hit an absorbing housing (between Sollers): ABSORB * total Soller aperture is width_of_Soller, * containg a slit pack of aperture xwidth */ - if (input_chan < (1-xwidth/width_of_Soller)/2 - || input_chan > (1+xwidth/width_of_Soller)/2) ABSORB; + if (input_chan < (1 - xwidth / width_of_Soller) / 2 || input_chan > (1 + xwidth / width_of_Soller) / 2) + ABSORB; } /* determine input slit index */ - input_slit = floor(input_theta*radius/width_of_slit); + input_slit = floor (input_theta * radius / width_of_slit); } else /* neutron missed collimator input range */ - input_theta=4*PI; + input_theta = 4 * PI; /* propagate to next cylinder */ - - if (!focusing) PROP_DT(t1-t0); - if (focusing) PROP_DT(t0-t1); + + if (!focusing) + PROP_DT (t1 - t0); + if (focusing) + PROP_DT (t0 - t1); /* angle on the outgoing cylinder */ - output_theta = atan2(x, z) + roc_theta; + output_theta = atan2 (x, z) + roc_theta; /* check if we are within min/max collimator output bounds */ if (output_theta >= theta_min && output_theta <= theta_max) { /* check if we come from sides: ABSORB */ - if (input_theta > 2*PI) ABSORB; /* input_theta=4*PI when missed input */ + if (input_theta > 2 * PI) + ABSORB; /* input_theta=4*PI when missed input */ if (approx) { - double phi=atan2(x, z)-atan2(vx, vz); /* difference between positional slit angle and velocity */ - if (fabs(phi) > divergence) + double phi = atan2 (x, z) - atan2 (vx, vz); /* difference between positional slit angle and velocity */ + if (fabs (phi) > divergence) ABSORB; /* get outside transmission */ else - p *= (1.0 - phi/divergence); + p *= (1.0 - phi / divergence); } else { /* check if we have changed slit: ABSORB */ /* slits are considered radial so that their output size is: width_of_slit*(radius+length)/radius and it turns out this the same exp as for input */ - output_slit = floor(output_theta*radius/width_of_slit); - if (input_slit != output_slit) ABSORB; + output_slit = floor (output_theta * radius / width_of_slit); + if (input_slit != output_slit) + ABSORB; } SCATTER; p *= transmission; - } - else if (focusing) ABSORB; - /* else neutron missed collimator output range*/ - + } else if (focusing) + ABSORB; + /* else neutron missed collimator output range*/ + } /* else did not encounter collimator cylinders */ } /* if nslit */ - %} MCDISPLAY %{ double Soller_theta; - double height_inner = yheight/2; - double height_outer = yheight_inner/2; + double height_inner = yheight / 2; + double height_outer = yheight_inner / 2; double theta1, theta2; - double x_in_l, z_in_l, x_in_r, z_in_r; + double x_in_l, z_in_l, x_in_r, z_in_r; double x_out_l, z_out_l, x_out_r, z_out_r; int i; @@ -259,51 +267,44 @@ MCDISPLAY in order to avoid too many lines, we shown main housing and channels but no slit */ - if (!nchan || nchan > 20) nchan=20; - if (nchan > 64) nchan=64; - Soller_theta=fabs(theta_max-theta_min)/nchan; /* angular width of Soller */ + if (!nchan || nchan > 20) + nchan = 20; + if (nchan > 64) + nchan = 64; + Soller_theta = fabs (theta_max - theta_min) / nchan; /* angular width of Soller */ /* draw all channels, which also show housing */ - + for (i = 0; i < nchan; i++) { - theta1 = i*Soller_theta+theta_min; - theta2 = theta1+Soller_theta; + theta1 = i * Soller_theta + theta_min; + theta2 = theta1 + Soller_theta; - z_in_l = radius*cos(theta1); - x_in_l = radius*sin(theta1); - z_in_r = radius*cos(theta2); - x_in_r = radius*sin(theta2); + z_in_l = radius * cos (theta1); + x_in_l = radius * sin (theta1); + z_in_r = radius * cos (theta2); + x_in_r = radius * sin (theta2); - z_out_l = (radius+length)*cos(theta1); - x_out_l = (radius+length)*sin(theta1); - z_out_r = (radius+length)*cos(theta2); - x_out_r = (radius+length)*sin(theta2); + z_out_l = (radius + length) * cos (theta1); + x_out_l = (radius + length) * sin (theta1); + z_out_r = (radius + length) * cos (theta2); + x_out_r = (radius + length) * sin (theta2); /* left side */ - multiline(6, - x_in_l, -height_outer, z_in_l, - x_in_l, height_outer, z_in_l, - x_out_l, height_inner, z_out_l, - x_out_l,-height_inner, z_out_l, - x_in_l, -height_outer, z_in_l, - x_in_r, -height_outer, z_in_r); - /* left -> right lines */ - line(x_in_l, height_outer, z_in_l, x_in_r, height_outer, z_in_r); - line(x_out_l, height_inner, z_out_l, x_out_r, height_inner, z_out_r); - line(x_out_l, -height_inner, z_out_l, x_out_r,-height_inner, z_out_r); + multiline (6, x_in_l, -height_outer, z_in_l, x_in_l, height_outer, z_in_l, x_out_l, height_inner, z_out_l, x_out_l, -height_inner, z_out_l, x_in_l, + -height_outer, z_in_l, x_in_r, -height_outer, z_in_r); + /* left -> right lines */ + line (x_in_l, height_outer, z_in_l, x_in_r, height_outer, z_in_r); + line (x_out_l, height_inner, z_out_l, x_out_r, height_inner, z_out_r); + line (x_out_l, -height_inner, z_out_l, x_out_r, -height_inner, z_out_r); } /* remaining bits */ - theta1 = nchan*Soller_theta+theta_min; - z_in_l = radius*cos(theta1); - x_in_l = radius*sin(theta1); - z_out_l = (radius+length)*cos(theta1); - x_out_l = (radius+length)*sin(theta1); - multiline(5, - x_in_l, -height_outer, z_in_l, - x_in_l, height_outer, z_in_l, - x_out_l, height_inner, z_out_l, - x_out_l,-height_inner, z_out_l, - x_in_l, -height_outer, z_in_l); + theta1 = nchan * Soller_theta + theta_min; + z_in_l = radius * cos (theta1); + x_in_l = radius * sin (theta1); + z_out_l = (radius + length) * cos (theta1); + x_out_l = (radius + length) * sin (theta1); + multiline (5, x_in_l, -height_outer, z_in_l, x_in_l, height_outer, z_in_l, x_out_l, height_inner, z_out_l, x_out_l, -height_inner, z_out_l, x_in_l, + -height_outer, z_in_l); %} END diff --git a/mcstas-comps/optics/Derotator.comp b/mcstas-comps/optics/Derotator.comp index 89b459ae92..48a1b81e00 100644 --- a/mcstas-comps/optics/Derotator.comp +++ b/mcstas-comps/optics/Derotator.comp @@ -45,17 +45,17 @@ TRACE Rotation R; /* Name of Rotation uservar */ - char* Rot_varptr = *COMP_GETPAR3(Rotator, rotator, rot_var); + char* Rot_varptr = *COMP_GETPAR3 (Rotator, rotator, rot_var); /* Invert rotation matrix for use in derotation */ - rot_transpose(*(Rotation *) particle_getvar_void(_particle, Rot_varptr, NULL), R); + rot_transpose (*(Rotation*)particle_getvar_void (_particle, Rot_varptr, NULL), R); /* apply rotation to centered coordinates */ - Coords tmp = coords_set(x,y,z); - coords_get(rot_apply(R, tmp), &x, &y, &z); + Coords tmp = coords_set (x, y, z); + coords_get (rot_apply (R, tmp), &x, &y, &z); /* rotate speed */ - tmp = coords_set(vx,vy,vz); - coords_get(rot_apply(R, tmp), &vx, &vy, &vz); + tmp = coords_set (vx, vy, vz); + coords_get (rot_apply (R, tmp), &vx, &vy, &vz); %} END diff --git a/mcstas-comps/optics/DiskChopper.comp b/mcstas-comps/optics/DiskChopper.comp index fe4be02ed7..ecf4bf6147 100644 --- a/mcstas-comps/optics/DiskChopper.comp +++ b/mcstas-comps/optics/DiskChopper.comp @@ -73,109 +73,108 @@ SETTING PARAMETERS (theta_0=0, radius=0.5, yheight, nu, nslit=3, jitter=0, delay DECLARE %{ -double Tg; -double To; -double delta_y; -double height; -double omega; + double Tg; + double To; + double delta_y; + double height; + double omega; %} INITIALIZE %{ -/* If slit height 'unset', assume full opening */ -if (yheight == 0) { - height=radius; - } else { - height=yheight; - } - delta_y = radius-height/2; /* radius at beam center */ - omega=2.0*PI*nu; /* rad/s */ - if (xwidth && !theta_0 && radius) theta_0 = 2*RAD2DEG*asin(xwidth/2/delta_y); - - if (nslit<=0 || theta_0 <= 0 || radius <=0) - { fprintf(stderr,"DiskChopper: %s: nslit, theta_0 and radius must be > 0\n", NAME_CURRENT_COMP); - exit(-1); } - if (nslit*theta_0 >= 360) - { fprintf(stderr,"DiskChopper: %s: nslit * theta_0 exceeds 2PI\n", NAME_CURRENT_COMP); - exit(-1); } - if (yheight && yheight>radius) { - fprintf(stderr,"DiskChopper: %s: yheight must be < radius\n", NAME_CURRENT_COMP); - exit(-1); } - if (isfirst && n_pulse <=0) - { fprintf(stderr,"DiskChopper: %s: wrong First chopper pulse number (n_pulse=%g)\n", NAME_CURRENT_COMP, n_pulse); - exit(-1); } - if (!omega) { - fprintf(stderr,"DiskChopper: %s WARNING: chopper frequency is 0!\n", NAME_CURRENT_COMP); - omega = 1e-15; /* We should actually use machine epsilon here... */ - } - if (!abs_out) { - fprintf(stderr,"DiskChopper: %s WARNING: chopper will NOT absorb neutrons outside radius %g [m]\n", NAME_CURRENT_COMP, radius); - } - - theta_0*=DEG2RAD; - - - /* Calulate delay from phase and vice versa */ - if (phase) { - if (delay) { - fprintf(stderr,"DiskChopper: %s WARNING: delay AND phase specified. Using phase setting\n", NAME_CURRENT_COMP); - } - phase*=DEG2RAD; - /* 'Delay' should always be a delay, taking rotation direction into account: */ - delay=phase/fabs(omega); - } else { - phase=delay*omega; /* rad */ - } - - /* Time from opening of slit to next opening of slit */ - Tg=2.0*PI/fabs(omega)/nslit; - - /* How long can neutrons pass the Chopper at a single point */ - To=theta_0/fabs(omega); - - if (!xwidth) xwidth=2*delta_y*sin(theta_0/2); - - if (verbose && nu) { - printf("DiskChopper: %s: frequency=%g [Hz] %g [rpm], time frame=%g [s] phase=%g [deg]\n", - NAME_CURRENT_COMP, nu, nu*60, Tg, phase*RAD2DEG); - printf(" %g slits, angle=%g [deg] height=%g [m], width=%g [m] at radius=%g [m]\n", - nslit, theta_0*RAD2DEG, height, xwidth, delta_y); - } -%} + /* If slit height 'unset', assume full opening */ + if (yheight == 0) { + height = radius; + } else { + height = yheight; + } + delta_y = radius - height / 2; /* radius at beam center */ + omega = 2.0 * PI * nu; /* rad/s */ + if (xwidth && !theta_0 && radius) + theta_0 = 2 * RAD2DEG * asin (xwidth / 2 / delta_y); + + if (nslit <= 0 || theta_0 <= 0 || radius <= 0) { + fprintf (stderr, "DiskChopper: %s: nslit, theta_0 and radius must be > 0\n", NAME_CURRENT_COMP); + exit (-1); + } + if (nslit * theta_0 >= 360) { + fprintf (stderr, "DiskChopper: %s: nslit * theta_0 exceeds 2PI\n", NAME_CURRENT_COMP); + exit (-1); + } + if (yheight && yheight > radius) { + fprintf (stderr, "DiskChopper: %s: yheight must be < radius\n", NAME_CURRENT_COMP); + exit (-1); + } + if (isfirst && n_pulse <= 0) { + fprintf (stderr, "DiskChopper: %s: wrong First chopper pulse number (n_pulse=%g)\n", NAME_CURRENT_COMP, n_pulse); + exit (-1); + } + if (!omega) { + fprintf (stderr, "DiskChopper: %s WARNING: chopper frequency is 0!\n", NAME_CURRENT_COMP); + omega = 1e-15; /* We should actually use machine epsilon here... */ + } + if (!abs_out) { + fprintf (stderr, "DiskChopper: %s WARNING: chopper will NOT absorb neutrons outside radius %g [m]\n", NAME_CURRENT_COMP, radius); + } -TRACE -%{ - double toff; - double yprime; - PROP_Z0; - yprime = y+delta_y; + theta_0 *= DEG2RAD; - /* Is neutron outside the vertical slit range and should we absorb? */ - if (abs_out && (x*x+yprime*yprime)>radius*radius) { - ABSORB; - } - /* Does neutron hit inner solid part of chopper in case of yheight!=radius? */ - if ((x*x+yprime*yprime)<(radius-height)*(radius-height)) { - ABSORB; + /* Calulate delay from phase and vice versa */ + if (phase) { + if (delay) { + fprintf (stderr, "DiskChopper: %s WARNING: delay AND phase specified. Using phase setting\n", NAME_CURRENT_COMP); } + phase *= DEG2RAD; + /* 'Delay' should always be a delay, taking rotation direction into account: */ + delay = phase / fabs (omega); + } else { + phase = delay * omega; /* rad */ + } + /* Time from opening of slit to next opening of slit */ + Tg = 2.0 * PI / fabs (omega) / nslit; - if (isfirst) - { - /* all events are put in the transmitted time frame */ - t=atan2(x,yprime)/omega + To*randpm1()/2.0 + delay + (jitter ? jitter*randnorm():0) + (n_pulse > 1 ? floor(n_pulse*rand01())*Tg : 0); - /* correction: chopper slits transmission opening/full disk */ - p *= nslit*theta_0/2.0/PI; - } - else - { - toff=fabs(t-atan2(x,yprime)/omega - delay - (jitter ? jitter*randnorm():0)); + /* How long can neutrons pass the Chopper at a single point */ + To = theta_0 / fabs (omega); - /* does neutron hit outside slit? */ - if (fmod(toff+To/2.0,Tg)>To) ABSORB; - } - SCATTER; + if (!xwidth) + xwidth = 2 * delta_y * sin (theta_0 / 2); + if (verbose && nu) { + printf ("DiskChopper: %s: frequency=%g [Hz] %g [rpm], time frame=%g [s] phase=%g [deg]\n", NAME_CURRENT_COMP, nu, nu * 60, Tg, phase * RAD2DEG); + printf (" %g slits, angle=%g [deg] height=%g [m], width=%g [m] at radius=%g [m]\n", nslit, theta_0 * RAD2DEG, height, xwidth, delta_y); + } +%} + +TRACE +%{ + double toff; + double yprime; + PROP_Z0; + yprime = y + delta_y; + + /* Is neutron outside the vertical slit range and should we absorb? */ + if (abs_out && (x * x + yprime * yprime) > radius * radius) { + ABSORB; + } + /* Does neutron hit inner solid part of chopper in case of yheight!=radius? */ + if ((x * x + yprime * yprime) < (radius - height) * (radius - height)) { + ABSORB; + } + + if (isfirst) { + /* all events are put in the transmitted time frame */ + t = atan2 (x, yprime) / omega + To * randpm1 () / 2.0 + delay + (jitter ? jitter * randnorm () : 0) + (n_pulse > 1 ? floor (n_pulse * rand01 ()) * Tg : 0); + /* correction: chopper slits transmission opening/full disk */ + p *= nslit * theta_0 / 2.0 / PI; + } else { + toff = fabs (t - atan2 (x, yprime) / omega - delay - (jitter ? jitter * randnorm () : 0)); + + /* does neutron hit outside slit? */ + if (fmod (toff + To / 2.0, Tg) > To) + ABSORB; + } + SCATTER; %} MCDISPLAY @@ -183,26 +182,20 @@ MCDISPLAY int j; /* Arrays for storing geometry of slit/beamstop */ - - circle("xy", 0, -delta_y, 0, radius); + + circle ("xy", 0, -delta_y, 0, radius); /* Drawing the slit(s) */ - for (j=0; j L then they would change position as the + first and second focal points. This is + @param in,out is the input varible there the error occurred [text] + */ + int + guide_elliptical_illegalInputFocalPointsHyperbola (char* in, char* out, double inValue, double outValue, int verbose) { + if (verbose) { + printf ("The user defined length of the guide, length \ + and the focal points %s and %s does not result \ + in an well defined ellipse. swap the focal points \ + or increase L, %s or %s to fix this problem\n", + in, out, in, out); + printf ("The mininum length of the should be around %e\n", inValue + outValue + 0.000001); + } + return 1; + } -/////////////////////////////////////////////////////////////////////////// -/////////////// Error Handling Functions -/////////////////////////////////////////////////////////////////////////// + /** + Gives a warning if a part of the code is called that + should not be accessible if the algoritmes are working correctly + Most likely errors are floating points and ill-defined cases + */ + void + guide_elliptical_callCriticalWarning (char* func, int verbose) { + if (verbose) + printf ("A CRITICAL WARNING has been called inside %s by function %s." + "This is most likely due to a programming error \ + inside the component. \n", + "Elliptic_guide_gravity", func); + } -/** - If a user input is less than zero and hence doesn't allow for a well - define geomtric of the guide or physical values for mirrors - @param var is the input varible there the error occurred [text] -*/ -int guide_elliptical_illegalInputLessThanZero(char* var,int verbose){ - if (verbose) - printf("The user defined variable %s in %s has an illegal value" - " less than zero\n",var,"Elliptic_guide_gravity"); - return 1; -} + /////////////////////////////////////////////////////////////////////////// + /////////////// Collision handling functions + /////////////////////////////////////////////////////////////////////////// + + int + guide_elliptical_getMirrorTypeFromInput (char* input, int verbose) { + int type = -1; + char* r1 = "reflection"; + char* r2 = "reflect"; + char* r3 = "r"; + char* a1 = "absorption"; + char* a2 = "absorb"; + char* a3 = "a"; + char* t1 = "transparant"; + char* t2 = "trans"; + char* t3 = "t"; + if (strcmp (input, r1) == 0 || strcmp (input, r2) == 0 || strcmp (input, r3) == 0) + type = MirrorTypeReflection; + if (strcmp (input, a1) == 0 || strcmp (input, a2) == 0 || strcmp (input, a3) == 0) + type = MirrorTypeabsorption; + if (strcmp (input, t1) == 0 || strcmp (input, t2) == 0 || strcmp (input, t3) == 0) + type = MirrorTypeTransparent; + if (type == -1 && verbose) + printf ("Following string is not a valid type of a mirror: %s," + "use reflection,absorption or transparant. \n", + input); + + return type; + } -/** - The first focal point is in and the second is out. - If -in-out > L then they would change position as the - first and second focal points. This is - @param in,out is the input varible there the error occurred [text] -*/ -int guide_elliptical_illegalInputFocalPointsHyperbola( - char* in,char* out, - double inValue,double outValue, int verbose){ - if (verbose){ - printf("The user defined length of the guide, length \ - and the focal points %s and %s does not result \ - in an well defined ellipse. swap the focal points \ - or increase L, %s or %s to fix this problem\n", - in,out,in,out); - printf("The mininum length of the should be around %e\n", - inValue+outValue+0.000001); - } - return 1; -} + /////////////////////////////////////////////////////////////////////////// + /////////////// Collision functions + /////////////////////////////////////////////////////////////////////////// + + /** + Find the intersection between the neutron and the ellipse using newton method. + As there is up to 4 solution to this problem, and only the + smallest positive root is the physical solution. Using the tuning points + it is possible to look the only the potential roots to speed up calculations. + + @param coef; A pointer to the array holding the coeffecients + for the 4th order polynomial. + @param startPosition, The default starting point for newton method. [s] + @param limit; A point after all the roots of the polynial. [s] + @param solution A pointer which will hold the physical solution + if this function return true. + @return; return 1 if the physical solution is found. [boolean] + */ + #pragma acc routine seq + double + guide_elliptical_foverdf (double* coefficients, double currentPoint) { + double numerator = coefficients[0] * currentPoint * currentPoint * currentPoint * currentPoint + coefficients[1] * currentPoint * currentPoint * currentPoint + + coefficients[2] * currentPoint * currentPoint + coefficients[3] * currentPoint + coefficients[4]; + double denominator = 4 * coefficients[0] * currentPoint * currentPoint * currentPoint + 3 * coefficients[1] * currentPoint * currentPoint + + 2 * coefficients[2] * currentPoint + coefficients[3]; + return numerator / denominator; + } + #pragma acc routine seq + int + guide_elliptical_newtonRapsonsMethod4thOrder (double* coefficients, double* solution, double startingPoint, double tolerance, double max_iterations) { + + double numerator; + double denominator; + double t_previous; + double t = startingPoint; + int iteration = 0; + + do { + t_previous = t; + t = t_previous - guide_elliptical_foverdf (coefficients, t); + iteration++; + } while (fabs (t - t_previous) > tolerance && iteration < max_iterations); + if (iteration == max_iterations) { + return 0; + } else { + *solution = t; + return 1; + } + } -/** - Gives a warning if a part of the code is called that - should not be accessible if the algoritmes are working correctly - Most likely errors are floating points and ill-defined cases -*/ -void guide_elliptical_callCriticalWarning(char* func,int verbose){ - if (verbose) - printf("A CRITICAL WARNING has been called inside %s by function %s." - "This is most likely due to a programming error \ - inside the component. \n", - "Elliptic_guide_gravity",func); - } - -/////////////////////////////////////////////////////////////////////////// -/////////////// Collision handling functions -/////////////////////////////////////////////////////////////////////////// - -int guide_elliptical_getMirrorTypeFromInput(char * input,int verbose){ - int type = -1; - char* r1 = "reflection"; char* r2 = "reflect"; char* r3 = "r"; - char* a1 = "absorption"; char* a2 = "absorb"; char* a3 = "a"; - char* t1 = "transparant";char* t2 = "trans"; char* t3 = "t"; - if (strcmp (input, r1) == 0 - || strcmp (input, r2) == 0 - || strcmp (input, r3) == 0) - type = MirrorTypeReflection; - if (strcmp (input, a1) == 0 - || strcmp (input, a2) == 0 - || strcmp (input, a3) == 0) - type = MirrorTypeabsorption; - if (strcmp (input, t1) == 0 - || strcmp (input, t2) == 0 - || strcmp (input, t3) == 0) - type = MirrorTypeTransparent; - if ( type == -1 && verbose) - printf( "Following string is not a valid type of a mirror: %s," - "use reflection,absorption or transparant. \n" ,input); - - return type; - } - -/////////////////////////////////////////////////////////////////////////// -/////////////// Collision functions -/////////////////////////////////////////////////////////////////////////// + #pragma acc routine seq + int + guide_elliptical_findNeutronEllipseIntersection (double* coef, double startPosition, double limit, double* solution) { + + // in the case of no gravity + if (coef[0] == 0 & coef[1] == 0) { + double t1 = 0; + double t2 = 0; + int boolean = solve_2nd_order (&t1, &t2, coef[2], coef[3], coef[4]); + + if (t1 > startPosition) { + *solution = t1; + } + if (t2 > startPosition) { + *solution = t2; + } + return boolean; + } -/** - Find the intersection between the neutron and the ellipse using newton method. - As there is up to 4 solution to this problem, and only the - smallest positive root is the physical solution. Using the tuning points - it is possible to look the only the potential roots to speed up calculations. - - @param coef; A pointer to the array holding the coeffecients - for the 4th order polynomial. - @param startPosition, The default starting point for newton method. [s] - @param limit; A point after all the roots of the polynial. [s] - @param solution A pointer which will hold the physical solution - if this function return true. - @return; return 1 if the physical solution is found. [boolean] -*/ -#pragma acc routine seq -double guide_elliptical_foverdf(double *coefficients,double currentPoint){ - double numerator= coefficients[0]*currentPoint*currentPoint*currentPoint*currentPoint - + coefficients[1]*currentPoint*currentPoint*currentPoint - + coefficients[2]*currentPoint*currentPoint - + coefficients[3]*currentPoint - + coefficients[4]; - double denominator=4*coefficients[0]*currentPoint*currentPoint*currentPoint - + 3*coefficients[1]*currentPoint*currentPoint - + 2*coefficients[2]*currentPoint - + coefficients[3]; - return numerator/denominator; -} -#pragma acc routine seq -int guide_elliptical_newtonRapsonsMethod4thOrder( - double *coefficients,double *solution,double startingPoint, - double tolerance,double max_iterations){ - - double numerator; - double denominator; - double t_previous; - double t = startingPoint; - int iteration = 0; - - do { - t_previous = t; - t = t_previous - guide_elliptical_foverdf(coefficients,t); - iteration++; - } while( fabs(t-t_previous) > tolerance && iteration < max_iterations ); - if( iteration == max_iterations ) { return 0; } - else { *solution = t; return 1; } -} - - -#pragma acc routine seq -int guide_elliptical_findNeutronEllipseIntersection( - double *coef,double startPosition, - double limit,double *solution){ - - // in the case of no gravity - if(coef[0] == 0 & coef[1] == 0){ - double t1=0; - double t2=0; - int boolean = solve_2nd_order(&t1,&t2,coef[2],coef[3],coef[4]); - - if ( t1 > startPosition ){ *solution = t1; } - if ( t2 > startPosition ){ *solution = t2; } - return boolean; - } - - double tol = 1e-15; - double max_iter = 1e3; - double turningP1,turningP2; - - double sp = startPosition; - int inside; - if ( coef[0]*sp*sp*sp*sp - +coef[1]*sp*sp*sp - +coef[2]*sp*sp - +coef[3]*sp - +coef[4] < 0) - inside = 1; - else inside = 0; - - int boolean = solve_2nd_order( - &turningP1,&turningP2, - 12*coef[0],6*coef[1],2*coef[2]); - - double t1=0,t2=0; - double ss=100; - - if( inside ){ - if(boolean) guide_elliptical_newtonRapsonsMethod4thOrder(coef,&t1,turningP1,tol,max_iter); - guide_elliptical_newtonRapsonsMethod4thOrder(coef,&t2,limit,tol,max_iter); - } - else{ - if(boolean) guide_elliptical_newtonRapsonsMethod4thOrder(coef,&t1,turningP2,tol,max_iter); - guide_elliptical_newtonRapsonsMethod4thOrder(coef,&t2,startPosition,tol,max_iter); - } - - if (ss > t1 && t1 > 1e-15) ss = t1; - if (ss > t2 && t2 > 1e-15) ss = t2; - *solution = ss; - - return 1; -} - -#pragma acc routine seq -int guide_elliptical_handleGuideIntersection( - double x, double y, double z, - double vx,double vy,double vz, - double Gx,double Gy,double Gz, - struct SGI *guideInfo, - struct Intersection *currentCollision){ - // - double horExS = 1/( guideInfo->ellipseMinorAxis[RightSide] - *guideInfo->ellipseMinorAxis[RightSide]); - double horEzS = 1/( guideInfo->ellipseMajorAxis[RightSide] - *guideInfo->ellipseMajorAxis[RightSide]); - double hordiffx = x-guideInfo->ellipseMinorOffset[RightSide]; - double hordiffz = z-guideInfo->ellipseMajorOffset[RightSide]; - - double horAlpha = ( Gx*Gx*horExS + Gz*Gz*horEzS )/4; - double horBeta = ( Gx*vx*horExS + Gz*vz*horEzS ); - double horGamma = horExS*vx*vx + horEzS*vz*vz - + horExS*Gx*hordiffx + horEzS*Gz*hordiffz; - double horDelta = 2*horExS*vx*hordiffx + 2*horEzS*vz*hordiffz; - double horEpsilon = horExS*hordiffx*hordiffx + horEzS*hordiffz*hordiffz - 1; - - double horCoefficients[5] = {horAlpha,horBeta,horGamma,horDelta,horEpsilon}; - - double verEyS = 1/( guideInfo->ellipseMinorAxis[TopSide] - *guideInfo->ellipseMinorAxis[TopSide]); - double verEzS = 1/( guideInfo->ellipseMajorAxis[TopSide] - *guideInfo->ellipseMajorAxis[TopSide]); - double verdiffy = y-guideInfo->ellipseMinorOffset[TopSide]; - double verdiffz = z-guideInfo->ellipseMajorOffset[TopSide]; - - double verAlpha = ( Gy*Gy*verEyS + Gz*Gz*verEzS )/4; - double verBeta = ( Gy*vy*verEyS + Gz*vz*verEzS ); - double verGamma = verEyS*vy*vy + verEzS*vz*vz - + verEyS*Gy*verdiffy + verEzS*Gz*verdiffz; - double verDelta = 2*verEyS*vy*verdiffy + 2*verEzS*vz*verdiffz; - double verEpsilon = verEyS*verdiffy*verdiffy + verEzS*verdiffz*verdiffz - 1; - - double verCoefficients[5] = {verAlpha,verBeta,verGamma,verDelta,verEpsilon}; - - - double upperlimit; - double startingPoint = 1e-15; - - int boolean=-1; - // Horizontal - double solutionH = 0; - solve_2nd_order( - &upperlimit,NULL, - -0.5*Gz,-vz,2*guideInfo->ellipseMajorAxis[RightSide]-z); - int booleanH = guide_elliptical_findNeutronEllipseIntersection( - horCoefficients,startingPoint,upperlimit,&solutionH); - // Vertical - double solutionV = 0; - solve_2nd_order( - &upperlimit,NULL, - -0.5*Gz,-vz,2*guideInfo->ellipseMajorAxis[TopSide]-z); - int booleanV = guide_elliptical_findNeutronEllipseIntersection( - verCoefficients,startingPoint,upperlimit,&solutionV); - - if (solutionH <= 0) - currentCollision->delta_time_to_next_collision = solutionV; - else if (solutionV <= 0) - currentCollision->delta_time_to_next_collision = solutionH; - else if (fabs(solutionH - solutionV) < 1e-12) return 0; - else if (solutionH < solutionV){ - currentCollision->delta_time_to_next_collision = solutionH; - boolean = booleanH; - } - else{ - currentCollision->delta_time_to_next_collision = solutionV; - boolean = booleanV; - } - - double tside = currentCollision->delta_time_to_next_collision; - double xside = x + vx*tside + 0.5*Gx*tside*tside; - double yside = y + vy*tside + 0.5*Gy*tside*tside; - double zside = z + vz*tside + 0.5*Gz*tside*tside; - - double xfactor = - 2*sqrt(1 - ( (zside-guideInfo->ellipseMajorOffset[RightSide]) - *(zside-guideInfo->ellipseMajorOffset[RightSide]) - )/(guideInfo->ellipseMajorAxis[RightSide] - *guideInfo->ellipseMajorAxis[RightSide] ) - )*guideInfo->ellipseMinorAxis[RightSide]; - - double yfactor = - 2*sqrt(1 - ( (zside-guideInfo->ellipseMajorOffset[BottomSide]) - *(zside-guideInfo->ellipseMajorOffset[BottomSide]) - )/(guideInfo->ellipseMajorAxis[BottomSide] - *guideInfo->ellipseMajorAxis[BottomSide] ) - )*guideInfo->ellipseMinorAxis[BottomSide]; - - xside = xside/xfactor; - yside = yside/yfactor; - if( fabs(yside) >= fabs(xside) ){ - if(y > 0) currentCollision->side = TopSide; - else currentCollision->side = BottomSide; - } - else{ - if(x < 0) currentCollision->side = RightSide; - else currentCollision->side = LeftSide; - } - if (tside < 1e-15) printf("low time is: %e\n",tside); - - return boolean; -} - -/////////////////////////////////////////////////////////////////////////// -/////////////// reflection functions -/////////////////////////////////////////////////////////////////////////// + double tol = 1e-15; + double max_iter = 1e3; + double turningP1, turningP2; + + double sp = startPosition; + int inside; + if (coef[0] * sp * sp * sp * sp + coef[1] * sp * sp * sp + coef[2] * sp * sp + coef[3] * sp + coef[4] < 0) + inside = 1; + else + inside = 0; + + int boolean = solve_2nd_order (&turningP1, &turningP2, 12 * coef[0], 6 * coef[1], 2 * coef[2]); + + double t1 = 0, t2 = 0; + double ss = 100; + + if (inside) { + if (boolean) + guide_elliptical_newtonRapsonsMethod4thOrder (coef, &t1, turningP1, tol, max_iter); + guide_elliptical_newtonRapsonsMethod4thOrder (coef, &t2, limit, tol, max_iter); + } else { + if (boolean) + guide_elliptical_newtonRapsonsMethod4thOrder (coef, &t1, turningP2, tol, max_iter); + guide_elliptical_newtonRapsonsMethod4thOrder (coef, &t2, startPosition, tol, max_iter); + } + if (ss > t1 && t1 > 1e-15) + ss = t1; + if (ss > t2 && t2 > 1e-15) + ss = t2; + *solution = ss; -/** - Calculate the new velocity vector for the particle colliding on - the inner side of the elliptic mirror and returns the loss-factor (TODO) - - @param pos_V0,pos_W0 Is the 2d position vector of the particle, - assumed to be a point on the ellipse. [m] - @param pvel_V0,pvel_W0 Is the 2d velocity vector of the particle. [m/s] - @param ellipse_V_axis_squared,ellipse_W_axis_squared - are the axes of the ellipse. [m] - @param ellipse_V_offset,ellipse_W_offset Is the 2d vector difference - between the ellipse coordinate system (center of the ellipse) - and the guide coordinate system [m] - @param R0, Mvalue, Qc, W, Alpha #TODO - slaa beskrivelse af disse variabler i andre dokumenter - og hold dig til standarden. - @return the new wieght of the package -*/ -#pragma acc routine seq -double guide_elliptical_ReflectionOnEllipticSurface( - double pos_V,double pos_W, - double *pvel_V,double *pvel_W, - double ellipse_V_axis,double ellipse_W_axis, - double ellipse_V_offset,double ellipse_W_offset, - double R0, double Qc, double alpha, double Mvalue, double W) -{ - - // Turns the velocity vector (vel_V0,vel_W0) into a local value - double vel_V = *pvel_V; - double vel_W = *pvel_W; - - // Galilean transformation of the particles start position - // to the ellipse coordinate system - pos_V=pos_V-ellipse_V_offset; - pos_W=pos_W-ellipse_W_offset; - - /* - * If we reflect the velocity vector in the normal - * to the ellipse in the point of intersection - * The resulting vector will be -f2, do to conservation of momentum. - * this result in the following equation - * f2 = -f1 + 2(f1 dot nhat)nhat - * which is equal to f2 = f1 - 2(f1 dot n)n/nlength^2 - */ - - // The normal vector to the point of intersection - double normVec_V = - pos_W*ellipse_V_axis/ellipse_W_axis; - double normVec_W = pos_V*ellipse_W_axis/ellipse_V_axis; - - double normVec_length_squared = normVec_V*normVec_V + normVec_W*normVec_W; - - // Dot product of (vel_V0,vel_W0) and the normal vector - double Vel_dot_NV = vel_V*normVec_V+vel_W*normVec_W; - - // Calculate f2 - double vel_V_2 = -vel_V + 2*Vel_dot_NV*normVec_V/normVec_length_squared; - double vel_W_2 = -vel_W + 2*Vel_dot_NV*normVec_W/normVec_length_squared; - - // Apply the new velocity vector to the particle globally - *pvel_V=vel_V_2; - *pvel_W=vel_W_2; - - // Calculate q and the weighting of the neutron package - // q=f1-f2 - double delta_vel_V = vel_V-vel_V_2; - double delta_vel_W = vel_W-vel_W_2; - double q = V2Q*sqrt( delta_vel_V*delta_vel_V+delta_vel_W*delta_vel_W ); - - // Calculate the loss of neutrons due to the reflection - double mirrorPar[] = {R0, Qc, alpha, Mvalue, W}; - double weight = 1.0; - StdReflecFunc(q, mirrorPar, &weight); - - return weight; -} + return 1; + } -/** - Use the found side of Intersection to call guide_elliptical_ReflectionOnEllipticSurface with - the parameters of that side. -*/ -#pragma acc routine seq -double guide_elliptical_handleReflection(double x0, double y0, double z0, - double *vx_p,double *vy_p,double *vz_p, - struct SGI *sgi, - struct Intersection *cc) -{ - - if(!sgi->enableSegments){ - if(cc->side == RightSide || cc->side == LeftSide) - return guide_elliptical_ReflectionOnEllipticSurface(x0,z0,vx_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mArr[cc->side], - sgi->WArr[cc->side] - ); - if(cc->side == TopSide || cc->side == BottomSide) - return guide_elliptical_ReflectionOnEllipticSurface(y0,z0,vy_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mArr[cc->side], - sgi->WArr[cc->side] - ); + #pragma acc routine seq + int + guide_elliptical_handleGuideIntersection (double x, double y, double z, double vx, double vy, double vz, double Gx, double Gy, double Gz, struct SGI* guideInfo, + struct Intersection* currentCollision) { + // + double horExS = 1 / (guideInfo->ellipseMinorAxis[RightSide] * guideInfo->ellipseMinorAxis[RightSide]); + double horEzS = 1 / (guideInfo->ellipseMajorAxis[RightSide] * guideInfo->ellipseMajorAxis[RightSide]); + double hordiffx = x - guideInfo->ellipseMinorOffset[RightSide]; + double hordiffz = z - guideInfo->ellipseMajorOffset[RightSide]; + + double horAlpha = (Gx * Gx * horExS + Gz * Gz * horEzS) / 4; + double horBeta = (Gx * vx * horExS + Gz * vz * horEzS); + double horGamma = horExS * vx * vx + horEzS * vz * vz + horExS * Gx * hordiffx + horEzS * Gz * hordiffz; + double horDelta = 2 * horExS * vx * hordiffx + 2 * horEzS * vz * hordiffz; + double horEpsilon = horExS * hordiffx * hordiffx + horEzS * hordiffz * hordiffz - 1; + + double horCoefficients[5] = { horAlpha, horBeta, horGamma, horDelta, horEpsilon }; + + double verEyS = 1 / (guideInfo->ellipseMinorAxis[TopSide] * guideInfo->ellipseMinorAxis[TopSide]); + double verEzS = 1 / (guideInfo->ellipseMajorAxis[TopSide] * guideInfo->ellipseMajorAxis[TopSide]); + double verdiffy = y - guideInfo->ellipseMinorOffset[TopSide]; + double verdiffz = z - guideInfo->ellipseMajorOffset[TopSide]; + + double verAlpha = (Gy * Gy * verEyS + Gz * Gz * verEzS) / 4; + double verBeta = (Gy * vy * verEyS + Gz * vz * verEzS); + double verGamma = verEyS * vy * vy + verEzS * vz * vz + verEyS * Gy * verdiffy + verEzS * Gz * verdiffz; + double verDelta = 2 * verEyS * vy * verdiffy + 2 * verEzS * vz * verdiffz; + double verEpsilon = verEyS * verdiffy * verdiffy + verEzS * verdiffz * verdiffz - 1; + + double verCoefficients[5] = { verAlpha, verBeta, verGamma, verDelta, verEpsilon }; + + double upperlimit; + double startingPoint = 1e-15; + + int boolean = -1; + // Horizontal + double solutionH = 0; + solve_2nd_order (&upperlimit, NULL, -0.5 * Gz, -vz, 2 * guideInfo->ellipseMajorAxis[RightSide] - z); + int booleanH = guide_elliptical_findNeutronEllipseIntersection (horCoefficients, startingPoint, upperlimit, &solutionH); + // Vertical + double solutionV = 0; + solve_2nd_order (&upperlimit, NULL, -0.5 * Gz, -vz, 2 * guideInfo->ellipseMajorAxis[TopSide] - z); + int booleanV = guide_elliptical_findNeutronEllipseIntersection (verCoefficients, startingPoint, upperlimit, &solutionV); + + if (solutionH <= 0) + currentCollision->delta_time_to_next_collision = solutionV; + else if (solutionV <= 0) + currentCollision->delta_time_to_next_collision = solutionH; + else if (fabs (solutionH - solutionV) < 1e-12) + return 0; + else if (solutionH < solutionV) { + currentCollision->delta_time_to_next_collision = solutionH; + boolean = booleanH; + } else { + currentCollision->delta_time_to_next_collision = solutionV; + boolean = booleanV; } - else{ - int currentSegment = -1; - double combinedLength = 0; - int i; - for(i=0; i < sgi->numberOfSegments; i++){ - combinedLength = combinedLength + sgi->segLength[i]; - if(z0 < combinedLength) { - currentSegment = i; break; - } - } - if (currentSegment < 0) { - printf("Elliptic_guide_gravity: Error indexing guide segment\n"); - return 0; - } - - if(cc->side == RightSide) - return guide_elliptical_ReflectionOnEllipticSurface(x0,z0,vx_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mValuesright[currentSegment], - sgi->WArr[cc->side] ); - if(cc->side == LeftSide) - return guide_elliptical_ReflectionOnEllipticSurface(x0,z0,vx_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mValuesleft[currentSegment], - sgi->WArr[cc->side] ); - if(cc->side == TopSide) - return guide_elliptical_ReflectionOnEllipticSurface(y0,z0,vy_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mValuestop[currentSegment], - sgi->WArr[cc->side] ); - if(cc->side == BottomSide) - return guide_elliptical_ReflectionOnEllipticSurface(y0,z0,vy_p,vz_p, - sgi->ellipseMinorAxis[cc->side], - sgi->ellipseMajorAxis[cc->side], - sgi->ellipseMinorOffset[cc->side], - sgi->ellipseMajorOffset[cc->side], - sgi->R0Arr[cc->side], - sgi->QcArr[cc->side], - sgi->alphaArr[cc->side], - sgi->mValuesbottom[currentSegment], - sgi->WArr[cc->side] ); + + double tside = currentCollision->delta_time_to_next_collision; + double xside = x + vx * tside + 0.5 * Gx * tside * tside; + double yside = y + vy * tside + 0.5 * Gy * tside * tside; + double zside = z + vz * tside + 0.5 * Gz * tside * tside; + + double xfactor = 2 + * sqrt (1 + - ((zside - guideInfo->ellipseMajorOffset[RightSide]) * (zside - guideInfo->ellipseMajorOffset[RightSide])) + / (guideInfo->ellipseMajorAxis[RightSide] * guideInfo->ellipseMajorAxis[RightSide])) + * guideInfo->ellipseMinorAxis[RightSide]; + + double yfactor = 2 + * sqrt (1 + - ((zside - guideInfo->ellipseMajorOffset[BottomSide]) * (zside - guideInfo->ellipseMajorOffset[BottomSide])) + / (guideInfo->ellipseMajorAxis[BottomSide] * guideInfo->ellipseMajorAxis[BottomSide])) + * guideInfo->ellipseMinorAxis[BottomSide]; + + xside = xside / xfactor; + yside = yside / yfactor; + if (fabs (yside) >= fabs (xside)) { + if (y > 0) + currentCollision->side = TopSide; + else + currentCollision->side = BottomSide; + } else { + if (x < 0) + currentCollision->side = RightSide; + else + currentCollision->side = LeftSide; + } + if (tside < 1e-15) + printf ("low time is: %e\n", tside); + + return boolean; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////// reflection functions + /////////////////////////////////////////////////////////////////////////// + + /** + Calculate the new velocity vector for the particle colliding on + the inner side of the elliptic mirror and returns the loss-factor (TODO) + + @param pos_V0,pos_W0 Is the 2d position vector of the particle, + assumed to be a point on the ellipse. [m] + @param pvel_V0,pvel_W0 Is the 2d velocity vector of the particle. [m/s] + @param ellipse_V_axis_squared,ellipse_W_axis_squared + are the axes of the ellipse. [m] + @param ellipse_V_offset,ellipse_W_offset Is the 2d vector difference + between the ellipse coordinate system (center of the ellipse) + and the guide coordinate system [m] + @param R0, Mvalue, Qc, W, Alpha #TODO + slaa beskrivelse af disse variabler i andre dokumenter + og hold dig til standarden. + @return the new wieght of the package + */ + #pragma acc routine seq + double + guide_elliptical_ReflectionOnEllipticSurface (double pos_V, double pos_W, double* pvel_V, double* pvel_W, double ellipse_V_axis, double ellipse_W_axis, + double ellipse_V_offset, double ellipse_W_offset, double R0, double Qc, double alpha, double Mvalue, double W) { + + // Turns the velocity vector (vel_V0,vel_W0) into a local value + double vel_V = *pvel_V; + double vel_W = *pvel_W; + + // Galilean transformation of the particles start position + // to the ellipse coordinate system + pos_V = pos_V - ellipse_V_offset; + pos_W = pos_W - ellipse_W_offset; + + /* + * If we reflect the velocity vector in the normal + * to the ellipse in the point of intersection + * The resulting vector will be -f2, do to conservation of momentum. + * this result in the following equation + * f2 = -f1 + 2(f1 dot nhat)nhat + * which is equal to f2 = f1 - 2(f1 dot n)n/nlength^2 + */ + + // The normal vector to the point of intersection + double normVec_V = -pos_W * ellipse_V_axis / ellipse_W_axis; + double normVec_W = pos_V * ellipse_W_axis / ellipse_V_axis; + + double normVec_length_squared = normVec_V * normVec_V + normVec_W * normVec_W; + + // Dot product of (vel_V0,vel_W0) and the normal vector + double Vel_dot_NV = vel_V * normVec_V + vel_W * normVec_W; + + // Calculate f2 + double vel_V_2 = -vel_V + 2 * Vel_dot_NV * normVec_V / normVec_length_squared; + double vel_W_2 = -vel_W + 2 * Vel_dot_NV * normVec_W / normVec_length_squared; + + // Apply the new velocity vector to the particle globally + *pvel_V = vel_V_2; + *pvel_W = vel_W_2; + + // Calculate q and the weighting of the neutron package + // q=f1-f2 + double delta_vel_V = vel_V - vel_V_2; + double delta_vel_W = vel_W - vel_W_2; + double q = V2Q * sqrt (delta_vel_V * delta_vel_V + delta_vel_W * delta_vel_W); + + // Calculate the loss of neutrons due to the reflection + double mirrorPar[] = { R0, Qc, alpha, Mvalue, W }; + double weight = 1.0; + StdReflecFunc (q, mirrorPar, &weight); + + return weight; + } + + /** + Use the found side of Intersection to call guide_elliptical_ReflectionOnEllipticSurface with + the parameters of that side. + */ + #pragma acc routine seq + double + guide_elliptical_handleReflection (double x0, double y0, double z0, double* vx_p, double* vy_p, double* vz_p, struct SGI* sgi, struct Intersection* cc) { + + if (!sgi->enableSegments) { + if (cc->side == RightSide || cc->side == LeftSide) + return guide_elliptical_ReflectionOnEllipticSurface (x0, z0, vx_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mArr[cc->side], sgi->WArr[cc->side]); + if (cc->side == TopSide || cc->side == BottomSide) + return guide_elliptical_ReflectionOnEllipticSurface (y0, z0, vy_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mArr[cc->side], sgi->WArr[cc->side]); + } else { + int currentSegment = -1; + double combinedLength = 0; + int i; + for (i = 0; i < sgi->numberOfSegments; i++) { + combinedLength = combinedLength + sgi->segLength[i]; + if (z0 < combinedLength) { + currentSegment = i; + break; + } + } + if (currentSegment < 0) { + printf ("Elliptic_guide_gravity: Error indexing guide segment\n"); + return 0; + } + + if (cc->side == RightSide) + return guide_elliptical_ReflectionOnEllipticSurface (x0, z0, vx_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mValuesright[currentSegment], + sgi->WArr[cc->side]); + if (cc->side == LeftSide) + return guide_elliptical_ReflectionOnEllipticSurface (x0, z0, vx_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mValuesleft[currentSegment], + sgi->WArr[cc->side]); + if (cc->side == TopSide) + return guide_elliptical_ReflectionOnEllipticSurface (y0, z0, vy_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mValuestop[currentSegment], sgi->WArr[cc->side]); + if (cc->side == BottomSide) + return guide_elliptical_ReflectionOnEllipticSurface (y0, z0, vy_p, vz_p, sgi->ellipseMinorAxis[cc->side], sgi->ellipseMajorAxis[cc->side], + sgi->ellipseMinorOffset[cc->side], sgi->ellipseMajorOffset[cc->side], sgi->R0Arr[cc->side], + sgi->QcArr[cc->side], sgi->alphaArr[cc->side], sgi->mValuesbottom[currentSegment], + sgi->WArr[cc->side]); } - return 0; -} + return 0; + } -/////////////////////////////////////////////////////////////////////////// -/////////////// End of functions -/////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + /////////////// End of functions + /////////////////////////////////////////////////////////////////////////// %} DECLARE %{ - /** - All variables below is locally declared - and hence accessible through OUTPUT PARAMETERS. - */ - struct SGI guideInfo; // Static Guide information is set in INITIALIZE - - double Gx0; // Local gravity vector, is set once in INITIALIZE - double Gy0; - double Gz0; - double Circ; - double *dynamicalSegLength; - + /** + All variables below is locally declared + and hence accessible through OUTPUT PARAMETERS. + */ + struct SGI guideInfo; // Static Guide information is set in INITIALIZE + + double Gx0; // Local gravity vector, is set once in INITIALIZE + double Gy0; + double Gz0; + double Circ; + double* dynamicalSegLength; %} INITIALIZE %{ - /////////////////////////////////////////////////////////////////////////// - /////////////// Test user input - /////////////////////////////////////////////////////////////////////////// - - if(strcmp(verbose,"on") == 0) - guideInfo.verboseSetting = 1; - else guideInfo.verboseSetting = 0; - - - guideInfo.R0Arr[RightSide] = R0; - guideInfo.QcArr[RightSide] = Qc; - guideInfo.alphaArr[RightSide] = alpharight; - guideInfo.mArr[RightSide] = mright; - guideInfo.WArr[RightSide] = W; - - guideInfo.R0Arr[TopSide] = R0; - guideInfo.QcArr[TopSide] = Qc; - guideInfo.alphaArr[TopSide] = alphatop; - guideInfo.mArr[TopSide] = mtop; - guideInfo.WArr[TopSide] = W; - - guideInfo.R0Arr[LeftSide] = R0; - guideInfo.QcArr[LeftSide] = Qc; - guideInfo.alphaArr[LeftSide] = alphaleft; - guideInfo.mArr[LeftSide] = mleft; - guideInfo.WArr[LeftSide] = W; - - guideInfo.R0Arr[BottomSide] = R0; - guideInfo.QcArr[BottomSide] = Qc; - guideInfo.alphaArr[BottomSide] = alphabottom; - guideInfo.mArr[BottomSide] = mbottom; - guideInfo.WArr[BottomSide] = W; - - int sides; - for (sides = RightSide; sides <= BottomSide; sides++){ - if (guideInfo.alphaArr[sides] == -1) guideInfo.alphaArr[sides] = alpha; - if (guideInfo.mArr[sides] == -1) guideInfo.mArr[sides] = m; - } - - // Test user input for illegal values - int inputErrors = 0; - // Lower or equal to zero - if(l <= 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("length",guideInfo.verboseSetting); - if(guideInfo.alphaArr[TopSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("alphatop",guideInfo.verboseSetting); - if(guideInfo.mArr[TopSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("mtop",guideInfo.verboseSetting); - - if(guideInfo.alphaArr[BottomSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("alphabottom",guideInfo.verboseSetting); - if(guideInfo.mArr[BottomSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("mbottom",guideInfo.verboseSetting); - - if(guideInfo.alphaArr[RightSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("alpharight",guideInfo.verboseSetting); - if(guideInfo.mArr[RightSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("mright",guideInfo.verboseSetting); - - if(guideInfo.alphaArr[LeftSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("alphaleft",guideInfo.verboseSetting); - if(guideInfo.mArr[LeftSide] < 0) inputErrors += - guide_elliptical_illegalInputLessThanZero("mleft",guideInfo.verboseSetting); - - // Focal points result in hyperbola instead of an ellipse - if(l <= -linxw-loutxw) inputErrors += guide_elliptical_illegalInputFocalPointsHyperbola( - "linw","loutw",linxw,loutxw,guideInfo.verboseSetting); - if(l <= -linyh-loutyh) inputErrors += guide_elliptical_illegalInputFocalPointsHyperbola( - "linh","louth",linyh,loutyh,guideInfo.verboseSetting); - - if( strcmp(dimensionsAt,"entrance") != 0 - && strcmp(dimensionsAt,"mid") != 0 - && strcmp(dimensionsAt,"exit") != 0){ - inputErrors += 1; - printf("dimensionsAt were given an incorrect input." - "Input must be string containing \"entrance\",\"mid\" or \"exit\" \n"); - } - - - // Terminate program if any input errors occurred - if(inputErrors != 0 ){ - exit(printf("\nCRITICAL ERROR(S) IN COMPONENT %s" - " CONSIDER CHECKING USER INPUT AS %d INPUT ERRORS WAS FOUND.\n", - NAME_CURRENT_COMP,inputErrors) ); - } - - - /////////////////////////////////////////////////////////////////////////// - /////////////// Calculate intern guide values from user input - /////////////////////////////////////////////////////////////////////////// - - /* Calculate the foci line for the ellipses. - These can be used to calculate the axes of the ellipses - using pyth and defination of the ellipse that says distance - between the foci and every point on the ellipse is constant. - */ - int directDefination = 0; - - if( majorAxisyh != 0 || minorAxisyh != 0 - || majorAxisxw != 0 || minorAxisxw != 0) - { - directDefination = 1; - guideInfo.Length = l; - - guideInfo.ellipseMajorAxis[RightSide] = majorAxisxw; - guideInfo.ellipseMinorAxis[RightSide] = minorAxisxw; - guideInfo.ellipseMajorOffset[RightSide] = majorAxisoffsetxw; - guideInfo.ellipseMinorOffset[RightSide] = 0; - - guideInfo.ellipseMajorAxis[TopSide] = majorAxisyh; - guideInfo.ellipseMinorAxis[TopSide] = minorAxisyh; - guideInfo.ellipseMajorOffset[TopSide] = majorAxisoffsetyh; - guideInfo.ellipseMinorOffset[TopSide] = 0; - - guideInfo.ellipseMajorAxis[LeftSide] = majorAxisxw; - guideInfo.ellipseMinorAxis[LeftSide] = minorAxisxw; - guideInfo.ellipseMajorOffset[LeftSide] = majorAxisoffsetxw; - guideInfo.ellipseMinorOffset[LeftSide] = 0; - - guideInfo.ellipseMajorAxis[BottomSide] = majorAxisyh; - guideInfo.ellipseMinorAxis[BottomSide] = minorAxisyh; - guideInfo.ellipseMajorOffset[BottomSide] = majorAxisoffsetyh; - guideInfo.ellipseMinorOffset[BottomSide] = 0; - - guideInfo.entranceHorizontalWidth = - 2*sqrt(1 - (majorAxisoffsetyh*majorAxisoffsetyh) - /(majorAxisyh*majorAxisyh) )*minorAxisyh; - guideInfo.entranceVerticalWidth = - 2*sqrt(1 - (majorAxisoffsetxw*majorAxisoffsetxw) - /(majorAxisxw*majorAxisxw) )*minorAxisxw; - } - - if ( strcmp(option,"ellipse") == 0 && directDefination == 0) - { - if ( strcmp(dimensionsAt,"entrance") == 0 ){ - double lofbs_horizontal = - sqrt( linxw*linxw + xwidth*xwidth*0.25) - + sqrt( (l + loutxw)*(l + loutxw) + xwidth*xwidth*0.25); - - double lofbs_vertical = - sqrt( linyh*linyh + yheight*yheight*0.25) - + sqrt( (l + loutyh)*(l + loutyh) + yheight*yheight*0.25); - - guideInfo.Length = l; - - guideInfo.ellipseMajorAxis[RightSide] = lofbs_horizontal/2; - guideInfo.ellipseMinorAxis[RightSide] = - sqrt(0.25*lofbs_horizontal*lofbs_horizontal - -0.25*(l+linxw+loutxw)*(l+linxw+loutxw) ); - - guideInfo.ellipseMajorOffset[RightSide] = (l+linxw+loutxw)/2-linxw; - guideInfo.ellipseMinorOffset[RightSide] = 0; - - guideInfo.ellipseMajorAxis[LeftSide] = - guideInfo.ellipseMajorAxis[RightSide]; - guideInfo.ellipseMinorAxis[LeftSide] = - guideInfo.ellipseMinorAxis[RightSide]; - guideInfo.ellipseMajorOffset[LeftSide] = - guideInfo.ellipseMajorOffset[RightSide]; - guideInfo.ellipseMinorOffset[LeftSide] = - guideInfo.ellipseMinorOffset[RightSide]; - - guideInfo.ellipseMajorAxis[TopSide] = lofbs_vertical/2; - - guideInfo.ellipseMinorAxis[TopSide] = - sqrt(0.25*lofbs_vertical*lofbs_vertical - -0.25*(l+linyh+loutyh)*(l+linyh+loutyh) ); - - guideInfo.ellipseMajorOffset[TopSide] = (l+linyh+loutyh)/2-linyh; - guideInfo.ellipseMinorOffset[TopSide] = 0; - - guideInfo.ellipseMajorAxis[BottomSide] = - guideInfo.ellipseMajorAxis[TopSide]; - guideInfo.ellipseMinorAxis[BottomSide] = - guideInfo.ellipseMinorAxis[TopSide]; - guideInfo.ellipseMajorOffset[BottomSide] = - guideInfo.ellipseMajorOffset[TopSide]; - guideInfo.ellipseMinorOffset[BottomSide] = - guideInfo.ellipseMinorOffset[TopSide]; - } - if ( strcmp(dimensionsAt,"exit") == 0 ){ - double lofbs_horizontal = - sqrt( loutxw*loutxw + xwidth*xwidth*0.25) - + sqrt( (l + linxw)*(l + linxw) + xwidth*xwidth*0.25); - - double lofbs_vertical = - sqrt( loutyh*loutyh + yheight*yheight*0.25) - + sqrt( (l + linyh)*(l + linyh) + yheight*yheight*0.25); - - guideInfo.Length = l; - - guideInfo.ellipseMajorAxis[RightSide] = lofbs_horizontal/2; - guideInfo.ellipseMinorAxis[RightSide] = - sqrt(0.25*lofbs_horizontal*lofbs_horizontal - -0.25*(l+linxw+loutxw)*(l+linxw+loutxw) ); - - guideInfo.ellipseMajorOffset[RightSide] =(l+linxw+loutxw)/2-linxw; - guideInfo.ellipseMinorOffset[RightSide] = 0; - - guideInfo.ellipseMajorAxis[LeftSide] = - guideInfo.ellipseMajorAxis[RightSide]; - guideInfo.ellipseMinorAxis[LeftSide] = - guideInfo.ellipseMinorAxis[RightSide]; - guideInfo.ellipseMajorOffset[LeftSide] = - guideInfo.ellipseMajorOffset[RightSide]; - guideInfo.ellipseMinorOffset[LeftSide] = - guideInfo.ellipseMinorOffset[RightSide]; - - guideInfo.ellipseMajorAxis[TopSide] = lofbs_vertical/2; - - guideInfo.ellipseMinorAxis[TopSide] = - sqrt(0.25*lofbs_vertical*lofbs_vertical - -0.25*(l+linyh+loutyh)*(l+linyh+loutyh) ); - - guideInfo.ellipseMajorOffset[TopSide] = (l+linyh+loutyh)/2-linyh; - guideInfo.ellipseMinorOffset[TopSide] = 0; - - guideInfo.ellipseMajorAxis[BottomSide] = - guideInfo.ellipseMajorAxis[TopSide]; - guideInfo.ellipseMinorAxis[BottomSide] = - guideInfo.ellipseMinorAxis[TopSide]; - guideInfo.ellipseMajorOffset[BottomSide] = - guideInfo.ellipseMajorOffset[TopSide]; - guideInfo.ellipseMinorOffset[BottomSide] = - guideInfo.ellipseMinorOffset[TopSide]; - } - if ( strcmp(dimensionsAt,"mid") == 0 ){ - - guideInfo.Length = l; - - guideInfo.ellipseMajorAxis[RightSide] = - sqrt( (linxw+l+loutxw)*(linxw+l+loutxw)/4+xwidth*xwidth/4); - guideInfo.ellipseMinorAxis[RightSide] = xwidth/2; - - guideInfo.ellipseMajorOffset[RightSide] = (l+linxw+loutxw)/2-linxw; - guideInfo.ellipseMinorOffset[RightSide] = 0; - - guideInfo.ellipseMajorAxis[LeftSide] = - guideInfo.ellipseMajorAxis[RightSide]; - guideInfo.ellipseMinorAxis[LeftSide] = - guideInfo.ellipseMinorAxis[RightSide]; - guideInfo.ellipseMajorOffset[LeftSide] = - guideInfo.ellipseMajorOffset[RightSide]; - guideInfo.ellipseMinorOffset[LeftSide] = - guideInfo.ellipseMinorOffset[RightSide]; - - guideInfo.ellipseMajorAxis[TopSide] = - sqrt( (linyh+l+loutyh)*(linyh+l+loutyh)/4+yheight*yheight/4); - guideInfo.ellipseMinorAxis[TopSide] = yheight/2; - - guideInfo.ellipseMajorOffset[TopSide] = (l+linyh+loutyh)/2-linyh; - guideInfo.ellipseMinorOffset[TopSide] = 0; - - guideInfo.ellipseMajorAxis[BottomSide] = - guideInfo.ellipseMajorAxis[TopSide]; - guideInfo.ellipseMinorAxis[BottomSide] = - guideInfo.ellipseMinorAxis[TopSide]; - guideInfo.ellipseMajorOffset[BottomSide] = - guideInfo.ellipseMajorOffset[TopSide]; - guideInfo.ellipseMinorOffset[BottomSide] = - guideInfo.ellipseMinorOffset[TopSide]; - - } - } - - guideInfo.entranceHorizontalWidth = 2*sqrt( - 1 - guideInfo.ellipseMajorOffset[RightSide] - *guideInfo.ellipseMajorOffset[RightSide] - /(guideInfo.ellipseMajorAxis[RightSide] - *guideInfo.ellipseMajorAxis[RightSide] ) ) - *guideInfo.ellipseMinorAxis[RightSide]; - guideInfo.entranceVerticalWidth = 2*sqrt( - 1 - guideInfo.ellipseMajorOffset[TopSide] - *guideInfo.ellipseMajorOffset[TopSide] - /(guideInfo.ellipseMajorAxis[TopSide] - *guideInfo.ellipseMajorAxis[TopSide] ) ) - *guideInfo.ellipseMinorAxis[TopSide]; - - - if ( strcmp(option,"halfellipse") == 0 && directDefination == 0 ){ - exit( printf("Critical error in %s; the option for option = halfellipse is currently disabled.",NAME_CURRENT_COMP) ); - - double used_focal_vertical; - double used_focal_horizontal; - double major_offset_horizontal = 0; - double major_offset_vertical = 0; - - if ( strcmp(dimensionsAt,"entrance") == 0 ){ - used_focal_vertical = sqrt( (yheight*yheight)/4 - + (l+linyh)*(l+linyh) ); - used_focal_horizontal = sqrt( (xwidth*xwidth)/4 - + (l+linxw)*(l+linxw) ); - major_offset_vertical = l; - major_offset_horizontal = l; - } - else { - used_focal_vertical = sqrt( (yheight*yheight)/4 - + (l+loutyh)*(l+loutyh) ); - used_focal_horizontal = sqrt( (xwidth*xwidth)/4 - + (l+loutxw)*(l+loutxw) ); - } - - guideInfo.Length = l; - - guideInfo.ellipseMajorAxis[RightSide] = used_focal_horizontal; - guideInfo.ellipseMinorAxis[RightSide] = xwidth/2; - - guideInfo.ellipseMajorOffset[RightSide] = major_offset_horizontal; - guideInfo.ellipseMinorOffset[RightSide] = 0; - - guideInfo.ellipseMajorAxis[LeftSide] = - guideInfo.ellipseMajorAxis[RightSide]; - guideInfo.ellipseMinorAxis[LeftSide] = - guideInfo.ellipseMinorAxis[RightSide]; - guideInfo.ellipseMajorOffset[LeftSide] = - guideInfo.ellipseMajorOffset[RightSide]; - guideInfo.ellipseMinorOffset[LeftSide] = - guideInfo.ellipseMinorOffset[RightSide]; - - guideInfo.ellipseMajorAxis[TopSide] = used_focal_vertical; - guideInfo.ellipseMinorAxis[TopSide] = yheight/2; - - guideInfo.ellipseMajorOffset[TopSide] = major_offset_vertical; - guideInfo.ellipseMinorOffset[TopSide] = 0; - - guideInfo.ellipseMajorAxis[BottomSide] = - guideInfo.ellipseMajorAxis[TopSide]; - guideInfo.ellipseMinorAxis[BottomSide] = - guideInfo.ellipseMinorAxis[TopSide]; - guideInfo.ellipseMajorOffset[BottomSide] = - guideInfo.ellipseMajorOffset[TopSide]; - guideInfo.ellipseMinorOffset[BottomSide] = - guideInfo.ellipseMinorOffset[TopSide]; - } - - // Applies the properties of the mirrors in the guide given by the user. - // These variables are used in the reflection functions. - - // Give a warning if all side of the guide is turned off, - // as the guide is essentially turned off - if( guideInfo.OuterSide[RightSide] == 1 - && guideInfo.OuterSide[TopSide] == 1 - && guideInfo.OuterSide[LeftSide] == 1 - && guideInfo.OuterSide[BottomSide] == 1 - && guideInfo.InnerSide[RightSide] == 1 - && guideInfo.InnerSide[TopSide] == 1 - && guideInfo.InnerSide[LeftSide] == 1 - && guideInfo.InnerSide[BottomSide] == 1) - printf("Warning: In %s all the sides of the guide has been disabled," - " so it not possible for any particle" - " to collide with the guide, consider" - " disabling this component",NAME_CURRENT_COMP); - - if(guideInfo.mArr[RightSide] <= 0) guideInfo.InnerSide[RightSide] = - MirrorTypeabsorption; - if(guideInfo.mArr[TopSide] <= 0) guideInfo.InnerSide[TopSide] = - MirrorTypeabsorption; - if(guideInfo.mArr[LeftSide] <= 0) guideInfo.InnerSide[LeftSide] = - MirrorTypeabsorption; - if(guideInfo.mArr[BottomSide] <= 0) guideInfo.InnerSide[BottomSide] = - MirrorTypeabsorption; - - if( strcmp(option,"halfellipse") == 0 && directDefination == 0 ){ - guideInfo.entranceHorizontalWidth = - (guideInfo.ellipseMinorAxis[RightSide] - * sqrt(1 - ( guideInfo.ellipseMajorOffset[RightSide] - *guideInfo.ellipseMajorOffset[RightSide] ) - /( guideInfo.ellipseMajorAxis[RightSide] - *guideInfo.ellipseMajorAxis[RightSide] ) ) - + guideInfo.ellipseMinorOffset[RightSide] )*2; - guideInfo.entranceVerticalWidth = - (guideInfo.ellipseMinorAxis[TopSide] - * sqrt(1 - ( guideInfo.ellipseMajorOffset[TopSide] - *guideInfo.ellipseMajorOffset[TopSide] ) - /( guideInfo.ellipseMajorAxis[TopSide] - *guideInfo.ellipseMajorAxis[TopSide] ) ) - + guideInfo.ellipseMinorOffset[TopSide] )*2; - } - - - guideInfo.EnclosingBoxOn = 0; - - guideInfo.exitVerticalWidth = - 2*sqrt(1 - ( (guideInfo.Length-guideInfo.ellipseMajorOffset[BottomSide]) - *(guideInfo.Length-guideInfo.ellipseMajorOffset[BottomSide]) - )/(guideInfo.ellipseMajorAxis[BottomSide] - *guideInfo.ellipseMajorAxis[BottomSide] ) - )*guideInfo.ellipseMinorAxis[BottomSide]; - - guideInfo.exitHorizontalWidth = - 2*sqrt(1 - ( (guideInfo.Length-guideInfo.ellipseMajorOffset[RightSide]) - *(guideInfo.Length-guideInfo.ellipseMajorOffset[RightSide]) - )/(guideInfo.ellipseMajorAxis[RightSide] - *guideInfo.ellipseMajorAxis[RightSide] ) - )*guideInfo.ellipseMinorAxis[RightSide]; - - //////////////////segmentation of m values - - // Are the arrays empty? - if(mvaluesright != NULL || mvaluesleft != NULL - || mvaluestop != NULL || mvaluesbottom != NULL) - { - guideInfo.enableSegments = 1; - - if (nSegments == -1) { - printf("\nError (%s): vector-specifcation of coating used, but nSegments=%i.\n Please give provide nSegments = length of coating segment-arrays!\n", _comp->_name, nSegments); - exit(-1); - } else { - guideInfo.numberOfSegments = (int)nSegments; - } - - //printf("Length is %i\n",guideInfo.numberOfSegments); - guideInfo.mValuesright = mvaluesright; - guideInfo.mValuesleft = mvaluesleft; - guideInfo.mValuestop = mvaluestop; - guideInfo.mValuesbottom = mvaluesbottom; - //printf("Seglength ... %f %f %f\n",seglength[0],seglength[1],seglength[2]); - - // Are the arrays of equal length? - if(seglength == NULL){ - dynamicalSegLength = - realloc(dynamicalSegLength, - guideInfo.numberOfSegments*sizeof(double) ); - int i; - for (i = 0; i < guideInfo.numberOfSegments; ++i){ - dynamicalSegLength[i] = - guideInfo.Length/guideInfo.numberOfSegments; - } - guideInfo.segLength = dynamicalSegLength; - } - else guideInfo.segLength = seglength; - - double sumOfelements=0; - int i; - for(i=0;i< guideInfo.numberOfSegments; i++) { - sumOfelements += guideInfo.segLength[i]; - } - if ( guideInfo.verboseSetting - && fabs(sumOfelements-guideInfo.Length) > 1e-9 ) - printf("Error in userinput inside %s, the difference between" - " guidelength and elements of the seglength array is:" - "%e consider changes the parameters l or seglength \n", - NAME_CURRENT_COMP,sumOfelements-guideInfo.Length); - } - else guideInfo.enableSegments = 0; - - -/////////////////////////////////////////////////////////////////////////// -/////////////// Calculate gravity vector in the guides coordinatesystem -/////////////////////////////////////////////////////////////////////////// - -/* - Sets the local gravity vector equal to the global gravity vector (0,-g,0) - and when apply the same rotation matrix as applied to guide. -*/ - if (enableGravity != 0){ - Gx0=0, Gy0=-GRAVITY*enableGravity, Gz0=0; - Coords mcLocG; - mcLocG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,Gy0,0)); - coords_get(mcLocG, &Gx0, &Gy0, &Gz0); - } - Circ=2*PI*curvature; + /////////////////////////////////////////////////////////////////////////// + /////////////// Test user input + /////////////////////////////////////////////////////////////////////////// + + if (strcmp (verbose, "on") == 0) + guideInfo.verboseSetting = 1; + else + guideInfo.verboseSetting = 0; + + guideInfo.R0Arr[RightSide] = R0; + guideInfo.QcArr[RightSide] = Qc; + guideInfo.alphaArr[RightSide] = alpharight; + guideInfo.mArr[RightSide] = mright; + guideInfo.WArr[RightSide] = W; + + guideInfo.R0Arr[TopSide] = R0; + guideInfo.QcArr[TopSide] = Qc; + guideInfo.alphaArr[TopSide] = alphatop; + guideInfo.mArr[TopSide] = mtop; + guideInfo.WArr[TopSide] = W; + + guideInfo.R0Arr[LeftSide] = R0; + guideInfo.QcArr[LeftSide] = Qc; + guideInfo.alphaArr[LeftSide] = alphaleft; + guideInfo.mArr[LeftSide] = mleft; + guideInfo.WArr[LeftSide] = W; + + guideInfo.R0Arr[BottomSide] = R0; + guideInfo.QcArr[BottomSide] = Qc; + guideInfo.alphaArr[BottomSide] = alphabottom; + guideInfo.mArr[BottomSide] = mbottom; + guideInfo.WArr[BottomSide] = W; + + int sides; + for (sides = RightSide; sides <= BottomSide; sides++) { + if (guideInfo.alphaArr[sides] == -1) + guideInfo.alphaArr[sides] = alpha; + if (guideInfo.mArr[sides] == -1) + guideInfo.mArr[sides] = m; + } + + // Test user input for illegal values + int inputErrors = 0; + // Lower or equal to zero + if (l <= 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("length", guideInfo.verboseSetting); + if (guideInfo.alphaArr[TopSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("alphatop", guideInfo.verboseSetting); + if (guideInfo.mArr[TopSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("mtop", guideInfo.verboseSetting); + + if (guideInfo.alphaArr[BottomSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("alphabottom", guideInfo.verboseSetting); + if (guideInfo.mArr[BottomSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("mbottom", guideInfo.verboseSetting); + + if (guideInfo.alphaArr[RightSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("alpharight", guideInfo.verboseSetting); + if (guideInfo.mArr[RightSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("mright", guideInfo.verboseSetting); + + if (guideInfo.alphaArr[LeftSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("alphaleft", guideInfo.verboseSetting); + if (guideInfo.mArr[LeftSide] < 0) + inputErrors += guide_elliptical_illegalInputLessThanZero ("mleft", guideInfo.verboseSetting); + + // Focal points result in hyperbola instead of an ellipse + if (l <= -linxw - loutxw) + inputErrors += guide_elliptical_illegalInputFocalPointsHyperbola ("linw", "loutw", linxw, loutxw, guideInfo.verboseSetting); + if (l <= -linyh - loutyh) + inputErrors += guide_elliptical_illegalInputFocalPointsHyperbola ("linh", "louth", linyh, loutyh, guideInfo.verboseSetting); + + if (strcmp (dimensionsAt, "entrance") != 0 && strcmp (dimensionsAt, "mid") != 0 && strcmp (dimensionsAt, "exit") != 0) { + inputErrors += 1; + printf ("dimensionsAt were given an incorrect input." + "Input must be string containing \"entrance\",\"mid\" or \"exit\" \n"); + } + + // Terminate program if any input errors occurred + if (inputErrors != 0) { + exit (printf ("\nCRITICAL ERROR(S) IN COMPONENT %s" + " CONSIDER CHECKING USER INPUT AS %d INPUT ERRORS WAS FOUND.\n", + NAME_CURRENT_COMP, inputErrors)); + } + + /////////////////////////////////////////////////////////////////////////// + /////////////// Calculate intern guide values from user input + /////////////////////////////////////////////////////////////////////////// + + /* Calculate the foci line for the ellipses. + These can be used to calculate the axes of the ellipses + using pyth and defination of the ellipse that says distance + between the foci and every point on the ellipse is constant. + */ + int directDefination = 0; + + if (majorAxisyh != 0 || minorAxisyh != 0 || majorAxisxw != 0 || minorAxisxw != 0) { + directDefination = 1; + guideInfo.Length = l; + + guideInfo.ellipseMajorAxis[RightSide] = majorAxisxw; + guideInfo.ellipseMinorAxis[RightSide] = minorAxisxw; + guideInfo.ellipseMajorOffset[RightSide] = majorAxisoffsetxw; + guideInfo.ellipseMinorOffset[RightSide] = 0; + + guideInfo.ellipseMajorAxis[TopSide] = majorAxisyh; + guideInfo.ellipseMinorAxis[TopSide] = minorAxisyh; + guideInfo.ellipseMajorOffset[TopSide] = majorAxisoffsetyh; + guideInfo.ellipseMinorOffset[TopSide] = 0; + + guideInfo.ellipseMajorAxis[LeftSide] = majorAxisxw; + guideInfo.ellipseMinorAxis[LeftSide] = minorAxisxw; + guideInfo.ellipseMajorOffset[LeftSide] = majorAxisoffsetxw; + guideInfo.ellipseMinorOffset[LeftSide] = 0; + + guideInfo.ellipseMajorAxis[BottomSide] = majorAxisyh; + guideInfo.ellipseMinorAxis[BottomSide] = minorAxisyh; + guideInfo.ellipseMajorOffset[BottomSide] = majorAxisoffsetyh; + guideInfo.ellipseMinorOffset[BottomSide] = 0; + + guideInfo.entranceHorizontalWidth = 2 * sqrt (1 - (majorAxisoffsetyh * majorAxisoffsetyh) / (majorAxisyh * majorAxisyh)) * minorAxisyh; + guideInfo.entranceVerticalWidth = 2 * sqrt (1 - (majorAxisoffsetxw * majorAxisoffsetxw) / (majorAxisxw * majorAxisxw)) * minorAxisxw; + } + + if (strcmp (option, "ellipse") == 0 && directDefination == 0) { + if (strcmp (dimensionsAt, "entrance") == 0) { + double lofbs_horizontal = sqrt (linxw * linxw + xwidth * xwidth * 0.25) + sqrt ((l + loutxw) * (l + loutxw) + xwidth * xwidth * 0.25); + + double lofbs_vertical = sqrt (linyh * linyh + yheight * yheight * 0.25) + sqrt ((l + loutyh) * (l + loutyh) + yheight * yheight * 0.25); + + guideInfo.Length = l; + + guideInfo.ellipseMajorAxis[RightSide] = lofbs_horizontal / 2; + guideInfo.ellipseMinorAxis[RightSide] = sqrt (0.25 * lofbs_horizontal * lofbs_horizontal - 0.25 * (l + linxw + loutxw) * (l + linxw + loutxw)); + + guideInfo.ellipseMajorOffset[RightSide] = (l + linxw + loutxw) / 2 - linxw; + guideInfo.ellipseMinorOffset[RightSide] = 0; + + guideInfo.ellipseMajorAxis[LeftSide] = guideInfo.ellipseMajorAxis[RightSide]; + guideInfo.ellipseMinorAxis[LeftSide] = guideInfo.ellipseMinorAxis[RightSide]; + guideInfo.ellipseMajorOffset[LeftSide] = guideInfo.ellipseMajorOffset[RightSide]; + guideInfo.ellipseMinorOffset[LeftSide] = guideInfo.ellipseMinorOffset[RightSide]; + + guideInfo.ellipseMajorAxis[TopSide] = lofbs_vertical / 2; + + guideInfo.ellipseMinorAxis[TopSide] = sqrt (0.25 * lofbs_vertical * lofbs_vertical - 0.25 * (l + linyh + loutyh) * (l + linyh + loutyh)); + + guideInfo.ellipseMajorOffset[TopSide] = (l + linyh + loutyh) / 2 - linyh; + guideInfo.ellipseMinorOffset[TopSide] = 0; + + guideInfo.ellipseMajorAxis[BottomSide] = guideInfo.ellipseMajorAxis[TopSide]; + guideInfo.ellipseMinorAxis[BottomSide] = guideInfo.ellipseMinorAxis[TopSide]; + guideInfo.ellipseMajorOffset[BottomSide] = guideInfo.ellipseMajorOffset[TopSide]; + guideInfo.ellipseMinorOffset[BottomSide] = guideInfo.ellipseMinorOffset[TopSide]; + } + if (strcmp (dimensionsAt, "exit") == 0) { + double lofbs_horizontal = sqrt (loutxw * loutxw + xwidth * xwidth * 0.25) + sqrt ((l + linxw) * (l + linxw) + xwidth * xwidth * 0.25); + + double lofbs_vertical = sqrt (loutyh * loutyh + yheight * yheight * 0.25) + sqrt ((l + linyh) * (l + linyh) + yheight * yheight * 0.25); + + guideInfo.Length = l; + + guideInfo.ellipseMajorAxis[RightSide] = lofbs_horizontal / 2; + guideInfo.ellipseMinorAxis[RightSide] = sqrt (0.25 * lofbs_horizontal * lofbs_horizontal - 0.25 * (l + linxw + loutxw) * (l + linxw + loutxw)); + + guideInfo.ellipseMajorOffset[RightSide] = (l + linxw + loutxw) / 2 - linxw; + guideInfo.ellipseMinorOffset[RightSide] = 0; + + guideInfo.ellipseMajorAxis[LeftSide] = guideInfo.ellipseMajorAxis[RightSide]; + guideInfo.ellipseMinorAxis[LeftSide] = guideInfo.ellipseMinorAxis[RightSide]; + guideInfo.ellipseMajorOffset[LeftSide] = guideInfo.ellipseMajorOffset[RightSide]; + guideInfo.ellipseMinorOffset[LeftSide] = guideInfo.ellipseMinorOffset[RightSide]; + + guideInfo.ellipseMajorAxis[TopSide] = lofbs_vertical / 2; + + guideInfo.ellipseMinorAxis[TopSide] = sqrt (0.25 * lofbs_vertical * lofbs_vertical - 0.25 * (l + linyh + loutyh) * (l + linyh + loutyh)); + + guideInfo.ellipseMajorOffset[TopSide] = (l + linyh + loutyh) / 2 - linyh; + guideInfo.ellipseMinorOffset[TopSide] = 0; + + guideInfo.ellipseMajorAxis[BottomSide] = guideInfo.ellipseMajorAxis[TopSide]; + guideInfo.ellipseMinorAxis[BottomSide] = guideInfo.ellipseMinorAxis[TopSide]; + guideInfo.ellipseMajorOffset[BottomSide] = guideInfo.ellipseMajorOffset[TopSide]; + guideInfo.ellipseMinorOffset[BottomSide] = guideInfo.ellipseMinorOffset[TopSide]; + } + if (strcmp (dimensionsAt, "mid") == 0) { + + guideInfo.Length = l; + + guideInfo.ellipseMajorAxis[RightSide] = sqrt ((linxw + l + loutxw) * (linxw + l + loutxw) / 4 + xwidth * xwidth / 4); + guideInfo.ellipseMinorAxis[RightSide] = xwidth / 2; + + guideInfo.ellipseMajorOffset[RightSide] = (l + linxw + loutxw) / 2 - linxw; + guideInfo.ellipseMinorOffset[RightSide] = 0; + + guideInfo.ellipseMajorAxis[LeftSide] = guideInfo.ellipseMajorAxis[RightSide]; + guideInfo.ellipseMinorAxis[LeftSide] = guideInfo.ellipseMinorAxis[RightSide]; + guideInfo.ellipseMajorOffset[LeftSide] = guideInfo.ellipseMajorOffset[RightSide]; + guideInfo.ellipseMinorOffset[LeftSide] = guideInfo.ellipseMinorOffset[RightSide]; + + guideInfo.ellipseMajorAxis[TopSide] = sqrt ((linyh + l + loutyh) * (linyh + l + loutyh) / 4 + yheight * yheight / 4); + guideInfo.ellipseMinorAxis[TopSide] = yheight / 2; + + guideInfo.ellipseMajorOffset[TopSide] = (l + linyh + loutyh) / 2 - linyh; + guideInfo.ellipseMinorOffset[TopSide] = 0; + + guideInfo.ellipseMajorAxis[BottomSide] = guideInfo.ellipseMajorAxis[TopSide]; + guideInfo.ellipseMinorAxis[BottomSide] = guideInfo.ellipseMinorAxis[TopSide]; + guideInfo.ellipseMajorOffset[BottomSide] = guideInfo.ellipseMajorOffset[TopSide]; + guideInfo.ellipseMinorOffset[BottomSide] = guideInfo.ellipseMinorOffset[TopSide]; + } + } + + guideInfo.entranceHorizontalWidth = 2 + * sqrt (1 + - guideInfo.ellipseMajorOffset[RightSide] * guideInfo.ellipseMajorOffset[RightSide] + / (guideInfo.ellipseMajorAxis[RightSide] * guideInfo.ellipseMajorAxis[RightSide])) + * guideInfo.ellipseMinorAxis[RightSide]; + guideInfo.entranceVerticalWidth = 2 + * sqrt (1 + - guideInfo.ellipseMajorOffset[TopSide] * guideInfo.ellipseMajorOffset[TopSide] + / (guideInfo.ellipseMajorAxis[TopSide] * guideInfo.ellipseMajorAxis[TopSide])) + * guideInfo.ellipseMinorAxis[TopSide]; + + if (strcmp (option, "halfellipse") == 0 && directDefination == 0) { + exit (printf ("Critical error in %s; the option for option = halfellipse is currently disabled.", NAME_CURRENT_COMP)); + + double used_focal_vertical; + double used_focal_horizontal; + double major_offset_horizontal = 0; + double major_offset_vertical = 0; + + if (strcmp (dimensionsAt, "entrance") == 0) { + used_focal_vertical = sqrt ((yheight * yheight) / 4 + (l + linyh) * (l + linyh)); + used_focal_horizontal = sqrt ((xwidth * xwidth) / 4 + (l + linxw) * (l + linxw)); + major_offset_vertical = l; + major_offset_horizontal = l; + } else { + used_focal_vertical = sqrt ((yheight * yheight) / 4 + (l + loutyh) * (l + loutyh)); + used_focal_horizontal = sqrt ((xwidth * xwidth) / 4 + (l + loutxw) * (l + loutxw)); + } + + guideInfo.Length = l; + + guideInfo.ellipseMajorAxis[RightSide] = used_focal_horizontal; + guideInfo.ellipseMinorAxis[RightSide] = xwidth / 2; + + guideInfo.ellipseMajorOffset[RightSide] = major_offset_horizontal; + guideInfo.ellipseMinorOffset[RightSide] = 0; + + guideInfo.ellipseMajorAxis[LeftSide] = guideInfo.ellipseMajorAxis[RightSide]; + guideInfo.ellipseMinorAxis[LeftSide] = guideInfo.ellipseMinorAxis[RightSide]; + guideInfo.ellipseMajorOffset[LeftSide] = guideInfo.ellipseMajorOffset[RightSide]; + guideInfo.ellipseMinorOffset[LeftSide] = guideInfo.ellipseMinorOffset[RightSide]; + + guideInfo.ellipseMajorAxis[TopSide] = used_focal_vertical; + guideInfo.ellipseMinorAxis[TopSide] = yheight / 2; + + guideInfo.ellipseMajorOffset[TopSide] = major_offset_vertical; + guideInfo.ellipseMinorOffset[TopSide] = 0; + + guideInfo.ellipseMajorAxis[BottomSide] = guideInfo.ellipseMajorAxis[TopSide]; + guideInfo.ellipseMinorAxis[BottomSide] = guideInfo.ellipseMinorAxis[TopSide]; + guideInfo.ellipseMajorOffset[BottomSide] = guideInfo.ellipseMajorOffset[TopSide]; + guideInfo.ellipseMinorOffset[BottomSide] = guideInfo.ellipseMinorOffset[TopSide]; + } + + // Applies the properties of the mirrors in the guide given by the user. + // These variables are used in the reflection functions. + + // Give a warning if all side of the guide is turned off, + // as the guide is essentially turned off + if (guideInfo.OuterSide[RightSide] == 1 && guideInfo.OuterSide[TopSide] == 1 && guideInfo.OuterSide[LeftSide] == 1 && guideInfo.OuterSide[BottomSide] == 1 + && guideInfo.InnerSide[RightSide] == 1 && guideInfo.InnerSide[TopSide] == 1 && guideInfo.InnerSide[LeftSide] == 1 && guideInfo.InnerSide[BottomSide] == 1) + printf ("Warning: In %s all the sides of the guide has been disabled," + " so it not possible for any particle" + " to collide with the guide, consider" + " disabling this component", + NAME_CURRENT_COMP); + + if (guideInfo.mArr[RightSide] <= 0) + guideInfo.InnerSide[RightSide] = MirrorTypeabsorption; + if (guideInfo.mArr[TopSide] <= 0) + guideInfo.InnerSide[TopSide] = MirrorTypeabsorption; + if (guideInfo.mArr[LeftSide] <= 0) + guideInfo.InnerSide[LeftSide] = MirrorTypeabsorption; + if (guideInfo.mArr[BottomSide] <= 0) + guideInfo.InnerSide[BottomSide] = MirrorTypeabsorption; + + if (strcmp (option, "halfellipse") == 0 && directDefination == 0) { + guideInfo.entranceHorizontalWidth = (guideInfo.ellipseMinorAxis[RightSide] + * sqrt (1 + - (guideInfo.ellipseMajorOffset[RightSide] * guideInfo.ellipseMajorOffset[RightSide]) + / (guideInfo.ellipseMajorAxis[RightSide] * guideInfo.ellipseMajorAxis[RightSide])) + + guideInfo.ellipseMinorOffset[RightSide]) + * 2; + guideInfo.entranceVerticalWidth = (guideInfo.ellipseMinorAxis[TopSide] + * sqrt (1 + - (guideInfo.ellipseMajorOffset[TopSide] * guideInfo.ellipseMajorOffset[TopSide]) + / (guideInfo.ellipseMajorAxis[TopSide] * guideInfo.ellipseMajorAxis[TopSide])) + + guideInfo.ellipseMinorOffset[TopSide]) + * 2; + } + + guideInfo.EnclosingBoxOn = 0; + + guideInfo.exitVerticalWidth + = 2 + * sqrt (1 + - ((guideInfo.Length - guideInfo.ellipseMajorOffset[BottomSide]) * (guideInfo.Length - guideInfo.ellipseMajorOffset[BottomSide])) + / (guideInfo.ellipseMajorAxis[BottomSide] * guideInfo.ellipseMajorAxis[BottomSide])) + * guideInfo.ellipseMinorAxis[BottomSide]; + + guideInfo.exitHorizontalWidth + = 2 + * sqrt (1 + - ((guideInfo.Length - guideInfo.ellipseMajorOffset[RightSide]) * (guideInfo.Length - guideInfo.ellipseMajorOffset[RightSide])) + / (guideInfo.ellipseMajorAxis[RightSide] * guideInfo.ellipseMajorAxis[RightSide])) + * guideInfo.ellipseMinorAxis[RightSide]; + + //////////////////segmentation of m values + + // Are the arrays empty? + if (mvaluesright != NULL || mvaluesleft != NULL || mvaluestop != NULL || mvaluesbottom != NULL) { + guideInfo.enableSegments = 1; + + if (nSegments == -1) { + printf ("\nError (%s): vector-specifcation of coating used, but nSegments=%i.\n Please give provide nSegments = length of coating segment-arrays!\n", + _comp->_name, nSegments); + exit (-1); + } else { + guideInfo.numberOfSegments = (int)nSegments; + } + + // printf("Length is %i\n",guideInfo.numberOfSegments); + guideInfo.mValuesright = mvaluesright; + guideInfo.mValuesleft = mvaluesleft; + guideInfo.mValuestop = mvaluestop; + guideInfo.mValuesbottom = mvaluesbottom; + // printf("Seglength ... %f %f %f\n",seglength[0],seglength[1],seglength[2]); + + // Are the arrays of equal length? + if (seglength == NULL) { + dynamicalSegLength = realloc (dynamicalSegLength, guideInfo.numberOfSegments * sizeof (double)); + int i; + for (i = 0; i < guideInfo.numberOfSegments; ++i) { + dynamicalSegLength[i] = guideInfo.Length / guideInfo.numberOfSegments; + } + guideInfo.segLength = dynamicalSegLength; + } else + guideInfo.segLength = seglength; + + double sumOfelements = 0; + int i; + for (i = 0; i < guideInfo.numberOfSegments; i++) { + sumOfelements += guideInfo.segLength[i]; + } + if (guideInfo.verboseSetting && fabs (sumOfelements - guideInfo.Length) > 1e-9) + printf ("Error in userinput inside %s, the difference between" + " guidelength and elements of the seglength array is:" + "%e consider changes the parameters l or seglength \n", + NAME_CURRENT_COMP, sumOfelements - guideInfo.Length); + } else + guideInfo.enableSegments = 0; + + /////////////////////////////////////////////////////////////////////////// + /////////////// Calculate gravity vector in the guides coordinatesystem + /////////////////////////////////////////////////////////////////////////// + + /* + Sets the local gravity vector equal to the global gravity vector (0,-g,0) + and when apply the same rotation matrix as applied to guide. + */ + if (enableGravity != 0) { + Gx0 = 0, Gy0 = -GRAVITY * enableGravity, Gz0 = 0; + Coords mcLocG; + mcLocG = rot_apply (ROT_A_CURRENT_COMP, coords_set (0, Gy0, 0)); + coords_get (mcLocG, &Gx0, &Gy0, &Gz0); + } + Circ = 2 * PI * curvature; %} /** @@ -1207,79 +1060,75 @@ INITIALIZE TRACE %{ struct Intersection latestParticleCollision; - latestParticleCollision.delta_time_to_next_collision=0; - latestParticleCollision.side=0; - latestParticleCollision.ApproxOn=0; - latestParticleCollision.collisionType=0; + latestParticleCollision.delta_time_to_next_collision = 0; + latestParticleCollision.side = 0; + latestParticleCollision.ApproxOn = 0; + latestParticleCollision.collisionType = 0; PROP_Z0; double Gloc; - double Gx,Gy,Gz; + double Gx, Gy, Gz; if (curvature) { - Gloc=(vx*vx+vy*vy+vz*vz)/curvature; + Gloc = (vx * vx + vy * vy + vz * vz) / curvature; } else { - Gloc=0; + Gloc = 0; } + if (!guideInfo.EnclosingBoxOn) + if (fabs (x) > guideInfo.entranceHorizontalWidth / 2.0 || fabs (y) > guideInfo.entranceVerticalWidth / 2.0) + ABSORB; - if( !guideInfo.EnclosingBoxOn ) - if( fabs(x) > guideInfo.entranceHorizontalWidth/2.0 - || fabs(y) > guideInfo.entranceVerticalWidth/2.0 ) - ABSORB; - - SCATTER; - - int bounces = 0; - for(bounces = 0; bounces <= 1000; bounces++){ - - Gx=Gx0; Gy=Gy0; Gz=Gz0; - if (curvature) { - // Add velocity-dependent, location-dependent approximation to centripetal force for curvature... - Gx=Gx0+Gloc*cos(2*PI*z/Circ);Gz=Gz0+Gloc*sin(2*PI*z/Circ); - } - - // Find the next intersection between the guide and the neutron. - int boolean = guide_elliptical_handleGuideIntersection( - x,y,z,vx,vy,vz,Gx,Gy,Gz, - &guideInfo,&latestParticleCollision); - - double timeToCollision = - latestParticleCollision.delta_time_to_next_collision; - - // Handle special cases. - if(boolean == 0) ABSORB; - if(timeToCollision < 1e-15) ABSORB; - - // If the neutron reach the end of the guide, when move - // the neutron to the end of guide and leave this component. - if( z+vz*timeToCollision+0.5*Gz*timeToCollision*timeToCollision - >= guideInfo.Length ) - { - double timeToExit = 0; - solve_2nd_order( - &timeToExit,NULL, - -0.5*Gz,-vz,guideInfo.Length-z-1e-9); - PROP_GRAV_DT(timeToExit,Gx,Gy,Gz); - SCATTER; - break; - } - - // Move the neutron and handle the reflection. - PROP_GRAV_DT(timeToCollision,Gx,Gy,Gz); - if(latestParticleCollision.collisionType == Absorb){ ABSORB; } - if(latestParticleCollision.collisionType == Reflex){ - p *= guide_elliptical_handleReflection(x,y,z,&vx,&vy,&vz, - &guideInfo,&latestParticleCollision); - SCATTER; - if(p == 0) ABSORB; - } - } - - if( fabs(x) > guideInfo.exitHorizontalWidth/2 - || fabs(y) > guideInfo.exitVerticalWidth/2 ) - ABSORB; + SCATTER; + int bounces = 0; + for (bounces = 0; bounces <= 1000; bounces++) { + + Gx = Gx0; + Gy = Gy0; + Gz = Gz0; + if (curvature) { + // Add velocity-dependent, location-dependent approximation to centripetal force for curvature... + Gx = Gx0 + Gloc * cos (2 * PI * z / Circ); + Gz = Gz0 + Gloc * sin (2 * PI * z / Circ); + } + + // Find the next intersection between the guide and the neutron. + int boolean = guide_elliptical_handleGuideIntersection (x, y, z, vx, vy, vz, Gx, Gy, Gz, &guideInfo, &latestParticleCollision); + + double timeToCollision = latestParticleCollision.delta_time_to_next_collision; + + // Handle special cases. + if (boolean == 0) + ABSORB; + if (timeToCollision < 1e-15) + ABSORB; + + // If the neutron reach the end of the guide, when move + // the neutron to the end of guide and leave this component. + if (z + vz * timeToCollision + 0.5 * Gz * timeToCollision * timeToCollision >= guideInfo.Length) { + double timeToExit = 0; + solve_2nd_order (&timeToExit, NULL, -0.5 * Gz, -vz, guideInfo.Length - z - 1e-9); + PROP_GRAV_DT (timeToExit, Gx, Gy, Gz); + SCATTER; + break; + } + + // Move the neutron and handle the reflection. + PROP_GRAV_DT (timeToCollision, Gx, Gy, Gz); + if (latestParticleCollision.collisionType == Absorb) { + ABSORB; + } + if (latestParticleCollision.collisionType == Reflex) { + p *= guide_elliptical_handleReflection (x, y, z, &vx, &vy, &vz, &guideInfo, &latestParticleCollision); + SCATTER; + if (p == 0) + ABSORB; + } + } + + if (fabs (x) > guideInfo.exitHorizontalWidth / 2 || fabs (y) > guideInfo.exitVerticalWidth / 2) + ABSORB; %} @@ -1291,198 +1140,167 @@ MCDISPLAY %{ - // Calculate the points need to draw approximation of the ellipses - // defining the guide - - // the number of lines used to draw one side of the guide - int ApproximationMirrors = 500; - - // The start of the guide - double zvalue=0; - - // The the different in z between point used to draw the ellipse - double zdelta = guideInfo.Length/(1.0*ApproximationMirrors); - - // The vector used to store the points defining the lines - double *xplus=malloc((ApproximationMirrors+1)*sizeof(double)); - double *xminus=malloc((ApproximationMirrors+1)*sizeof(double)); - double *yplus=malloc((ApproximationMirrors+1)*sizeof(double)); - double *yminus=malloc((ApproximationMirrors+1)*sizeof(double)); - - if (!xplus || !xminus || !yplus || !yminus) { - fprintf(stderr,"Elliptic_guide_gravity %s: ERROR allocating visualisation arrays. Exit!\n",NAME_CURRENT_COMP); - exit(-1); - } - - // Temperary values for the loop - double tempx; - double tempy; - - /* - Calculate the second coordinates to the points on the ellipse with z_i - as the first coordinate. We transform the point to the coordinate system - there the ellipse is a unit circle. And use the defination of this circle - to find second coordinate (x^2+z^2 = 1) - */ - - ///////////////////////////////////////////////////////// - double Length; - double entranceHorizontalWidth; - double entranceVerticalWidth; - - // ellipses infomation - double ellipseMajorAxis[4], ellipseMinorAxis[4]; - double ellipseMajorOffset[4], ellipseMinorOffset[4]; - - enum Side {RightSide,TopSide,LeftSide,BottomSide,None}; - ///////////////////////////////////////////////////////// - - int i = 0; - double tempz = 0; - for(i=0;i radius of central blocking zone\n",NAME_CURRENT_COMP); - exit(-1); - } - if (eta<0 ||eta>1){ - fprintf(stderr,"Error(%s): Efficiency (eta) of zone late must be in [0:1]\n",NAME_CURRENT_COMP); - exit(-1); - } - if(!eta){ - if(!thickness){ - fprintf(stderr,"Warning(%s): Efficiency (eta) and thickness of FZP is 0. No absorption is modelled\n",NAME_CURRENT_COMP); - }else if ( !(sigma_abs || sigma_inc || sigma_coh) ){ - fprintf(stderr,"Warning(%s): (sigma_abs,sigma_inc,sigma_coh)==0. No absorption is modelled\n",NAME_CURRENT_COMP); - } + if (rad <= bs0rad) { + fprintf (stderr, "Error(%s): Radius of Zone Plate must be > radius of central blocking zone\n", NAME_CURRENT_COMP); + exit (-1); + } + if (eta < 0 || eta > 1) { + fprintf (stderr, "Error(%s): Efficiency (eta) of zone late must be in [0:1]\n", NAME_CURRENT_COMP); + exit (-1); + } + if (!eta) { + if (!thickness) { + fprintf (stderr, "Warning(%s): Efficiency (eta) and thickness of FZP is 0. No absorption is modelled\n", NAME_CURRENT_COMP); + } else if (!(sigma_abs || sigma_inc || sigma_coh)) { + fprintf (stderr, "Warning(%s): (sigma_abs,sigma_inc,sigma_coh)==0. No absorption is modelled\n", NAME_CURRENT_COMP); } + } %} TRACE %{ int ord; - double focal_point,lambda,vel,theta_inx,theta_iny,theta_outx,theta_outy; + double focal_point, lambda, vel, theta_inx, theta_iny, theta_outx, theta_outy; PROP_Z0; - if ((bs0rad != 0) && (x*x + y*y < bs0rad*bs0rad)){ - ABSORB; - } else if (x*x + y*y < rad*rad) { - /*pick a diffraction order, and efficiency*/ - ord=floor(rand01()*(order*2+1))-order; - SCATTER; - vel=sqrt(vx*vx+vy*vy+vz*vz); - if(ord){ - int nn; - if(ord>0){ - nn=((abs(ord)-1)*2 + 1); - }else{ - nn=-((abs(ord)-1)*2 + 1); - } - lambda = 2*PI/(V2K*1e10*vel); // A factor of 10^10 to go from Ã… to m - focal_point = 2*rad*dr/lambda/nn;//-dr*dr/lambda; //add this to calculate w/ spherical aberration - /*check for negative focal pt. what happens?*/ - theta_inx = atan2(vx,vz); - theta_iny = atan2(vy,vz); - theta_outx = theta_inx - x/focal_point; - theta_outy = theta_iny - y/focal_point; - // printf ("x: %G theta inx: %G theta outx: %G\n",x,theta_inx,theta_outx); - // printf("y: %G theta_iny: %G theta_outy: %G\n",y,theta_iny,theta_outy); - vx = vel*sin(theta_outx); - vy = vel*sin(theta_outy); - vz = vel*sqrt(cos(theta_outx)*cos(theta_outx)-sin(theta_outy)*sin(theta_outy)); + if ((bs0rad != 0) && (x * x + y * y < bs0rad * bs0rad)) { + ABSORB; + } else if (x * x + y * y < rad * rad) { + /*pick a diffraction order, and efficiency*/ + ord = floor (rand01 () * (order * 2 + 1)) - order; + SCATTER; + vel = sqrt (vx * vx + vy * vy + vz * vz); + if (ord) { + int nn; + if (ord > 0) { + nn = ((abs (ord) - 1) * 2 + 1); + } else { + nn = -((abs (ord) - 1) * 2 + 1); } - /*if given use an external efficiency, else use diffraction theory*/ - if(eta){ - p *= eta; - }else{ - /*the relative strength of diffraction orders == the probability of scattering into that order.*/ - double etan; - int nn; - if (ord){ - nn=((abs(ord)-1)*2 + 1); - etan=2.0/(M_PI*M_PI * nn*nn);//(1.0/(nn*nn))/ 2.0 * 4/(M_PI*M_PI); - }else{ - etan=0.5; - } - /*weight by real prob / mc prob*/ - p*=etan/(1.0/(2.0*order+1)); - } - if (thickness){ - /* Add absorption to target efficiency. We approximate this by using a mean absorption, - * weighted by the diffraction angle, for half the distance travelled through the FZP.*/ - double inv_cth=vel/vz;/* theta=acos(v.[0,0,1] /|v|)*/ - double l_full=0.5*thickness *(1.0+inv_cth); - double mu=gamma * rho*100.0*( sigma_abs*(2200.0/vel) + sigma_inc + sigma_coh); - p*=exp(-l_full*mu); + lambda = 2 * PI / (V2K * 1e10 * vel); // A factor of 10^10 to go from Ã… to m + focal_point = 2 * rad * dr / lambda / nn; //-dr*dr/lambda; //add this to calculate w/ spherical aberration + /*check for negative focal pt. what happens?*/ + theta_inx = atan2 (vx, vz); + theta_iny = atan2 (vy, vz); + theta_outx = theta_inx - x / focal_point; + theta_outy = theta_iny - y / focal_point; + // printf ("x: %G theta inx: %G theta outx: %G\n",x,theta_inx,theta_outx); + // printf("y: %G theta_iny: %G theta_outy: %G\n",y,theta_iny,theta_outy); + vx = vel * sin (theta_outx); + vy = vel * sin (theta_outy); + vz = vel * sqrt (cos (theta_outx) * cos (theta_outx) - sin (theta_outy) * sin (theta_outy)); + } + /*if given use an external efficiency, else use diffraction theory*/ + if (eta) { + p *= eta; + } else { + /*the relative strength of diffraction orders == the probability of scattering into that order.*/ + double etan; + int nn; + if (ord) { + nn = ((abs (ord) - 1) * 2 + 1); + etan = 2.0 / (M_PI * M_PI * nn * nn); //(1.0/(nn*nn))/ 2.0 * 4/(M_PI*M_PI); + } else { + etan = 0.5; } + /*weight by real prob / mc prob*/ + p *= etan / (1.0 / (2.0 * order + 1)); + } + if (thickness) { + /* Add absorption to target efficiency. We approximate this by using a mean absorption, + * weighted by the diffraction angle, for half the distance travelled through the FZP.*/ + double inv_cth = vel / vz; /* theta=acos(v.[0,0,1] /|v|)*/ + double l_full = 0.5 * thickness * (1.0 + inv_cth); + double mu = gamma * rho * 100.0 * (sigma_abs * (2200.0 / vel) + sigma_inc + sigma_coh); + p *= exp (-l_full * mu); + } } %} diff --git a/mcstas-comps/optics/FermiChopper.comp b/mcstas-comps/optics/FermiChopper.comp index 3048086162..1f54112bd9 100644 --- a/mcstas-comps/optics/FermiChopper.comp +++ b/mcstas-comps/optics/FermiChopper.comp @@ -97,191 +97,184 @@ curvature=0,delay=0) SHARE %{ -%include "ref-lib" -#ifndef FermiChopper_TimeAccuracy -#define FermiChopper_TimeAccuracy 1e-9 -#define FermiChopper_MAXITER 100 - -/* Definition of internal variable structure: all counters */ -struct FermiChopper_struct -{ -double omega; /* chopper rotation */ -double ph0; /* chopper rotation */ -double t0; /* chopper rotation */ -double C_slit; /* slit curvature radius in [m] */ -double L_slit; /* slit package length [m] */ -double sum_t; -double sum_v; -double sum_N; -double sum_N_pass; -/* events */ -long absorb_alreadyinside; -long absorb_topbottom; -long absorb_cylentrance; -long absorb_sideentrance; -long absorb_notreachentrance; -long absorb_packentrance; -long absorb_slitcoating; -long warn_notreachslitwall; -long absorb_exitslitpack; -long absorb_maxiterations; -long absorb_wrongdirection; -long absorb_nocontrol; -long absorb_cylexit; -long warn_notreachslitoutput; -char compcurname[256]; -}; - -/***************************************************************************** -* FC_zrot: returns Z' in rotating frame, from X,Z and t,omega,ph0 -****************************************************************************/ -#pragma acc routine seq -double FC_zrot(double X, double Z, double T, struct FermiChopper_struct FCs) -{ - double omega =FCs.omega; - double ph0 =FCs.ph0; - - return( Z*cos(omega*T+ph0)-X*sin(omega*T+ph0) ); -} - -/***************************************************************************** - * FC_xrot: returns X' in rotating frame, from X,Z and omega,t,ph0 - * additional coordinate shift in case of curved slits - ****************************************************************************/ -#pragma acc routine seq -double FC_xrot(double X, double Z, double T, struct FermiChopper_struct FCs) -{ - double omega =FCs.omega; - double ph0 =FCs.ph0; - double C_slit=FCs.C_slit; - double ret, tmp; - - ret = X*cos(omega*T+ph0)+Z*sin(omega*T+ph0); - - if (C_slit) { - tmp = fabs(FC_zrot(X, Z, T, FCs)); - if (tmp < FCs.L_slit/2) { - tmp = (FCs.L_slit/2 - tmp)*C_slit; - ret += (1-sqrt(1-tmp*tmp))/C_slit; - } + %include "ref-lib" + #ifndef FermiChopper_TimeAccuracy + #define FermiChopper_TimeAccuracy 1e-9 + #define FermiChopper_MAXITER 100 + + /* Definition of internal variable structure: all counters */ + struct FermiChopper_struct { + double omega; /* chopper rotation */ + double ph0; /* chopper rotation */ + double t0; /* chopper rotation */ + double C_slit; /* slit curvature radius in [m] */ + double L_slit; /* slit package length [m] */ + double sum_t; + double sum_v; + double sum_N; + double sum_N_pass; + /* events */ + long absorb_alreadyinside; + long absorb_topbottom; + long absorb_cylentrance; + long absorb_sideentrance; + long absorb_notreachentrance; + long absorb_packentrance; + long absorb_slitcoating; + long warn_notreachslitwall; + long absorb_exitslitpack; + long absorb_maxiterations; + long absorb_wrongdirection; + long absorb_nocontrol; + long absorb_cylexit; + long warn_notreachslitoutput; + char compcurname[256]; + }; + + /***************************************************************************** + * FC_zrot: returns Z' in rotating frame, from X,Z and t,omega,ph0 + ****************************************************************************/ + #pragma acc routine seq + double + FC_zrot (double X, double Z, double T, struct FermiChopper_struct FCs) { + double omega = FCs.omega; + double ph0 = FCs.ph0; + + return (Z * cos (omega * T + ph0) - X * sin (omega * T + ph0)); } - return( ret ); -} - -/***************************************************************************** - * FC_xzrot_dt(x,z,vx,vz, t,dt, type='x' or 'z', FCs) - * returns X' or Z' in rotating frame, from X,Z and t,omega,ph0 - * taking into account propagation with velocity during time dt - ****************************************************************************/ -#pragma acc routine seq -double FC_xzrot_dt(double x, double z, double vx, double vz, - double t, double dt, char type, struct FermiChopper_struct FCs) -{ - if (dt) /* with propagation */ - return( (type == 'x' ? FC_xrot(x+vx*dt, z+vz*dt, t+dt, FCs) - : FC_zrot(x+vx*dt, z+vz*dt, t+dt, FCs)) ); - else /* without propagation */ - return( (type == 'x' ? FC_xrot(x,z,t,FCs) - : FC_zrot(x,z,t,FCs)) ); -} - -/***************************************************************************** - * FC_xzbrent(x,z,vx,vz, t,dt, type='x' or 'z', d, FCs) - * solves X'=d and Z'=d with Brent algorithm in time interval [0, dt]. - * Returns time within [0,dt], from NumRecip in C, chap 9, p360 (zbrent) - * ERRORS: return -1 not used - * -2 if exceed MAX iteration - * -3 no sign change in range - ****************************************************************************/ -#pragma acc routine seq -double FC_xzbrent(double x, double z, double vx, double vz, - double t, double dt, - char type, double d, struct FermiChopper_struct FCs) -{ - int iter; - double a=0,b=dt; - double c,dd,e,min1,min2; - double tol=FermiChopper_TimeAccuracy; - double EPS=FermiChopper_TimeAccuracy; - double fa=FC_xzrot_dt(x,z,vx,vz, t,a, type, FCs) - d; - double fb=FC_xzrot_dt(x,z,vx,vz, t,b, type, FCs) - d; - double fc,p,q,r,s,tol1,xm; - - if (fb*fa > 0.0) return -3; - fc=fb; - for (iter=1;iter<=FermiChopper_MAXITER;iter++) { - if (fb*fc > 0.0) { - c=a; - fc=fa; - e=dd=b-a; - } - if (fabs(fc) < fabs(fb)) { - a=b; - b=c; - c=a; - fa=fb; - fb=fc; - fc=fa; + + /***************************************************************************** + * FC_xrot: returns X' in rotating frame, from X,Z and omega,t,ph0 + * additional coordinate shift in case of curved slits + ****************************************************************************/ + #pragma acc routine seq + double + FC_xrot (double X, double Z, double T, struct FermiChopper_struct FCs) { + double omega = FCs.omega; + double ph0 = FCs.ph0; + double C_slit = FCs.C_slit; + double ret, tmp; + + ret = X * cos (omega * T + ph0) + Z * sin (omega * T + ph0); + + if (C_slit) { + tmp = fabs (FC_zrot (X, Z, T, FCs)); + if (tmp < FCs.L_slit / 2) { + tmp = (FCs.L_slit / 2 - tmp) * C_slit; + ret += (1 - sqrt (1 - tmp * tmp)) / C_slit; + } } - tol1=2.0*EPS*fabs(b)+0.5*tol; - xm=0.5*(c-b); - if (fabs(xm) <= tol1 || fb == 0.0) return b; - if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) { - s=fb/fa; - if (a == c) { - p=2.0*xm*s; - q=1.0-s; - } else { - q=fa/fc; - r=fb/fc; - p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0)); - q=(q-1.0)*(r-1.0)*(s-1.0); + return (ret); + } + + /***************************************************************************** + * FC_xzrot_dt(x,z,vx,vz, t,dt, type='x' or 'z', FCs) + * returns X' or Z' in rotating frame, from X,Z and t,omega,ph0 + * taking into account propagation with velocity during time dt + ****************************************************************************/ + #pragma acc routine seq + double + FC_xzrot_dt (double x, double z, double vx, double vz, double t, double dt, char type, struct FermiChopper_struct FCs) { + if (dt) /* with propagation */ + return ((type == 'x' ? FC_xrot (x + vx * dt, z + vz * dt, t + dt, FCs) : FC_zrot (x + vx * dt, z + vz * dt, t + dt, FCs))); + else /* without propagation */ + return ((type == 'x' ? FC_xrot (x, z, t, FCs) : FC_zrot (x, z, t, FCs))); + } + + /***************************************************************************** + * FC_xzbrent(x,z,vx,vz, t,dt, type='x' or 'z', d, FCs) + * solves X'=d and Z'=d with Brent algorithm in time interval [0, dt]. + * Returns time within [0,dt], from NumRecip in C, chap 9, p360 (zbrent) + * ERRORS: return -1 not used + * -2 if exceed MAX iteration + * -3 no sign change in range + ****************************************************************************/ + #pragma acc routine seq + double + FC_xzbrent (double x, double z, double vx, double vz, double t, double dt, char type, double d, struct FermiChopper_struct FCs) { + int iter; + double a = 0, b = dt; + double c, dd, e, min1, min2; + double tol = FermiChopper_TimeAccuracy; + double EPS = FermiChopper_TimeAccuracy; + double fa = FC_xzrot_dt (x, z, vx, vz, t, a, type, FCs) - d; + double fb = FC_xzrot_dt (x, z, vx, vz, t, b, type, FCs) - d; + double fc, p, q, r, s, tol1, xm; + + if (fb * fa > 0.0) + return -3; + fc = fb; + for (iter = 1; iter <= FermiChopper_MAXITER; iter++) { + if (fb * fc > 0.0) { + c = a; + fc = fa; + e = dd = b - a; } - if (p > 0.0) q = -q; - p=fabs(p); - min1=3.0*xm*q-fabs(tol1*q); - min2=fabs(e*q); - if (2.0*p < (min1 < min2 ? min1 : min2)) { - e=dd; - dd=p/q; + if (fabs (fc) < fabs (fb)) { + a = b; + b = c; + c = a; + fa = fb; + fb = fc; + fc = fa; + } + tol1 = 2.0 * EPS * fabs (b) + 0.5 * tol; + xm = 0.5 * (c - b); + if (fabs (xm) <= tol1 || fb == 0.0) + return b; + if (fabs (e) >= tol1 && fabs (fa) > fabs (fb)) { + s = fb / fa; + if (a == c) { + p = 2.0 * xm * s; + q = 1.0 - s; + } else { + q = fa / fc; + r = fb / fc; + p = s * (2.0 * xm * q * (q - r) - (b - a) * (r - 1.0)); + q = (q - 1.0) * (r - 1.0) * (s - 1.0); + } + if (p > 0.0) + q = -q; + p = fabs (p); + min1 = 3.0 * xm * q - fabs (tol1 * q); + min2 = fabs (e * q); + if (2.0 * p < (min1 < min2 ? min1 : min2)) { + e = dd; + dd = p / q; + } else { + dd = xm; + e = dd; + } } else { - dd=xm; - e=dd; + dd = xm; + e = dd; } - } else { - dd=xm; - e=dd; + a = b; + fa = fb; + if (fabs (dd) > tol1) + b += dd; + else + b += (xm > 0.0 ? fabs (tol1) : -fabs (tol1)); + fb = FC_xzrot_dt (x, z, vx, vz, t, b, type, FCs) - d; } - a=b; - fa=fb; - if (fabs(dd) > tol1) - b += dd; - else - b += (xm > 0.0 ? fabs(tol1) : -fabs(tol1)); - fb=FC_xzrot_dt(x,z,vx,vz, t,b, type, FCs) - d; + return -2; + } /* FC_xzbrent */ + + /***************************************************************************** + * Wrappers to intersection algorithms + ****************************************************************************/ + #pragma acc routine seq + double + FC_xintersect (double x, double z, double vx, double vz, double t, double dt, double d, struct FermiChopper_struct FCs) { + return (FC_xzbrent (x, z, vx, vz, t, dt, 'x', d, FCs)); + } + #pragma acc routine seq + double + FC_zintersect (double x, double z, double vx, double vz, double t, double dt, double d, struct FermiChopper_struct FCs) { + return (FC_xzbrent (x, z, vx, vz, t, dt, 'z', d, FCs)); } - return -2; -} /* FC_xzbrent */ - -/***************************************************************************** - * Wrappers to intersection algorithms - ****************************************************************************/ -#pragma acc routine seq -double FC_xintersect(double x, double z, double vx, double vz, - double t, double dt, - double d, struct FermiChopper_struct FCs) -{ - return(FC_xzbrent(x, z, vx, vz, t, dt, 'x', d, FCs)); -} -#pragma acc routine seq -double FC_zintersect(double x, double z, double vx, double vz, - double t, double dt, - double d, struct FermiChopper_struct FCs) -{ - return(FC_xzbrent(x, z, vx, vz, t, dt, 'z', d, FCs)); -} - -#endif + + #endif %} DECLARE @@ -292,80 +285,92 @@ DECLARE INITIALIZE %{ -/************************ CALCULATION CONSTANTS *****************************/ - strcpy(FCVars.compcurname, NAME_CURRENT_COMP); + /************************ CALCULATION CONSTANTS *****************************/ + strcpy (FCVars.compcurname, NAME_CURRENT_COMP); - FCVars.omega = 2*PI*nu; + FCVars.omega = 2 * PI * nu; if (!phase && delay) { - FCVars.ph0= fmod(-delay*nu*360,360)*DEG2RAD; - } else FCVars.ph0 = phase*DEG2RAD; - FCVars.sum_t=FCVars.sum_v=FCVars.sum_N=FCVars.sum_N_pass=0; + FCVars.ph0 = fmod (-delay * nu * 360, 360) * DEG2RAD; + } else + FCVars.ph0 = phase * DEG2RAD; + FCVars.sum_t = FCVars.sum_v = FCVars.sum_N = FCVars.sum_N_pass = 0; /* check of input parameters */ - if (nslit < 1) nslit=1; - if (yheight <= 0) exit(printf("FermiChopper: %s: FATAL: unrealistic cylinder yheight =%g [m]\n", NAME_CURRENT_COMP, yheight)); - - if (m <= 0) { m=0; R0=0; } + if (nslit < 1) + nslit = 1; + if (yheight <= 0) + exit (printf ("FermiChopper: %s: FATAL: unrealistic cylinder yheight =%g [m]\n", NAME_CURRENT_COMP, yheight)); + + if (m <= 0) { + m = 0; + R0 = 0; + } if (radius <= 0) { - printf("FermiChopper: %s: FATAL: Unrealistic cylinder radius radius=%g [m]\n", NAME_CURRENT_COMP, radius); - exit(-1); + printf ("FermiChopper: %s: FATAL: Unrealistic cylinder radius radius=%g [m]\n", NAME_CURRENT_COMP, radius); + exit (-1); } - if (xwidth > 0 && xwidth < radius*2 && nslit > 0) { - w = xwidth/nslit; + if (xwidth > 0 && xwidth < radius * 2 && nslit > 0) { + w = xwidth / nslit; } if (w <= 0) { - printf("FermiChopper: %s: FATAL: Slits in the package have unrealistic width w=%g [m]\n", NAME_CURRENT_COMP, w); - exit(-1); + printf ("FermiChopper: %s: FATAL: Slits in the package have unrealistic width w=%g [m]\n", NAME_CURRENT_COMP, w); + exit (-1); } - if (nslit*w > radius*2) { - nslit = floor(radius/w); - printf("FermiChopper: %s: Too many slits to fit in the cylinder\n" - " Adjusting nslit=%f\n", NAME_CURRENT_COMP, nslit); + if (nslit * w > radius * 2) { + nslit = floor (radius / w); + printf ("FermiChopper: %s: Too many slits to fit in the cylinder\n" + " Adjusting nslit=%f\n", + NAME_CURRENT_COMP, nslit); } - if (length > radius*2) { - length = 2*sqrt(radius*radius - nslit*w*nslit*w/4); - printf("FermiChopper: %s: Slit package is longer than the whole\n" - " chopper cylinder. Adjusting length=%g [m]\n", NAME_CURRENT_COMP, length); + if (length > radius * 2) { + length = 2 * sqrt (radius * radius - nslit * w * nslit * w / 4); + printf ("FermiChopper: %s: Slit package is longer than the whole\n" + " chopper cylinder. Adjusting length=%g [m]\n", + NAME_CURRENT_COMP, length); } if (eff <= 0 || eff > 1) { eff = 0.95; - printf("FermiChopper: %s: Efficiency is unrealistic\n" - " Adjusting eff=%f\n", NAME_CURRENT_COMP, eff); + printf ("FermiChopper: %s: Efficiency is unrealistic\n" + " Adjusting eff=%f\n", + NAME_CURRENT_COMP, eff); } - if (Qc <= 0) { Qc = 0.02176; m = 0; R0 = 0; } - if (W <= 0) W=1e-6; + if (Qc <= 0) { + Qc = 0.02176; + m = 0; + R0 = 0; + } + if (W <= 0) + W = 1e-6; if (curvature) { FCVars.C_slit = curvature; - if (1 < fabs(radius*curvature)) - exit(printf("FermiChopper: %s: Slit curvature is unrealistic\n", - NAME_CURRENT_COMP)); + if (1 < fabs (radius * curvature)) + exit (printf ("FermiChopper: %s: Slit curvature is unrealistic\n", NAME_CURRENT_COMP)); } FCVars.L_slit = length; if (verbose && nu) - printf("FermiChopper: %s: Frequency nu=%g [Hz] %g [rpm], time frame=%g [s] phase=%g [deg]\n" - , NAME_CURRENT_COMP, nu, nu*60, 2/nu, FCVars.ph0*RAD2DEG); + printf ("FermiChopper: %s: Frequency nu=%g [Hz] %g [rpm], time frame=%g [s] phase=%g [deg]\n", NAME_CURRENT_COMP, nu, nu * 60, 2 / nu, FCVars.ph0* RAD2DEG); - FCVars.absorb_alreadyinside = 0; - FCVars.absorb_topbottom = 0; - FCVars.absorb_cylentrance = 0; - FCVars.absorb_sideentrance = 0; + FCVars.absorb_alreadyinside = 0; + FCVars.absorb_topbottom = 0; + FCVars.absorb_cylentrance = 0; + FCVars.absorb_sideentrance = 0; FCVars.absorb_notreachentrance = 0; - FCVars.absorb_packentrance = 0; - FCVars.absorb_slitcoating = 0; - FCVars.warn_notreachslitwall = 0; - FCVars.absorb_exitslitpack = 0; - FCVars.absorb_maxiterations = 0; - FCVars.absorb_wrongdirection = 0; - FCVars.absorb_nocontrol = 0; - FCVars.absorb_cylexit = 0; + FCVars.absorb_packentrance = 0; + FCVars.absorb_slitcoating = 0; + FCVars.warn_notreachslitwall = 0; + FCVars.absorb_exitslitpack = 0; + FCVars.absorb_maxiterations = 0; + FCVars.absorb_wrongdirection = 0; + FCVars.absorb_nocontrol = 0; + FCVars.absorb_cylexit = 0; FCVars.warn_notreachslitoutput = 0; /* fix for the wrong coordinate frame orientation to come back to McStas XYZ system */ FCVars.omega *= -1; - FCVars.ph0 *= -1; - FCVars.t0 = -FCVars.ph0/FCVars.omega; + FCVars.ph0 *= -1; + FCVars.t0 = -FCVars.ph0 / FCVars.omega; %} TRACE @@ -383,67 +388,66 @@ TRACE double n1; /** Multiple Reflections ******************************/ - int loopcounter=0; /* How many reflections happen? */ + int loopcounter = 0; /* How many reflections happen? */ /** Time variables *********************************/ - double t3=0; /* interaction time at n3 position (slit wall) */ - double t1=0,t2=0; /* cylinder intersection time (at entry and exit of slit pack - n1 n2 - or cylinder) */ - double dt; /* interaction intervals (e.g. time for exiting slit pack) */ - - double X[5],Z[5]; /* position of interaction locations in the Fermi chopper rotating frame - [0]=cylinder input - [1]=slit input - [2]=slit wall reflection - [3]=slit exit - [4]=cylinder exit - */ + double t3 = 0; /* interaction time at n3 position (slit wall) */ + double t1 = 0, t2 = 0; /* cylinder intersection time (at entry and exit of slit pack - n1 n2 - or cylinder) */ + double dt; /* interaction intervals (e.g. time for exiting slit pack) */ + + double X[5], Z[5]; /* position of interaction locations in the Fermi chopper rotating frame + [0]=cylinder input + [1]=slit input + [2]=slit wall reflection + [3]=slit exit + [4]=cylinder exit + */ double ref = 0; - double par[5] = {R0, Qc, alpha, m, W}; - + double par[5] = { R0, Qc, alpha, m, W }; + /************************ TIME OF FLIGHT RESET ************************/ if (zero_time == 1 && nu) - t -= floor( (t+1/(4*nu))*(2*nu) )/(2*nu); + t -= floor ((t + 1 / (4 * nu)) * (2 * nu)) / (2 * nu); /* zero arrays used to store positions */ - for (loopcounter=0; loopcounter < 5; loopcounter++) - X[loopcounter] = Z[loopcounter]=0; + for (loopcounter = 0; loopcounter < 5; loopcounter++) + X[loopcounter] = Z[loopcounter] = 0; /************** test, if the neutron interacts with the cylinder ***/ - if (cylinder_intersect (&t1, &t2, x, y, z, vx, vy, vz, radius, yheight)) - { + if (cylinder_intersect (&t1, &t2, x, y, z, vx, vy, vz, radius, yheight)) { if (t1 <= 0) { /* Neutron started inside the cylinder */ - if (verbose > 0 && FCVars.absorb_alreadyinside 0 && FCVars.absorb_alreadyinside < FermiChopper_MAXITER) + printf ("FermiChopper: %s: ABSORB Neutron started inside the cylinder, t1=%8.3g (enter).\n", NAME_CURRENT_COMP, t1); #pragma acc atomic FCVars.absorb_alreadyinside = FCVars.absorb_alreadyinside + 1; ABSORB; } if (verbose > 2) - printf("FermiChopper: %s: t1=%8.3g t2=%8.3g xyz=[%8.3g %8.3g %8.3g] v=[%8.3g %8.3g %8.3g] t=%8.3g (init).\n", - NAME_CURRENT_COMP, t1, t2, x,y,z,vx,vy,vz,t); + printf ("FermiChopper: %s: t1=%8.3g t2=%8.3g xyz=[%8.3g %8.3g %8.3g] v=[%8.3g %8.3g %8.3g] t=%8.3g (init).\n", NAME_CURRENT_COMP, t1, t2, x, y, z, + vx, vy, vz, t); - dt=t2-t1; /* total time of flight inside the cylinder */ - PROP_DT(t1); /* Propagates neutron to entrance of the cylinder */ + dt = t2 - t1; /* total time of flight inside the cylinder */ + PROP_DT (t1); /* Propagates neutron to entrance of the cylinder */ SCATTER; if (verbose > 2) - printf("FermiChopper: %s: PROP_DT t1=%8.3g t2=%8.3g xyz=[%8.3g %8.3g %8.3g] v=[%8.3g %8.3g %8.3g] t=%8.3g (IN cyl).\n", - NAME_CURRENT_COMP, t1, t2, x,y,z,vx,vy,vz,t); + printf ("FermiChopper: %s: PROP_DT t1=%8.3g t2=%8.3g xyz=[%8.3g %8.3g %8.3g] v=[%8.3g %8.3g %8.3g] t=%8.3g (IN cyl).\n", NAME_CURRENT_COMP, t1, t2, x, y, z, + vx, vy, vz, t); /* neutron must not enter or leave from top or bottom of cylinder. */ - if (fabs(y) >= yheight/2.0 || fabs(y+vy*dt) >= yheight/2.0) { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron hits top/bottom of cylinder, y=%8.3g (enter).\n", - NAME_CURRENT_COMP, y); + if (fabs (y) >= yheight / 2.0 || fabs (y + vy * dt) >= yheight / 2.0) { + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron hits top/bottom of cylinder, y=%8.3g (enter).\n", NAME_CURRENT_COMP, y); #pragma acc atomic - FCVars.absorb_topbottom = FCVars.absorb_topbottom + 1; + FCVars.absorb_topbottom = FCVars.absorb_topbottom + 1; ABSORB; } - vxp1 = sqrt(vx*vx+vy*vy+vz*vz); - double tmp=p*vxp1; + vxp1 = sqrt (vx * vx + vy * vy + vz * vz); + double tmp = p * vxp1; #pragma acc atomic FCVars.sum_v = FCVars.sum_v + tmp; - tmp = p*t; + tmp = p * t; #pragma acc atomic FCVars.sum_t = FCVars.sum_t + tmp; #pragma acc atomic @@ -451,123 +455,126 @@ TRACE if (zero_time > 1 && FCVars.sum_N) { /* automatic phase adjustment */ double mean_t, mean_phase; - mean_t = FCVars.sum_t/FCVars.sum_N; - mean_phase = fmod(mean_t*nu*2*PI, 2*PI); + mean_t = FCVars.sum_t / FCVars.sum_N; + mean_phase = fmod (mean_t * nu * 2 * PI, 2 * PI); /* now we shift the phase so that the neutron pulse is centered on the slit pack */ - mean_phase+= radius/vxp1*2*PI*nu; + mean_phase += radius / vxp1 * 2 * PI * nu; #pragma acc atomic write FCVars.ph0 = mean_phase; } - /* neutron must enter the cylinder opening: |X'| < full package width*/ - xp1 = FC_xrot(x,z, t,FCVars); /* X'(t) */ - if (fabs(xp1) >= nslit*w/2) { + xp1 = FC_xrot (x, z, t, FCVars); /* X'(t) */ + if (fabs (xp1) >= nslit * w / 2) { if (verbose > 2) - printf("FermiChopper: %s: ABSORB Neutron X is outside cylinder aperture, x'=%8.3g > %g (enter).\n", - NAME_CURRENT_COMP, xp1, nslit*w/2); + printf ("FermiChopper: %s: ABSORB Neutron X is outside cylinder aperture, x'=%8.3g > %g (enter).\n", NAME_CURRENT_COMP, xp1, nslit * w / 2); #pragma acc atomic FCVars.absorb_cylentrance = FCVars.absorb_cylentrance + 1; ABSORB; } -/*********************** PROPAGATE TO SLIT PACKAGE **************************/ + /*********************** PROPAGATE TO SLIT PACKAGE **************************/ /* zp1 = Z' at entrance of cylinder Z'(t) */ - zp1 = FC_zrot(x,z, t, FCVars); + zp1 = FC_zrot (x, z, t, FCVars); - X[0] = xp1; Z[0] = zp1; + X[0] = xp1; + Z[0] = zp1; /* here we should have sqrt(x*x+z*z) == sqrt(xp1*xp1+zp1*zp1) */ - t3 = sqrt(x*x+z*z) / sqrt(xp1*xp1+zp1*zp1); + t3 = sqrt (x * x + z * z) / sqrt (xp1 * xp1 + zp1 * zp1); if (t3 < 0.99 || 1.01 < t3) { if (verbose > 1 && FCVars.absorb_cylentrance < FermiChopper_MAXITER) - printf("FermiChopper: %s: ABSORB Neutron radius on cylinder in static frame r=%g does not match that of rotating frame r'=%g.\n", - NAME_CURRENT_COMP, sqrt(x*x+z*z), sqrt(xp1*xp1+zp1*zp1)); + printf ("FermiChopper: %s: ABSORB Neutron radius on cylinder in static frame r=%g does not match that of rotating frame r'=%g.\n", NAME_CURRENT_COMP, + sqrt (x * x + z * z), sqrt (xp1 * xp1 + zp1 * zp1)); #pragma acc atomic - FCVars.absorb_cylentrance = FCVars.absorb_cylentrance +1 ; + FCVars.absorb_cylentrance = FCVars.absorb_cylentrance + 1; ABSORB; } /* Checking on which side of the Chopper the Neutron enters: sign(Z') */ - slit_input = (zp1 > 0 ? length/2 : -length/2); + slit_input = (zp1 > 0 ? length / 2 : -length / 2); /* time shift to reach slit package in [0,time to exit cylinder]: Z'=slit_input */ /* t3 is used here as a tmp variable, will be redefined in for loop */ - t3 = FC_zintersect(x,z,vx,vz, t,dt, slit_input, FCVars); + t3 = FC_zintersect (x, z, vx, vz, t, dt, slit_input, FCVars); - if( (t3 < 0)||(t3 > dt) ) { + if ((t3 < 0) || (t3 > dt)) { if (verbose > 2 && FCVars.absorb_notreachentrance < FermiChopper_MAXITER) { - printf("FermiChopper: %s: Can not reach entrance of slits. dt=%8.3g t3=%8.3g (intersection:1).\n", - NAME_CURRENT_COMP, dt, t3); + printf ("FermiChopper: %s: Can not reach entrance of slits. dt=%8.3g t3=%8.3g (intersection:1).\n", NAME_CURRENT_COMP, dt, t3); if (t3 == -3) - printf(" No sign change to determine intersection\n"); + printf (" No sign change to determine intersection\n"); else if (t3 == -2) - printf(" Max iterations reached\n"); + printf (" Max iterations reached\n"); else if (t3 < 0) - printf(" Error when solving intersection\n"); + printf (" Error when solving intersection\n"); } - #pragma acc atomic + #pragma acc atomic FCVars.absorb_notreachentrance = FCVars.absorb_notreachentrance + 1; ABSORB; /* neutron can not reach slit entrance */ } /* Propagating to the slit package entrance */ - PROP_DT(t3); /* dt = t2-t1: time in cylinder */ - dt -= t3; /* remaining time from slit pack entry to exit of cylinder */ - xp1 = FC_xrot(x,z, t, FCVars); /* should be slit_input */ - zp1 = FC_zrot(x,z, t, FCVars); - X[1] = xp1; Z[1] = zp1; - -#ifndef OPENACC + PROP_DT (t3); /* dt = t2-t1: time in cylinder */ + dt -= t3; /* remaining time from slit pack entry to exit of cylinder */ + xp1 = FC_xrot (x, z, t, FCVars); /* should be slit_input */ + zp1 = FC_zrot (x, z, t, FCVars); + X[1] = xp1; + Z[1] = zp1; + + #ifndef OPENACC if (mcdotrace) { /* indicate position of neutron in mcdisplay */ - double xp2 = x; double zp2 = z; x = xp1; z=zp1; SCATTER; x=xp2; z=zp2; - } else -#endif -SCATTER; + double xp2 = x; + double zp2 = z; + x = xp1; + z = zp1; + SCATTER; + x = xp2; + z = zp2; + } else + #endif + SCATTER; if (verbose > 2) - printf("FermiChopper: %s: PROP_DT t=%8.3g dt=%8.3g x'=%8.3g z'=%8.3g length=%g (slit enter).\n", - NAME_CURRENT_COMP, t, dt, xp1, zp1, slit_input); + printf ("FermiChopper: %s: PROP_DT t=%8.3g dt=%8.3g x'=%8.3g z'=%8.3g length=%g (slit enter).\n", NAME_CURRENT_COMP, t, dt, xp1, zp1, slit_input); /* must have X'< slit package width at package Z'=slit_input */ - if (fabs(xp1) >= nslit*w/2) { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron X is outside slit package, x'=%8.3g > %g (enter).\n", - NAME_CURRENT_COMP, xp1, nslit*w/2); + if (fabs (xp1) >= nslit * w / 2) { + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron X is outside slit package, x'=%8.3g > %g (enter).\n", NAME_CURRENT_COMP, xp1, nslit * w / 2); #pragma acc atomic - FCVars.absorb_packentrance = FCVars.absorb_packentrance + 1; + FCVars.absorb_packentrance = FCVars.absorb_packentrance + 1; ABSORB; } /* solve Z'=-slit_input for time of exit of slit package */ /* t3 is used here as a tmp variable, will be redefined in for loop */ - t3 = FC_zintersect(x,z,vx,vz, t,dt*1.1, -slit_input, FCVars); + t3 = FC_zintersect (x, z, vx, vz, t, dt * 1.1, -slit_input, FCVars); - if((t3 < FermiChopper_TimeAccuracy)||(t3 > dt)) { + if ((t3 < FermiChopper_TimeAccuracy) || (t3 > dt)) { if (verbose > 1 && FCVars.warn_notreachslitoutput < FermiChopper_MAXITER) { - printf("FermiChopper: %s: Can not reach exit of slits. dt=%8.3g t3=%8.3g (intersection:2).\n", - NAME_CURRENT_COMP, dt, t3); + printf ("FermiChopper: %s: Can not reach exit of slits. dt=%8.3g t3=%8.3g (intersection:2).\n", NAME_CURRENT_COMP, dt, t3); if (t3 == -3) - printf(" No sign change to determine intersection\n"); + printf (" No sign change to determine intersection\n"); else if (t3 == -2) - printf(" Max iterations reached\n"); + printf (" Max iterations reached\n"); else if (t3 < 0) - printf(" Error when solving intersection\n"); + printf (" Error when solving intersection\n"); } #pragma acc atomic - FCVars.warn_notreachslitoutput = FCVars.warn_notreachslitoutput + 1; + FCVars.warn_notreachslitoutput = FCVars.warn_notreachslitoutput + 1; /* we estimate analytically the time to the slit exit */ - t3 = length/vxp1; + t3 = length / vxp1; } dt = t3; /* reduce time interval to [0, time of slit exit] */ /* here we should have dt*v = length (slit entrance -> exit) */ - t3 = fabs(FC_xzrot_dt(x,z,vx,vz, t, 0 , 'z', FCVars) - FC_xzrot_dt(x,z,vx,vz, t, dt, 'z', FCVars))/length; - if (fabs(t3-1) > 0.02) { + t3 = fabs (FC_xzrot_dt (x, z, vx, vz, t, 0, 'z', FCVars) - FC_xzrot_dt (x, z, vx, vz, t, dt, 'z', FCVars)) / length; + if (fabs (t3 - 1) > 0.02) { if (verbose > 0 && FCVars.warn_notreachslitoutput < FermiChopper_MAXITER) - printf("FermiChopper: %s: ABSORB Neutron propagation time v*dt/length=%g in slit does not match its length=%g (slit exit expected).\n", - NAME_CURRENT_COMP, t3, length); + printf ("FermiChopper: %s: ABSORB Neutron propagation time v*dt/length=%g in slit does not match its length=%g (slit exit expected).\n", + NAME_CURRENT_COMP, t3, length); #pragma acc atomic FCVars.warn_notreachslitoutput = FCVars.warn_notreachslitoutput + 1; ABSORB; @@ -582,53 +589,50 @@ SCATTER; |---------| */ -/*********************PROPAGATION INSIDE THE SLIT PACKAGE *******************/ + /*********************PROPAGATION INSIDE THE SLIT PACKAGE *******************/ /* index of slit hit at entrance n1=-N/2 (xp1=-) ... N/2 (xp1=+) */ - n1 = floor(xp1/w); + n1 = floor (xp1 / w); -/******************* BEGIN LOOP FOR MULTIPLE REFLECTIONS ********************/ + /******************* BEGIN LOOP FOR MULTIPLE REFLECTIONS ********************/ - for (loopcounter=0; loopcounter<=FermiChopper_MAXITER; loopcounter++) { - double dt_to_tangent=0; /* time shift to go to tangent intersection */ - double n2,n3; /* slit indices */ - double xp2, zp2,xp3=0,vxp2=0,vzp1=0; /* position, velocity */ - double q; /* used for calculating new velocities after reflection */ - int i; + for (loopcounter = 0; loopcounter <= FermiChopper_MAXITER; loopcounter++) { + double dt_to_tangent = 0; /* time shift to go to tangent intersection */ + double n2, n3; /* slit indices */ + double xp2, zp2, xp3 = 0, vxp2 = 0, vzp1 = 0; /* position, velocity */ + double q; /* used for calculating new velocities after reflection */ + int i; /* compute trajectory tangents: m1=Vz'+w.X'(t), m2=Vz'+w.X'(t+dt) */ - xp1 = FC_xrot (x,z, t, FCVars); /* X'(t) current position */ - xp2 = FC_xzrot_dt(x,z,vx,vz, t, dt, 'x', FCVars); /* X'(t+dt) slit exit */ - zp2 = FC_xzrot_dt(x,z,vx,vz, t, dt, 'z', FCVars); /* Z'(t+dt) slit exit */ + xp1 = FC_xrot (x, z, t, FCVars); /* X'(t) current position */ + xp2 = FC_xzrot_dt (x, z, vx, vz, t, dt, 'x', FCVars); /* X'(t+dt) slit exit */ + zp2 = FC_xzrot_dt (x, z, vx, vz, t, dt, 'z', FCVars); /* Z'(t+dt) slit exit */ /* slit index at the end of the slit: */ - n2 = floor(xp2/w); + n2 = floor (xp2 / w); /* quick exit for absorbing walls when neutron changes slit index */ if (n2 != n1 && (m <= 0 || R0 <= 0 || Qc <= 0)) { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron hits absorbing coating (change slit).\n", - NAME_CURRENT_COMP); - #pragma acc atomic - FCVars.absorb_slitcoating = FCVars.absorb_slitcoating + 1; - ABSORB; + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron hits absorbing coating (change slit).\n", NAME_CURRENT_COMP); + #pragma acc atomic + FCVars.absorb_slitcoating = FCVars.absorb_slitcoating + 1; + ABSORB; } /* compute transversal velocity to determine their intersection */ - vxp1= FC_xrot (vx+z*FCVars.omega,vz-x*FCVars.omega, - t, FCVars); /* dX'(t)/dt slope at current position*/ + vxp1 = FC_xrot (vx + z * FCVars.omega, vz - x * FCVars.omega, t, FCVars); /* dX'(t)/dt slope at current position*/ - vxp2= FC_xrot (vx+(z+vz*dt)*FCVars.omega,vz-(x+vx*dt)*FCVars.omega, - t+dt,FCVars); /* dX'(t+dt)/dt slope at slit exit */ + vxp2 = FC_xrot (vx + (z + vz * dt) * FCVars.omega, vz - (x + vx * dt) * FCVars.omega, t + dt, FCVars); /* dX'(t+dt)/dt slope at slit exit */ /* absolute time at tangent intersection, changed to time shift below */ - dt_to_tangent = (vxp1 - vxp2 ? (xp2 - xp1 - dt*vxp2)/(vxp1 - vxp2) : -1); + dt_to_tangent = (vxp1 - vxp2 ? (xp2 - xp1 - dt * vxp2) / (vxp1 - vxp2) : -1); /* If algorithm fails, take the middle of the interval*/ if (dt_to_tangent < 0 || dt_to_tangent > dt) { if (verbose > 1) - printf("FermiChopper: %s: WARNING could not determine tangent intersection dt=%g. Using middle.\n", - NAME_CURRENT_COMP, dt_to_tangent); - dt_to_tangent=dt*0.5; + printf ("FermiChopper: %s: WARNING could not determine tangent intersection dt=%g. Using middle.\n", NAME_CURRENT_COMP, dt_to_tangent); + dt_to_tangent = dt * 0.5; } /* @@ -641,403 +645,380 @@ SCATTER; */ /* point coordinates at tangent intersection/middle point (max deviation from optical axis) */ - xp3 = FC_xzrot_dt(x,z,vx,vz, t, dt_to_tangent, 'x', FCVars); /* X'(t+dt_to_tangent) */ + xp3 = FC_xzrot_dt (x, z, vx, vz, t, dt_to_tangent, 'x', FCVars); /* X'(t+dt_to_tangent) */ /* slit index at the tangent intersection/middle point */ - n3 = floor(xp3/w); + n3 = floor (xp3 / w); if (verbose > 2) - printf("FermiChopper: %s: t3=%8.3g slit_indices=[%g %g %g] (time at tangent intersection).\n", - NAME_CURRENT_COMP, dt_to_tangent, n1, n2, n3); + printf ("FermiChopper: %s: t3=%8.3g slit_indices=[%g %g %g] (time at tangent intersection).\n", NAME_CURRENT_COMP, dt_to_tangent, n1, n2, n3); /* change slit means there is a reflection/intersection inside */ - if ( n2!=n1 || n3!=n1 ) { + if (n2 != n1 || n3 != n1) { double t3a, t3b, distance_Wa, distance_Wb; if (m <= 0 || R0 <= 0 || Qc <= 0) { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron hits absorbing coating (change slit).\n", - NAME_CURRENT_COMP); - #pragma acc atomic + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron hits absorbing coating (change slit).\n", NAME_CURRENT_COMP); + #pragma acc atomic FCVars.absorb_slitcoating = FCVars.absorb_slitcoating + 1; - ABSORB; + ABSORB; } /* Choosing the first time it isn't in the slit anymore */ - if(n2 == n1 && n3 != n1){ + if (n2 == n1 && n3 != n1) { n2 = n3; } /* get position of slit wall towards which neutron is propagating */ - if (n2 > n1) { /* X' positive side of slit is in principle the first intersection to test*/ - distance_Wa = n1*w+w; - distance_Wb = n1*w; - } else { /* X' negative side of slit */ - distance_Wb = n1*w+w; - distance_Wa = n1*w; + if (n2 > n1) { /* X' positive side of slit is in principle the first intersection to test*/ + distance_Wa = n1 * w + w; + distance_Wb = n1 * w; + } else { /* X' negative side of slit */ + distance_Wb = n1 * w + w; + distance_Wa = n1 * w; } /* time shift to reach slit wall point in [0,dt_to_tangent]: X'=distance_W slit_wall */ - for (i=0; i< 2; i++) { + for (i = 0; i < 2; i++) { /* first attempt: [0,dt_to_tangent] (to max deviation location) second attempt: [0, dt] (to slit exit) */ double dt_search = (i == 0 ? dt_to_tangent : dt); - t3a = FC_xintersect(x,z,vx,vz, t,dt_to_tangent, distance_Wa, FCVars); - t3b = FC_xintersect(x,z,vx,vz, t,dt_to_tangent, distance_Wb, FCVars); - if (t3b < 0) t3 = t3a; - else if (t3a < 0 && t3b >= 0) t3 = t3b; - else t3 = (t3a < t3b ? t3a : t3b); + t3a = FC_xintersect (x, z, vx, vz, t, dt_to_tangent, distance_Wa, FCVars); + t3b = FC_xintersect (x, z, vx, vz, t, dt_to_tangent, distance_Wb, FCVars); + if (t3b < 0) + t3 = t3a; + else if (t3a < 0 && t3b >= 0) + t3 = t3b; + else + t3 = (t3a < t3b ? t3a : t3b); if (FermiChopper_TimeAccuracy < t3 && t3 < dt_search) break; /* we found the intersection location */ } /* handle case where intersection search fails */ if (t3 < FermiChopper_TimeAccuracy || t3 >= dt_to_tangent) { if (verbose > 1 && FCVars.warn_notreachslitwall < FermiChopper_MAXITER) { - printf("FermiChopper: %s: Can not reach slit wall (iteration %i). dt=%8.3g t3=%8.3g (intersection:3).\n", - NAME_CURRENT_COMP, loopcounter, dt_to_tangent, t3); + printf ("FermiChopper: %s: Can not reach slit wall (iteration %i). dt=%8.3g t3=%8.3g (intersection:3).\n", NAME_CURRENT_COMP, loopcounter, + dt_to_tangent, t3); if (t3 == -3) - printf(" No sign change to determine intersection\n"); + printf (" No sign change to determine intersection\n"); else if (t3 == -2) - printf(" Max iterations reached\n"); + printf (" Max iterations reached\n"); else if (t3 < 0 || t3 >= dt_to_tangent) - printf(" Error when solving intersection\n"); + printf (" Error when solving intersection\n"); } /* neutron can not reach slit wall. */ - #pragma acc atomic + #pragma acc atomic FCVars.warn_notreachslitwall = FCVars.warn_notreachslitwall + 1; ABSORB; } /* Propagate to slit wall point (t+t3) on slit n3 wall */ - PROP_DT(t3); dt -= t3; /* dt: time remaining to slit exit after propagation */ - xp1 = FC_xrot(x,z, t, FCVars); /* X'(t+t3) : on slit wall */ - zp1 = FC_zrot(x,z, t, FCVars); /* Z'(t+t3) : on slit wall */ - X[2] = xp1; Z[2] = zp1; + PROP_DT (t3); + dt -= t3; /* dt: time remaining to slit exit after propagation */ + xp1 = FC_xrot (x, z, t, FCVars); /* X'(t+t3) : on slit wall */ + zp1 = FC_zrot (x, z, t, FCVars); /* Z'(t+t3) : on slit wall */ + X[2] = xp1; + Z[2] = zp1; if (verbose > 2) - printf("FermiChopper: %s: PROP_DT t3=%8.3g dt=%8.3g xyz=[%8.3g %8.3g %8.3g] (on wall). z'=%g\n", - NAME_CURRENT_COMP, t3, dt, x,y,z, zp1); + printf ("FermiChopper: %s: PROP_DT t3=%8.3g dt=%8.3g xyz=[%8.3g %8.3g %8.3g] (on wall). z'=%g\n", NAME_CURRENT_COMP, t3, dt, x, y, z, zp1); /* check if intersection point is still in the slit package, else exit loop */ - if (fabs(zp1) > length/2 || dt <= 0) { + if (fabs (zp1) > length / 2 || dt <= 0) { if (verbose > 2) - printf("FermiChopper: %s: Neutron is outside slit pack (on slit wall).\n", - NAME_CURRENT_COMP); + printf ("FermiChopper: %s: Neutron is outside slit pack (on slit wall).\n", NAME_CURRENT_COMP); break; } - /* here - |---o-----| - | / \ | - |/ \ | - | \ |(dt) - |---------| - */ + /* here + |---o-----| + | / \ | + |/ \ | + | \ |(dt) + |---------| + */ /* get velocity in rotating frame, on slit wall */ - vxp1 = FC_xrot(vx,vz, t, FCVars); - vzp1 = FC_zrot(vx,vz, t, FCVars); + vxp1 = FC_xrot (vx, vz, t, FCVars); + vzp1 = FC_zrot (vx, vz, t, FCVars); - q = 2*V2Q*(fabs(vxp1)); + q = 2 * V2Q * (fabs (vxp1)); { /* double ref = 0; - double par[] = {R0, Qc, alpha, m, W};*/ - StdReflecFunc(q, par, &ref); - if (ref>0) p *= ref; + double par[] = {R0, Qc, alpha, m, W};*/ + StdReflecFunc (q, par, &ref); + if (ref > 0) + p *= ref; else { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron hits absorbing coating (on slit wall).\n", - NAME_CURRENT_COMP); + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron hits absorbing coating (on slit wall).\n", NAME_CURRENT_COMP); #pragma acc atomic FCVars.absorb_slitcoating = FCVars.absorb_slitcoating + 1; - ABSORB; + ABSORB; } /* Cutoff ~ 1E-10 */ } -#ifndef OPENACC + #ifndef OPENACC if (mcdotrace) { - double xp2 = x; double zp2 = z; + double xp2 = x; + double zp2 = z; /* indicate position of neutron in mcdisplay */ - x = FC_xrot(x,z, t,FCVars); z= FC_zrot(x,z, t,FCVars); SCATTER; x=xp2; z=zp2; - } else -#endif - SCATTER; + x = FC_xrot (x, z, t, FCVars); + z = FC_zrot (x, z, t, FCVars); + SCATTER; + x = xp2; + z = zp2; + } else + #endif + SCATTER; /* reflect perpendicular velocity and compute new velocity in static frame */ vxp1 *= -1; /* apply transposed Transformation matrix */ - vx = FC_xrot( vxp1,-vzp1, t,FCVars); - vz = FC_zrot(-vxp1, vzp1, t,FCVars); + vx = FC_xrot (vxp1, -vzp1, t, FCVars); + vz = FC_zrot (-vxp1, vzp1, t, FCVars); /* recompute time to slit exit */ /* solve Z'=-slit_input for time of exit of slit package */ - t3 = FC_zintersect(x,z,vx,vz, t,dt, -slit_input, FCVars); + t3 = FC_zintersect (x, z, vx, vz, t, dt, -slit_input, FCVars); - if(t3 < 0 || t3 > dt) { + if (t3 < 0 || t3 > dt) { if (verbose > 1 && FCVars.warn_notreachslitoutput < FermiChopper_MAXITER) { - printf("FermiChopper: %s: Can not reach exit of slits. dt=%8.3g t3=%8.3g (intersection:4).\n", - NAME_CURRENT_COMP, dt, t3); + printf ("FermiChopper: %s: Can not reach exit of slits. dt=%8.3g t3=%8.3g (intersection:4).\n", NAME_CURRENT_COMP, dt, t3); if (t3 == -3) - printf(" No sign change to determine intersection\n"); + printf (" No sign change to determine intersection\n"); else if (t3 == -2) - printf(" Max iterations reached\n"); + printf (" Max iterations reached\n"); else if (t3 < 0) - printf(" Error when solving intersection\n"); + printf (" Error when solving intersection\n"); } - #pragma acc atomic + #pragma acc atomic FCVars.warn_notreachslitoutput = FCVars.warn_notreachslitoutput + 1; ABSORB; /* neutron can not reach slit output. */ - } else dt = t3; /* reduce time interval to [0, time of slit exit] */ + } else + dt = t3; /* reduce time interval to [0, time of slit exit] */ } /* end if changed slit index */ else { /* neutron remains in the same slit: direct flight */ - if (dt > 0) PROP_DT(dt); /* go to slit exit */ + if (dt > 0) + PROP_DT (dt); /* go to slit exit */ break; } } /* end for */ - xp1 = FC_xrot(x,z, t,FCVars); - zp1 = FC_zrot(x,z, t,FCVars); - X[3] = xp1; Z[3] = zp1; /* slit exit */ + xp1 = FC_xrot (x, z, t, FCVars); + zp1 = FC_zrot (x, z, t, FCVars); + X[3] = xp1; + Z[3] = zp1; /* slit exit */ - if (fabs(xp1) >= nslit*w/2) - { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron X is outside slit package, x'=%8.3g (slit exit).\n", - NAME_CURRENT_COMP, xp1); + if (fabs (xp1) >= nslit * w / 2) { + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron X is outside slit package, x'=%8.3g (slit exit).\n", NAME_CURRENT_COMP, xp1); #pragma acc atomic FCVars.absorb_slitcoating = FCVars.absorb_slitcoating + 1; ABSORB; } - if (loopcounter >= FermiChopper_MAXITER) - { + if (loopcounter >= FermiChopper_MAXITER) { if (verbose > 1 && FCVars.absorb_maxiterations < FermiChopper_MAXITER) - printf("FermiChopper: %s: Max iterations %i reached inside slit. Absorb.\n", - NAME_CURRENT_COMP, FermiChopper_MAXITER); + printf ("FermiChopper: %s: Max iterations %i reached inside slit. Absorb.\n", NAME_CURRENT_COMP, FermiChopper_MAXITER); #pragma acc atomic - FCVars.absorb_maxiterations = FCVars.absorb_maxiterations + 1; + FCVars.absorb_maxiterations = FCVars.absorb_maxiterations + 1; ABSORB; } - /********************* EXIT SLIT PACKAGE ********************************/ /* propagation times to cylinder. Should use t2 to exit */ if (!cylinder_intersect (&t1, &t2, x, y, z, vx, vy, vz, radius, yheight)) { /* must be inside the cylinder */ - if (verbose > 1) printf("FermiChopper: %s: ABSORB Neutron has unexpectidely exited cylinder ! (exiting)\n", - NAME_CURRENT_COMP); + if (verbose > 1) + printf ("FermiChopper: %s: ABSORB Neutron has unexpectidely exited cylinder ! (exiting)\n", NAME_CURRENT_COMP); #pragma acc atomic FCVars.absorb_exitslitpack = FCVars.absorb_exitslitpack + 1; ABSORB; } - if (t1 > 0) - { + if (t1 > 0) { if (verbose > 1 && FCVars.absorb_wrongdirection < FermiChopper_MAXITER) - printf("FermiChopper: %s: Neutrons are leaving chopper\n" - " in the wrong direction. Absorb.\n", NAME_CURRENT_COMP); + printf ("FermiChopper: %s: Neutrons are leaving chopper\n" + " in the wrong direction. Absorb.\n", + NAME_CURRENT_COMP); #pragma acc atomic FCVars.absorb_wrongdirection = FCVars.absorb_wrongdirection + 1; ABSORB; } - if (t2 <= 0 && FCVars.absorb_nocontrol < FermiChopper_MAXITER) - { + if (t2 <= 0 && FCVars.absorb_nocontrol < FermiChopper_MAXITER) { if (verbose > 1) - printf("FermiChopper: %s: Neutrons are leaving chopper\n" - " without any control. Absorb.\n", NAME_CURRENT_COMP); + printf ("FermiChopper: %s: Neutrons are leaving chopper\n" + " without any control. Absorb.\n", + NAME_CURRENT_COMP); #pragma acc atomic FCVars.absorb_nocontrol = FCVars.absorb_nocontrol + 1; ABSORB; } /* propagate to cylinder surface (exit) */ - PROP_DT(t2); + PROP_DT (t2); SCATTER; - xp1 = FC_xrot(x,z, t,FCVars); - zp1 = FC_zrot(x,z, t,FCVars); - X[4] = xp1; Z[4] = zp1; + xp1 = FC_xrot (x, z, t, FCVars); + zp1 = FC_zrot (x, z, t, FCVars); + X[4] = xp1; + Z[4] = zp1; if (verbose > 2) - printf("FermiChopper: %s: t1=%8.3g PROP_DT t2=%8.3g xyz=[%8.3g %8.3g %8.3g] (OUT cyl). z'=%g\n", - NAME_CURRENT_COMP, t1, t2, x,y,z, zp1); + printf ("FermiChopper: %s: t1=%8.3g PROP_DT t2=%8.3g xyz=[%8.3g %8.3g %8.3g] (OUT cyl). z'=%g\n", NAME_CURRENT_COMP, t1, t2, x, y, z, zp1); /* Check if the neutron left the cylinder by its top or bottom */ - if (fabs(y) >= yheight/2) - { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron hits top/bottom of cylinder, y=%8.3g (exiting)\n", - NAME_CURRENT_COMP, y); + if (fabs (y) >= yheight / 2) { + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron hits top/bottom of cylinder, y=%8.3g (exiting)\n", NAME_CURRENT_COMP, y); #pragma acc atomic FCVars.absorb_topbottom = FCVars.absorb_topbottom + 1; ABSORB; } /* must have X'< slit package width at package Z'=cylinder output */ - if (fabs(xp1) >= nslit*w/2) - { - if (verbose > 2) printf("FermiChopper: %s: ABSORB Neutron X is outside slit package cylinder, xp1=%8.3g (exiting).\n", - NAME_CURRENT_COMP, xp1); + if (fabs (xp1) >= nslit * w / 2) { + if (verbose > 2) + printf ("FermiChopper: %s: ABSORB Neutron X is outside slit package cylinder, xp1=%8.3g (exiting).\n", NAME_CURRENT_COMP, xp1); #pragma acc atomic FCVars.absorb_cylexit = FCVars.absorb_cylexit + 1; ABSORB; } /* Transmission coefficent */ - p = p*eff; //finite cross section + transmission + p = p * eff; // finite cross section + transmission #pragma acc atomic FCVars.sum_N_pass = FCVars.sum_N_pass + p; } /* end if cylinder_intersect */ - %} SAVE %{ - double mean_k, mean_v, mean_t, mean_w=0, mean_L=0; + double mean_k, mean_v, mean_t, mean_w = 0, mean_L = 0; if (FCVars.sum_N) { - mean_v = FCVars.sum_v/FCVars.sum_N; - mean_t = FCVars.sum_t/FCVars.sum_N; - mean_k = V2K*mean_v; - if (mean_k) mean_L = 2*PI/mean_k; - mean_w = VS2E*mean_v*mean_v; + mean_v = FCVars.sum_v / FCVars.sum_N; + mean_t = FCVars.sum_t / FCVars.sum_N; + mean_k = V2K * mean_v; + if (mean_k) + mean_L = 2 * PI / mean_k; + mean_w = VS2E * mean_v * mean_v; /* base opening time */ double div, mean_phase; - div = atan2(w,length)/PI*180; - mean_phase = fmod(mean_t*nu*360, 360); - mean_phase+=radius/mean_v*360*nu; - if (mean_phase > 180) mean_phase -= 360; + div = atan2 (w, length) / PI * 180; + mean_phase = fmod (mean_t * nu * 360, 360); + mean_phase += radius / mean_v * 360 * nu; + if (mean_phase > 180) + mean_phase -= 360; if (!FCVars.sum_N_pass) - printf("FermiChopper: %s: No neutron can pass the chopper.\n", NAME_CURRENT_COMP); + printf ("FermiChopper: %s: No neutron can pass the chopper.\n", NAME_CURRENT_COMP); if (!FCVars.sum_N_pass || verbose) - printf("FermiChopper: %s\n" - " Mean velocity v = %g [m/s]\n" - " Mean wavelength lambda= %g [Angs]\n" - " Mean energy omega = %g [meV]\n" - " Mean arrival time t = %g [s]\n" - " Mean phase = %g [deg] (%s)\n" - " Slit pack divergence = %g [deg] (full width)\n" - " Opening time dt = %g [s]\n" - " Intensity reaching FC = %g [n/s]\n" - " Intensity passing FC = %g [n/s]\n" - , NAME_CURRENT_COMP, - mean_v, mean_L, mean_w, mean_t, mean_phase, - (zero_time > 1 ? "set automatically" : "use phase=-(this value) to optimize"), - 2*div, - (nu ? fabs(div/PI/nu) : 1), - FCVars.sum_N, - FCVars.sum_N_pass); + printf ("FermiChopper: %s\n" + " Mean velocity v = %g [m/s]\n" + " Mean wavelength lambda= %g [Angs]\n" + " Mean energy omega = %g [meV]\n" + " Mean arrival time t = %g [s]\n" + " Mean phase = %g [deg] (%s)\n" + " Slit pack divergence = %g [deg] (full width)\n" + " Opening time dt = %g [s]\n" + " Intensity reaching FC = %g [n/s]\n" + " Intensity passing FC = %g [n/s]\n", + NAME_CURRENT_COMP, mean_v, mean_L, mean_w, mean_t, mean_phase, (zero_time > 1 ? "set automatically" : "use phase=-(this value) to optimize"), + 2 * div, (nu ? fabs (div / PI / nu) : 1), FCVars.sum_N, FCVars.sum_N_pass); if (!FCVars.sum_N_pass || verbose) { - printf("FermiChopper: %s: Lost events anaylsis\n" - " Already inside: %li\n" - " By Top/Bottom of cylinder: %li\n" - " At cylinder entrance: %li\n" - " Hit cyl. entrance sides: %li\n" - " Can't prop. to slit pack: %li\n" - " At slit pack entrance: %li\n" - " On absorbing slit coating: %li\n" - " Exiting slit pack: %li\n" - " Too many iterations: %li\n" - " Prop. in wrong direction : %li\n" - " Mad neutron (no control): %li\n" - " At cylinder exit: %li\n" - , NAME_CURRENT_COMP, - FCVars.absorb_alreadyinside, - FCVars.absorb_topbottom, - FCVars.absorb_cylentrance, - FCVars.absorb_sideentrance, - FCVars.absorb_notreachentrance, - FCVars.absorb_packentrance, - FCVars.absorb_slitcoating, - - FCVars.absorb_exitslitpack, - FCVars.absorb_maxiterations, - FCVars.absorb_wrongdirection, - FCVars.absorb_nocontrol, - FCVars.absorb_cylexit); + printf ("FermiChopper: %s: Lost events anaylsis\n" + " Already inside: %li\n" + " By Top/Bottom of cylinder: %li\n" + " At cylinder entrance: %li\n" + " Hit cyl. entrance sides: %li\n" + " Can't prop. to slit pack: %li\n" + " At slit pack entrance: %li\n" + " On absorbing slit coating: %li\n" + " Exiting slit pack: %li\n" + " Too many iterations: %li\n" + " Prop. in wrong direction : %li\n" + " Mad neutron (no control): %li\n" + " At cylinder exit: %li\n", + NAME_CURRENT_COMP, FCVars.absorb_alreadyinside, FCVars.absorb_topbottom, FCVars.absorb_cylentrance, FCVars.absorb_sideentrance, + FCVars.absorb_notreachentrance, FCVars.absorb_packentrance, FCVars.absorb_slitcoating, + + FCVars.absorb_exitslitpack, FCVars.absorb_maxiterations, FCVars.absorb_wrongdirection, FCVars.absorb_nocontrol, FCVars.absorb_cylexit); if (FCVars.warn_notreachslitwall || FCVars.warn_notreachslitoutput) - printf("Warning: Can not reach slit wall: %li\n" - "Warning: Can not reach slit output: %li\n", - FCVars.warn_notreachslitwall, - FCVars.warn_notreachslitoutput); + printf ("Warning: Can not reach slit wall: %li\n" + "Warning: Can not reach slit output: %li\n", + FCVars.warn_notreachslitwall, FCVars.warn_notreachslitoutput); } } else { - printf("FermiChopper: %s: No neutron can reach the chopper.\n", NAME_CURRENT_COMP); + printf ("FermiChopper: %s: No neutron can reach the chopper.\n", NAME_CURRENT_COMP); } %} MCDISPLAY %{ - double index_x=0; - double index_z=0; + double index_x = 0; + double index_z = 0; double xpos, zpos; - double Nz,Nx; - double ymin=-yheight/2.0; - double ymax= yheight/2.0; + double Nz, Nx; + double ymin = -yheight / 2.0; + double ymax = yheight / 2.0; - double omega=FCVars.omega; - FCVars.omega=0; + double omega = FCVars.omega; + FCVars.omega = 0; // FCVars.ph0 =0; - Nz = (FCVars.C_slit ? 4 : 1); - Nx = (nslit > 11 ? 11 : nslit); + Nz = (FCVars.C_slit ? 4 : 1); + Nx = (nslit > 11 ? 11 : nslit); FCVars.C_slit *= -1; - + /* cylinder top/center/bottom */ - circle("xz", 0,ymax,0,radius); - circle("xz", 0,0 ,0,radius); - circle("xz", 0,ymin,0,radius); + circle ("xz", 0, ymax, 0, radius); + circle ("xz", 0, 0, 0, radius); + circle ("xz", 0, ymin, 0, radius); /* vertical lines to make a kind of volume */ - line( 0 ,ymin,-radius, 0 ,ymax,-radius); - line( 0 ,ymin, radius, 0 ,ymax, radius); - line(-radius,ymin, 0 ,-radius,ymax, 0 ); - line( radius,ymin, 0 , radius,ymax, 0 ); + line (0, ymin, -radius, 0, ymax, -radius); + line (0, ymin, radius, 0, ymax, radius); + line (-radius, ymin, 0, -radius, ymax, 0); + line (radius, ymin, 0, radius, ymax, 0); /* slit package */ - for (index_x = -Nx/2; index_x < Nx/2; index_x++) { - for (index_z = -Nz/2; index_z < Nz/2; index_z++) { + for (index_x = -Nx / 2; index_x < Nx / 2; index_x++) { + for (index_z = -Nz / 2; index_z < Nz / 2; index_z++) { double xs1, zs1, zs2; double xp1, xp2, zp1, zp2; - zs1 = length*index_z/Nz; - zs2 = length*(index_z+1)/Nz; - xs1 = w*nslit*index_x/Nx; - xp1 = FC_xrot(xs1, zs1, 0, FCVars); - xp2 = FC_xrot(xs1, zs2, 0, FCVars); - zp1 = FC_zrot(xs1, zs1, 0, FCVars); - zp2 = FC_zrot(xs1, zs2, 0, FCVars); - multiline(5, xp1, ymin, zp1, - xp1, ymax, zp1, - xp2, ymax, zp2, - xp2, ymin, zp2, - xp1, ymin, zp1); + zs1 = length * index_z / Nz; + zs2 = length * (index_z + 1) / Nz; + xs1 = w * nslit * index_x / Nx; + xp1 = FC_xrot (xs1, zs1, 0, FCVars); + xp2 = FC_xrot (xs1, zs2, 0, FCVars); + zp1 = FC_zrot (xs1, zs1, 0, FCVars); + zp2 = FC_zrot (xs1, zs2, 0, FCVars); + multiline (5, xp1, ymin, zp1, xp1, ymax, zp1, xp2, ymax, zp2, xp2, ymin, zp2, xp1, ymin, zp1); } } /* cylinder inner sides containing slit package */ double xp1, xp2, zp1, zp2; - xpos = nslit*w/2; - zpos = sqrt(radius*radius - xpos*xpos); - xp1 = FC_xrot(xpos, -zpos, 0, FCVars); - xp2 = FC_xrot(xpos, +zpos, 0, FCVars); - zp1 = FC_zrot(xpos, -zpos, 0, FCVars); - zp2 = FC_zrot(xpos, +zpos, 0, FCVars); - multiline(5, xp1, ymin, zp1, - xp1, ymax, zp1, - xp2, ymax, zp2, - xp2, ymin, zp2, - xp1, ymin, zp1); + xpos = nslit * w / 2; + zpos = sqrt (radius * radius - xpos * xpos); + xp1 = FC_xrot (xpos, -zpos, 0, FCVars); + xp2 = FC_xrot (xpos, +zpos, 0, FCVars); + zp1 = FC_zrot (xpos, -zpos, 0, FCVars); + zp2 = FC_zrot (xpos, +zpos, 0, FCVars); + multiline (5, xp1, ymin, zp1, xp1, ymax, zp1, xp2, ymax, zp2, xp2, ymin, zp2, xp1, ymin, zp1); xpos *= -1; - xp1 = FC_xrot(xpos, -zpos, 0, FCVars); - xp2 = FC_xrot(xpos, +zpos, 0, FCVars); - zp1 = FC_zrot(xpos, -zpos, 0, FCVars); - zp2 = FC_zrot(xpos, +zpos, 0, FCVars); - multiline(5, xp1, ymin, zp1, - xp1, ymax, zp1, - xp2, ymax, zp2, - xp2, ymin, zp2, - xp1, ymin, zp1); - FCVars.omega=omega; + xp1 = FC_xrot (xpos, -zpos, 0, FCVars); + xp2 = FC_xrot (xpos, +zpos, 0, FCVars); + zp1 = FC_zrot (xpos, -zpos, 0, FCVars); + zp2 = FC_zrot (xpos, +zpos, 0, FCVars); + multiline (5, xp1, ymin, zp1, xp1, ymax, zp1, xp2, ymax, zp2, xp2, ymin, zp2, xp1, ymin, zp1); + FCVars.omega = omega; %} END diff --git a/mcstas-comps/optics/Filter_gen.comp b/mcstas-comps/optics/Filter_gen.comp index 9d66b7cbde..33d2ba6486 100644 --- a/mcstas-comps/optics/Filter_gen.comp +++ b/mcstas-comps/optics/Filter_gen.comp @@ -80,7 +80,7 @@ SETTING PARAMETERS (string filename=0, string options=0, xmin=-0.05, xmax=0.05, SHARE %{ -#ifndef FILTER_GEN + #ifndef FILTER_GEN #define FILTER_GEN $Revision$ #define UNKNOWN_TABLE 0 #define ENERGY_TABLE 1 @@ -90,33 +90,39 @@ SHARE #define FLUX_ADAPT_MULT 1 #define FLUX_ADAPT_ADD 2 - char FilterGen_Mode(char *str, char *Mode, char *Type, double *verbose) - { + char + FilterGen_Mode (char* str, char* Mode, char* Type, double* verbose) { long i; - char *c; - if (!str || !strlen(str)) return(0); - c = malloc(strlen(str)); + char* c; + if (!str || !strlen (str)) + return (0); + c = malloc (strlen (str)); if (!c) { - fprintf(stderr,"Filter_Gen: malloc error in FilterGen_Mode. Exit!\n"); - exit(-1); + fprintf (stderr, "Filter_Gen: malloc error in FilterGen_Mode. Exit!\n"); + exit (-1); } - for (i=0; i 0) { xmax = xwidth/2; xmin = -xmax; } - if (yheight > 0) { ymax = yheight/2; ymin = -ymax; } + if (xwidth > 0) { + xmax = xwidth / 2; + xmin = -xmax; + } + if (yheight > 0) { + ymax = yheight / 2; + ymin = -ymax; + } - FilterGen_Mode(options, &Mode_Table, &Type_Table, &verbose); + FilterGen_Mode (options, &Mode_Table, &Type_Table, &verbose); - if (filename != NULL && strlen(filename) && strcmp(filename,"NULL") && strcmp(filename,"0")) - { - if (Table_Read(&pTable, filename, 1) <= 0) /* read 1st block data from filename into pTable */ - exit(fprintf(stderr,"Filter_gen: %s: can not read filename %s\n", NAME_CURRENT_COMP, filename)); + if (filename != NULL && strlen (filename) && strcmp (filename, "NULL") && strcmp (filename, "0")) { + if (Table_Read (&pTable, filename, 1) <= 0) /* read 1st block data from filename into pTable */ + exit (fprintf (stderr, "Filter_gen: %s: can not read filename %s\n", NAME_CURRENT_COMP, filename)); - Table_Rebin(&pTable); /* rebin as evenly, increasing array */ + Table_Rebin (&pTable); /* rebin as evenly, increasing array */ if (pTable.rows < 2 || !pTable.step_x) { - Table_Free(&pTable); + Table_Free (&pTable); } - if (pTable.data) - { - FilterGen_Mode(pTable.header, &Mode_Table, &Type_Table, &verbose); - if (verbose) - { - Table_Info(pTable); - printf("Filter_gen: %s: Filter data [", NAME_CURRENT_COMP); - if (Type_Table == ENERGY_TABLE) printf("Energy"); - if (Type_Table == WAVEVECTOR_TABLE) printf("Wavevector"); - if (Type_Table == WAVELENGTH_TABLE) printf("Wavelength"); - if (Type_Table == UNKNOWN_TABLE) printf("UNKNOWN (not used)"); - printf(", Flux] in "); - if (Mode_Table == FLUX_ADAPT_MULT) printf("multiply"); - else if (Mode_Table == FLUX_ADAPT_ADD) printf("add"); - else printf("set"); - printf(" mode\n"); + if (pTable.data) { + FilterGen_Mode (pTable.header, &Mode_Table, &Type_Table, &verbose); + if (verbose) { + Table_Info (pTable); + printf ("Filter_gen: %s: Filter data [", NAME_CURRENT_COMP); + if (Type_Table == ENERGY_TABLE) + printf ("Energy"); + if (Type_Table == WAVEVECTOR_TABLE) + printf ("Wavevector"); + if (Type_Table == WAVELENGTH_TABLE) + printf ("Wavelength"); + if (Type_Table == UNKNOWN_TABLE) + printf ("UNKNOWN (not used)"); + printf (", Flux] in "); + if (Mode_Table == FLUX_ADAPT_MULT) + printf ("multiply"); + else if (Mode_Table == FLUX_ADAPT_ADD) + printf ("add"); + else + printf ("set"); + printf (" mode\n"); } - } else fprintf(stderr,"Filter_gen: %s: file %s contains no data.\n", NAME_CURRENT_COMP, filename); + } else + fprintf (stderr, "Filter_gen: %s: file %s contains no data.\n", NAME_CURRENT_COMP, filename); - } else pTable.data = NULL; + } else + pTable.data = NULL; %} TRACE @@ -172,50 +190,50 @@ TRACE double v2, K, L, E, X, new_p; PROP_Z0; - if (Type_Table && (x>xmin && xymin && y xmin && x < xmax && y > ymin && y < ymax)) { + v2 = (vx * vx + vy * vy + vz * vz); + K = V2K * sqrt (v2); /* k */ + L = (2 * PI / K); /* lambda */ + E = VS2E * v2; /* energy */ + if (Type_Table == ENERGY_TABLE) + X = E; + if (Type_Table == WAVEVECTOR_TABLE) + X = K; + if (Type_Table == WAVELENGTH_TABLE) + X = L; /* table look up */ - if (pTable.data != NULL) - { + if (pTable.data != NULL) { double y1, y2, x1; - long Index; - Index = floor((X - pTable.min_x)/pTable.step_x); - y1 = Table_Index(pTable, Index, 1); /* 2nd column */ - x1 = Table_Index(pTable, Index, 0); /* 1st column */ - y2 = Table_Index(pTable, Index+1, 1); /* 2nd column */ - new_p = scaling*(y1+(X - x1)*(y2-y1)/pTable.step_x); /* 2nd column */ - if (thickness != 1) new_p = pow(new_p, thickness); - } - else new_p = 1; - - if (Mode_Table == FLUX_ADAPT_MULT) p *= new_p; - else p = new_p; + long Index; + Index = floor ((X - pTable.min_x) / pTable.step_x); + y1 = Table_Index (pTable, Index, 1); /* 2nd column */ + x1 = Table_Index (pTable, Index, 0); /* 1st column */ + y2 = Table_Index (pTable, Index + 1, 1); /* 2nd column */ + new_p = scaling * (y1 + (X - x1) * (y2 - y1) / pTable.step_x); /* 2nd column */ + if (thickness != 1) + new_p = pow (new_p, thickness); + } else + new_p = 1; + + if (Mode_Table == FLUX_ADAPT_MULT) + p *= new_p; + else + p = new_p; SCATTER; - } - else - if (Type_Table) ABSORB; + } else if (Type_Table) + ABSORB; %} FINALLY %{ - Table_Free(&pTable); + Table_Free (&pTable); %} MCDISPLAY %{ - - multiline(5, (double)xmin, (double)ymin, 0.0, - (double)xmax, (double)ymin, 0.0, - (double)xmax, (double)ymax, 0.0, - (double)xmin, (double)ymax, 0.0, - (double)xmin, (double)ymin, 0.0); + + multiline (5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, + (double)ymin, 0.0); %} END diff --git a/mcstas-comps/optics/Guide.comp b/mcstas-comps/optics/Guide.comp index f095da2b53..2dd279cafb 100644 --- a/mcstas-comps/optics/Guide.comp +++ b/mcstas-comps/optics/Guide.comp @@ -66,46 +66,51 @@ SHARE DECLARE %{ -t_Table pTable; -int table_present; + t_Table pTable; + int table_present; %} INITIALIZE %{ -if (mcgravitation) fprintf(stderr,"WARNING: Guide: %s: " - "This component produces wrong results with gravitation !\n" - "Use Guide_gravity.\n", - NAME_CURRENT_COMP); + if (mcgravitation) + fprintf (stderr, + "WARNING: Guide: %s: " + "This component produces wrong results with gravitation !\n" + "Use Guide_gravity.\n", + NAME_CURRENT_COMP); - if (!w2) w2=w1; - if (!h2) h2=h1; + if (!w2) + w2 = w1; + if (!h2) + h2 = h1; - if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) { - if (Table_Read(&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ - exit(fprintf(stderr,"Guide: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); - table_present=1; + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) { + if (Table_Read (&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ + exit (fprintf (stderr, "Guide: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); + table_present = 1; } else { - table_present=0; - if (W < 0 || R0 < 0 || Qc < 0 || m < 0) - { fprintf(stderr,"Guide: %s: W R0 Qc must be >0.\n", NAME_CURRENT_COMP); - exit(-1); } + table_present = 0; + if (W < 0 || R0 < 0 || Qc < 0 || m < 0) { + fprintf (stderr, "Guide: %s: W R0 Qc must be >0.\n", NAME_CURRENT_COMP); + exit (-1); + } } %} TRACE %{ - double t1,t2; /* Intersection times. */ - double av,ah,bv,bh,cv1,cv2,ch1,ch2,d; /* Intermediate values */ - double weight; /* Internal probability weight */ - double vdotn_v1,vdotn_v2,vdotn_h1,vdotn_h2; /* Dot products. */ - int i; /* Which mirror hit? */ - double q; /* Q [1/AA] of reflection */ - double nlen2; /* Vector lengths squared */ - double par[5] = {R0, Qc, alpha, m, W}; - + double t1, t2; /* Intersection times. */ + double av, ah, bv, bh, cv1, cv2, ch1, ch2, d; /* Intermediate values */ + double weight; /* Internal probability weight */ + double vdotn_v1, vdotn_v2, vdotn_h1, vdotn_h2; /* Dot products. */ + int i; /* Which mirror hit? */ + double q; /* Q [1/AA] of reflection */ + double nlen2; /* Vector lengths squared */ + double par[5] = { R0, Qc, alpha, m, W }; + /* ToDo: These could be precalculated. */ - double ww = .5*(w2 - w1), hh = .5*(h2 - h1); - double whalf = .5*w1, hhalf = .5*h1; + double ww = .5 * (w2 - w1), hh = .5 * (h2 - h1); + double whalf = .5 * w1, hhalf = .5 * h1; /* Propagate neutron to guide entrance. */ PROP_Z0; @@ -113,89 +118,88 @@ TRACE absorbed in a GROUP construction, e.g. all neutrons - even the later absorbed ones are scattered at the guide entry. */ SCATTER; - if(x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) + if (x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) ABSORB; - for(;;) - { + 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 */ + 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; + cv1 = -whalf * l - z * ww; + cv2 = x * l; + ch1 = -hhalf * l - z * hh; + ch2 = y * l; /* Compute intersection times. */ - t1 = (l - z)/vz; + t1 = (l - z) / vz; i = 0; - if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) - { + if (vdotn_v1 < 0 && (t2 = (cv1 - cv2) / vdotn_v1) < t1) { t1 = t2; i = 1; } - if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) - { + if (vdotn_v2 < 0 && (t2 = (cv1 + cv2) / vdotn_v2) < t1) { t1 = t2; i = 2; } - if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) - { + if (vdotn_h1 < 0 && (t2 = (ch1 - ch2) / vdotn_h1) < t1) { t1 = t2; i = 3; } - if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) - { + 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; + 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. */ weight = 1.0; /* Initial internal weight factor */ - if(m == 0) + if (m == 0) ABSORB; - if (reflect && table_present==1) - TableReflecFunc(q, &pTable, &weight); + if (reflect && table_present == 1) + TableReflecFunc (q, &pTable, &weight); else { - StdReflecFunc(q, par, &weight); + StdReflecFunc (q, par, &weight); } if (weight > 0) p *= weight; - else ABSORB; + else + ABSORB; SCATTER; } %} @@ -204,35 +208,16 @@ MCDISPLAY %{ /* V3, independent "polygons": */ // TOP - polygon(4, - -w1/2.0, h1/2.0, 0.0, - w1/2.0, h1/2.0, 0.0, - w2/2.0, h2/2.0, (double)l, - -w2/2.0, h2/2.0, (double)l); + polygon (4, -w1 / 2.0, h1 / 2.0, 0.0, w1 / 2.0, h1 / 2.0, 0.0, w2 / 2.0, h2 / 2.0, (double)l, -w2 / 2.0, h2 / 2.0, (double)l); // BOTTOM - polygon(4, - -w1/2.0, -h1/2.0, 0.0, - w1/2.0, -h1/2.0, 0.0, - w2/2.0, -h2/2.0, (double)l, - -w2/2.0, -h2/2.0, (double)l); + polygon (4, -w1 / 2.0, -h1 / 2.0, 0.0, w1 / 2.0, -h1 / 2.0, 0.0, w2 / 2.0, -h2 / 2.0, (double)l, -w2 / 2.0, -h2 / 2.0, (double)l); // RIGHT - polygon(4, - -w1/2.0, h1/2.0, 0.0, - -w1/2.0, -h1/2.0, 0.0, - -w2/2.0, -h2/2.0, (double)l, - -w2/2.0, h2/2.0, (double)l); + polygon (4, -w1 / 2.0, h1 / 2.0, 0.0, -w1 / 2.0, -h1 / 2.0, 0.0, -w2 / 2.0, -h2 / 2.0, (double)l, -w2 / 2.0, h2 / 2.0, (double)l); // LEFT - polygon(4, - w1/2.0, h1/2.0, 0.0, - w1/2.0, -h1/2.0, 0.0, - w2/2.0, -h2/2.0, (double)l, - w2/2.0, h2/2.0, (double)l); - - + polygon (4, w1 / 2.0, h1 / 2.0, 0.0, w1 / 2.0, -h1 / 2.0, 0.0, w2 / 2.0, -h2 / 2.0, (double)l, w2 / 2.0, h2 / 2.0, (double)l); - /* V2, draw top, bottom, sides independently: */ // TOP /* multiline(5, */ @@ -265,9 +250,7 @@ MCDISPLAY /* w2/2.0, h2/2.0, (double)l, */ /* w1/2.0, h1/2.0, 0.0); */ - - - /* Original implementation: + /* Original implementation: multiline(5, -w1/2.0, -h1/2.0, 0.0, w1/2.0, -h1/2.0, 0.0, diff --git a/mcstas-comps/optics/Guide_anyshape.comp b/mcstas-comps/optics/Guide_anyshape.comp index f7b184d65d..04fe3579b0 100644 --- a/mcstas-comps/optics/Guide_anyshape.comp +++ b/mcstas-comps/optics/Guide_anyshape.comp @@ -88,28 +88,29 @@ SHARE DECLARE %{ -off_struct offdata; -t_Table pTable; + off_struct offdata; + t_Table pTable; %} INITIALIZE %{ -/* initialize OFF object from the file(s) */ - if (!off_init( geometry, xwidth, yheight, zdepth, !center, &offdata )) exit(-1); + /* initialize OFF object from the file(s) */ + if (!off_init (geometry, xwidth, yheight, zdepth, !center, &offdata)) + exit (-1); /* optionally initialize reflectivity curves */ - if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) { - if (Table_Read(&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ - exit(fprintf(stderr,"Guide_anyshape: %s: can not read file %s. Aborting.\n", NAME_CURRENT_COMP, reflect)); + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) { + if (Table_Read (&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ + exit (fprintf (stderr, "Guide_anyshape: %s: can not read file %s. Aborting.\n", NAME_CURRENT_COMP, reflect)); else - Table_Rebin(&pTable); /* rebin as evenly, increasing array */ + Table_Rebin (&pTable); /* rebin as evenly, increasing array */ } %} TRACE %{ - int intersect=0; - int counter=0; + int intersect = 0; + int counter = 0; /* main loop for multiple reflections */ #ifdef OPENACC off_struct thread_offdata = offdata; @@ -117,83 +118,92 @@ TRACE #define thread_offdata offdata #endif do { - double t0=0, t3=0, dt=0; - Coords n0, n3, n={0,0,0}; + double t0 = 0, t3 = 0, dt = 0; + Coords n0, n3, n = { 0, 0, 0 }; /* determine intersections with object */ - - double mc_gx=0.0, mc_gy=0.0, mc_gz=0.0; + + double mc_gx = 0.0, mc_gy = 0.0, mc_gz = 0.0; if (mcgravitation) { - Coords locgrav; - locgrav = rot_apply(_comp->_rotation_absolute, coords_set(0,-GRAVITY,0)); - coords_get(locgrav, &mc_gx, &mc_gy, &mc_gz); + Coords locgrav; + locgrav = rot_apply (_comp->_rotation_absolute, coords_set (0, -GRAVITY, 0)); + coords_get (locgrav, &mc_gx, &mc_gy, &mc_gz); } - - intersect = off_intersect(&t0, &t3, &n0, &n3, x,y,z, vx, vy, vz, mc_gx, mc_gy, mc_gz, thread_offdata ); + + intersect = off_intersect (&t0, &t3, &n0, &n3, x, y, z, vx, vy, vz, mc_gx, mc_gy, mc_gz, thread_offdata); /* get the smallest positive */ - if (t0 > 0) { dt = t0; n=n0; } - if (intersect > 1 && dt <= 0 && t3 > dt) { dt = t3; n=n3; } + if (t0 > 0) { + dt = t0; + n = n0; + } + if (intersect > 1 && dt <= 0 && t3 > dt) { + dt = t3; + n = n3; + } /* exit loop when no intersection forward */ - if (dt <= 0 || !intersect) break; + if (dt <= 0 || !intersect) + break; - double nx,ny,nz; - coords_get(n, &nx, &ny, &nz); + double nx, ny, nz; + coords_get (n, &nx, &ny, &nz); /* propagate neutron to reflection point, must be before n_dot_v with gravity */ - PROP_DT(dt); + PROP_DT (dt); /* test if the angle is large in case the object has an internal coating */ - double n2 = nx*nx+ny*ny+nz*nz; - double n_dot_v = scalar_prod(vx,vy,vz,nx,ny,nz); - double q = 2*fabs(n_dot_v)*V2K/sqrt(n2); + double n2 = nx * nx + ny * ny + nz * nz; + double n_dot_v = scalar_prod (vx, vy, vz, nx, ny, nz); + double q = 2 * fabs (n_dot_v) * V2K / sqrt (n2); /* handle surface intersection */ - double R=0; + double R = 0; /* Reflectivity (see component Guide). */ - if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) - TableReflecFunc(q, &pTable, &R); + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) + TableReflecFunc (q, &pTable, &R); else { - double par[] = {R0, Qc, alpha, m, W}; - StdReflecFunc(q, par, &R); + double par[] = { R0, Qc, alpha, m, W }; + StdReflecFunc (q, par, &R); } if (R > 1) { - fprintf(stderr,"Guide_anyshape: %s: Warning: Reflectivity R=%g > 1 lowered to R=1.\n", NAME_CURRENT_COMP, R); - R=1; + fprintf (stderr, "Guide_anyshape: %s: Warning: Reflectivity R=%g > 1 lowered to R=1.\n", NAME_CURRENT_COMP, R); + R = 1; } /* now handle either probability when transmit or reflect */ if (R > 0) { /* when allowing transmission, we should check if indeed we reflect */ - if (!transmit || (transmit && rand01() < R)) { + if (!transmit || (transmit && rand01 () < R)) { /* reflect velocity: -q -> -2*n*n.v/|n|^2 */ - if (!transmit) p *= R; - n_dot_v *= 2/n2; - vx -= nx*n_dot_v; - vy -= ny*n_dot_v; - vz -= nz*n_dot_v; + if (!transmit) + p *= R; + n_dot_v *= 2 / n2; + vx -= nx * n_dot_v; + vy -= ny * n_dot_v; + vz -= nz * n_dot_v; SCATTER; } else { if (transmit) { - p *= (1-R); /* transmitted beam has non reflected weight */ - } else ABSORB; + p *= (1 - R); /* transmitted beam has non reflected weight */ + } else + ABSORB; } } else { /* R=0: no reflection: absorb or transmit through when allowed */ - if (!transmit) ABSORB; + if (!transmit) + ABSORB; } /* leave surface by a small amount so that next intersection is not the same one */ - PROP_DT(1e-9); - } while (intersect && counter++ 1) && (w1 != w2)) - { - fprintf(stderr,"WARNING: Guide_channeled: %s:" - "This component does not work with multichannel focusing guide\n" - "Use Guide_gravity for that.\n", NAME_CURRENT_COMP); - exit(-1); + if ((nslit > 1) && (w1 != w2)) { + fprintf (stderr, + "WARNING: Guide_channeled: %s:" + "This component does not work with multichannel focusing guide\n" + "Use Guide_gravity for that.\n", + NAME_CURRENT_COMP); + exit (-1); } - if (d*nslit > w1) exit(fprintf(stderr, "Guide_channeled: %s: absorbing walls fill input window. No space left for transmission (d*nslit > w1).\n", NAME_CURRENT_COMP)); + if (d * nslit > w1) + exit (fprintf (stderr, "Guide_channeled: %s: absorbing walls fill input window. No space left for transmission (d*nslit > w1).\n", NAME_CURRENT_COMP)); - if (mcgravitation) fprintf(stderr,"WARNING: Guide_channeled: %s: " - "This component produces wrong results with gravitation !\n" - "Use Guide_gravity.\n", - NAME_CURRENT_COMP); + if (mcgravitation) + fprintf (stderr, + "WARNING: Guide_channeled: %s: " + "This component produces wrong results with gravitation !\n" + "Use Guide_gravity.\n", + NAME_CURRENT_COMP); if (nu != 0 || phase != 0) { - if (w1 != w2 || h1 != h2) - exit(fprintf(stderr,"Guide_channeled: %s: rotating slit pack must be straight (w1=w2 and h1=h2).\n", NAME_CURRENT_COMP)); - printf("Guide_channeled: %s: Fermi Chopper mode: frequency=%g [Hz] phase=%g [deg]\n", - NAME_CURRENT_COMP, nu, phase); - } + if (w1 != w2 || h1 != h2) + exit (fprintf (stderr, "Guide_channeled: %s: rotating slit pack must be straight (w1=w2 and h1=h2).\n", NAME_CURRENT_COMP)); + printf ("Guide_channeled: %s: Fermi Chopper mode: frequency=%g [Hz] phase=%g [deg]\n", NAME_CURRENT_COMP, nu, phase); + } %} TRACE %{ - double t1,t2; /* Intersection times. */ - double av,ah,bv,bh,cv1,cv2,ch1,ch2,dd; /* 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 nlen2; /* Vector lengths squared */ + double t1, t2; /* Intersection times. */ + double av, ah, bv, bh, cv1, cv2, ch1, ch2, dd; /* 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 nlen2; /* Vector lengths squared */ double edge; - double hadj; /* Channel displacement */ - double angle=0; + double hadj; /* Channel displacement */ + double angle = 0; if (nu != 0 || phase != 0) { /* rotate neutron w/r to guide element */ /* approximation of rotating straight Fermi Chopper */ - Coords X = coords_set(x,y,z-l/2); /* current coordinates of neutron in centered static frame */ + Coords X = coords_set (x, y, z - l / 2); /* current coordinates of neutron in centered static frame */ Rotation R; - double dt=(-z+l/2)/vz; /* time shift to each center of slit package */ - angle=fmod(360*nu*(t+dt)+phase, 360); /* in deg */ + double dt = (-z + l / 2) / vz; /* time shift to each center of slit package */ + angle = fmod (360 * nu * (t + dt) + phase, 360); /* in deg */ /* modify angle so that Z0 guide side is always in front of incoming neutron */ - if (angle > 90 && angle < 270) { angle -= 180; } + if (angle > 90 && angle < 270) { + angle -= 180; + } angle *= DEG2RAD; - rot_set_rotation(R, 0, -angle, 0); /* will rotate neutron instead of comp: negative side */ + rot_set_rotation (R, 0, -angle, 0); /* will rotate neutron instead of comp: negative side */ /* apply rotation to centered coordinates */ - Coords RX = rot_apply(R, X); - coords_get(RX, &x, &y, &z); - z = z+l/2; + Coords RX = rot_apply (R, X); + coords_get (RX, &x, &y, &z); + z = z + l / 2; /* rotate speed */ - X = coords_set(vx,vy,vz); - RX = rot_apply(R, X); - coords_get(RX, &vx, &vy, &vz); + X = coords_set (vx, vy, vz); + RX = rot_apply (R, X); + coords_get (RX, &vx, &vy, &vz); } /* Propagate neutron to guide entrance. */ @@ -167,132 +181,129 @@ TRACE absorbed in a GROUP construction, e.g. all neutrons - even the later absorbed ones are scattered at the guide entry. */ SCATTER; - if(x <= w1/-2.0 || x >= w1/2.0 || y <= -hhalf || y >= hhalf) + if (x <= w1 / -2.0 || x >= w1 / 2.0 || y <= -hhalf || y >= hhalf) ABSORB; /* Shift origin to center of channel hit (absorb if hit dividing walls) */ - x += w1/2.0; - edge = floor(x/w1c)*w1c; - if(x - edge > w1c - d) - { - x -= w1/2.0; /* Re-adjust origin */ + x += w1 / 2.0; + edge = floor (x / w1c) * w1c; + if (x - edge > w1c - d) { + x -= w1 / 2.0; /* Re-adjust origin */ ABSORB; } - x -= (edge + (w1c - d)/2.0); - hadj = edge + (w1c - d)/2.0 - w1/2.0; - for(;;) - { + x -= (edge + (w1c - d) / 2.0); + hadj = edge + (w1c - d) / 2.0 - w1 / 2.0; + 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 */ + 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; + cv1 = -whalf * l - z * ww; + cv2 = x * l; + ch1 = -hhalf * l - z * hh; + ch2 = y * l; /* Compute intersection times. */ - t1 = (l - z)/vz; + t1 = (l - z) / vz; i = 0; - if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) - { + if (vdotn_v1 < 0 && (t2 = (cv1 - cv2) / vdotn_v1) < t1) { t1 = t2; i = 1; } - if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) - { + if (vdotn_v2 < 0 && (t2 = (cv1 + cv2) / vdotn_v2) < t1) { t1 = t2; i = 2; } - if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) - { + if (vdotn_h1 < 0 && (t2 = (ch1 - ch2) / vdotn_h1) < t1) { t1 = t2; i = 3; } - if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) - { + 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); - dd = 2*vdotn_v1/nlen2; - vx = vx - dd*l; - vz = vz - dd*ww; - break; - case 2: /* Right vertical mirror */ - nlen2 = l*l + ww*ww; - q = V2Q*(-2)*vdotn_v2/sqrt(nlen2); - dd = 2*vdotn_v2/nlen2; - vx = vx + dd*l; - vz = vz - dd*ww; - break; - case 3: /* Lower horizontal mirror */ - nlen2 = l*l + hh*hh; - q = V2Q*(-2)*vdotn_h1/sqrt(nlen2); - dd = 2*vdotn_h1/nlen2; - vy = vy - dd*l; - vz = vz - dd*hh; - break; - case 4: /* Upper horizontal mirror */ - nlen2 = l*l + hh*hh; - q = V2Q*(-2)*vdotn_h2/sqrt(nlen2); - dd = 2*vdotn_h2/nlen2; - vy = vy + dd*l; - vz = vz - dd*hh; - break; + 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); + dd = 2 * vdotn_v1 / nlen2; + vx = vx - dd * l; + vz = vz - dd * ww; + break; + case 2: /* Right vertical mirror */ + nlen2 = l * l + ww * ww; + q = V2Q * (-2) * vdotn_v2 / sqrt (nlen2); + dd = 2 * vdotn_v2 / nlen2; + vx = vx + dd * l; + vz = vz - dd * ww; + break; + case 3: /* Lower horizontal mirror */ + nlen2 = l * l + hh * hh; + q = V2Q * (-2) * vdotn_h1 / sqrt (nlen2); + dd = 2 * vdotn_h1 / nlen2; + vy = vy - dd * l; + vz = vz - dd * hh; + break; + case 4: /* Upper horizontal mirror */ + nlen2 = l * l + hh * hh; + q = V2Q * (-2) * vdotn_h2 / sqrt (nlen2); + dd = 2 * vdotn_h2 / nlen2; + vy = vy + dd * l; + vz = vz - dd * hh; + break; } /* Now compute reflectivity. */ - if((i <= 2 && mx == 0) || (i > 2 && my == 0)) - { + if ((i <= 2 && mx == 0) || (i > 2 && my == 0)) { x += hadj; /* Re-adjust origin */ ABSORB; } else { - double ref=1; - if (i <= 2) - { - double par[] = {R0, Qcx, alphax, mx, W}; - StdReflecFunc(q, par, &ref); + double ref = 1; + if (i <= 2) { + double par[] = { R0, Qcx, alphax, mx, W }; + StdReflecFunc (q, par, &ref); if (ref > 0) p *= ref; else { x += hadj; /* Re-adjust origin */ - ABSORB; /* Cutoff ~ 1E-10 */ + ABSORB; /* Cutoff ~ 1E-10 */ } } else { - double par[] = {R0, Qcy, alphay, my, W}; - StdReflecFunc(q, par, &ref); + double par[] = { R0, Qcy, alphay, my, W }; + StdReflecFunc (q, par, &ref); if (ref > 0) p *= ref; else { x += hadj; /* Re-adjust origin */ - ABSORB; /* Cutoff ~ 1E-10 */ + ABSORB; /* Cutoff ~ 1E-10 */ } } } - x += hadj; SCATTER; x -= hadj; + x += hadj; + SCATTER; + x -= hadj; } /* end for */ - x += hadj; /* Re-adjust origin */ + x += hadj; /* Re-adjust origin */ if (nu != 0 || phase != 0) { /* rotate back neutron w/r to guide element */ - /* approximation of rotating straight Fermi Chopper */ - Coords X = coords_set(x,y,z-l/2); /* current coordinates of neutron in centered static frame */ - Rotation R; - rot_set_rotation(R, 0, angle, 0); /* will rotate back neutron: positive side */ - /* apply rotation to centered coordinates */ - Coords RX = rot_apply(R, X); - coords_get(RX, &x, &y, &z); - z = z+l/2; - /* rotate speed */ - X = coords_set(vx,vy,vz); - RX = rot_apply(R, X); - coords_get(RX, &vx, &vy, &vz); - } + /* approximation of rotating straight Fermi Chopper */ + Coords X = coords_set (x, y, z - l / 2); /* current coordinates of neutron in centered static frame */ + Rotation R; + rot_set_rotation (R, 0, angle, 0); /* will rotate back neutron: positive side */ + /* apply rotation to centered coordinates */ + Coords RX = rot_apply (R, X); + coords_get (RX, &x, &y, &z); + z = z + l / 2; + /* rotate speed */ + X = coords_set (vx, vy, vz); + RX = rot_apply (R, X); + coords_get (RX, &vx, &vy, &vz); + } %} MCDISPLAY @@ -300,29 +311,22 @@ MCDISPLAY int i; /* Draw the vertial slit-planes along each channel */ - for(i = 0; i < nslit; i++) - { - polygon(4, - i*w1c - w1/2.0, -h1/2.0, 0.0, - i*w2c - w2/2.0, -h2/2.0, (double)l, - i*w2c - w2/2.0, h2/2.0, (double)l, - i*w1c - w1/2.0, h1/2.0, 0.0); - polygon(4, - (i+1)*w1c - d - w1/2.0, -h1/2.0, 0.0, - (i+1)*w2c - d - w2/2.0, -h2/2.0, (double)l, - (i+1)*w2c - d - w2/2.0, h2/2.0, (double)l, - (i+1)*w1c - d - w1/2.0, h1/2.0, 0.0); + for (i = 0; i < nslit; i++) { + polygon (4, i * w1c - w1 / 2.0, -h1 / 2.0, 0.0, i * w2c - w2 / 2.0, -h2 / 2.0, (double)l, i * w2c - w2 / 2.0, h2 / 2.0, (double)l, i * w1c - w1 / 2.0, + h1 / 2.0, 0.0); + polygon (4, (i + 1) * w1c - d - w1 / 2.0, -h1 / 2.0, 0.0, (i + 1) * w2c - d - w2 / 2.0, -h2 / 2.0, (double)l, (i + 1) * w2c - d - w2 / 2.0, h2 / 2.0, + (double)l, (i + 1) * w1c - d - w1 / 2.0, h1 / 2.0, 0.0); } /* Add "bottom" and "lid" */ - polygon(4,-w1/2.0, -h1/2.0, 0.0, w1/2.0, -h1/2.0, 0.0, w2/2.0, -h2/2.0, (double)l, -w2/2.0, -h2/2.0, (double)l); - polygon(4,-w1/2.0, h1/2.0, 0.0, w1/2.0, h1/2.0, 0.0, w2/2.0, h2/2.0, (double)l, -w2/2.0, h2/2.0, (double)l); + polygon (4, -w1 / 2.0, -h1 / 2.0, 0.0, w1 / 2.0, -h1 / 2.0, 0.0, w2 / 2.0, -h2 / 2.0, (double)l, -w2 / 2.0, -h2 / 2.0, (double)l); + polygon (4, -w1 / 2.0, h1 / 2.0, 0.0, w1 / 2.0, h1 / 2.0, 0.0, w2 / 2.0, h2 / 2.0, (double)l, -w2 / 2.0, h2 / 2.0, (double)l); if (nu || phase) { - double radius = sqrt(w1*w1+l*l); + double radius = sqrt (w1 * w1 + l * l); /* cylinder top/center/bottom */ - circle("xz", 0,-h1/2,l/2,radius); - circle("xz", 0,0 ,l/2,radius); - circle("xz", 0, h1/2,l/2,radius); + circle ("xz", 0, -h1 / 2, l / 2, radius); + circle ("xz", 0, 0, l / 2, radius); + circle ("xz", 0, h1 / 2, l / 2, radius); } %} diff --git a/mcstas-comps/optics/Guide_gravity.comp b/mcstas-comps/optics/Guide_gravity.comp index 99513146c5..ff08fc00b1 100644 --- a/mcstas-comps/optics/Guide_gravity.comp +++ b/mcstas-comps/optics/Guide_gravity.comp @@ -121,34 +121,33 @@ SETTING PARAMETERS (w1, h1, w2=0, h2=0, l, /* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ SHARE %{ -%include "ref-lib" -#ifndef Gravity_guide_Version -#define Gravity_guide_Version "$Revision$" - -#ifndef PROP_GRAV_DT -#error McStas : You need PROP_GRAV_DT (McStas >= 1.4.3) to run this component -#endif - -/* -* G: (m/s^2) Gravitation acceleration along y axis [-9.81] -* Gx: (m/s^2) Gravitation acceleration along x axis [0] -* Gy: (m/s^2) Gravitation acceleration along y axis [-9.81] -* Gz: (m/s^2) Gravitation acceleration along z axis [0] -* mh: (1) m-value of material for left/right vert. mirrors -* mv: (1) m-value of material for top/bottom horz. mirrors -* mx: (1) m-value of material for left/right vert. mirrors -* my: (1) m-value of material for top/bottom horz. mirrors -*/ - - typedef struct Gravity_guide_Vars - { + %include "ref-lib" + #ifndef Gravity_guide_Version + #define Gravity_guide_Version "$Revision$" + + #ifndef PROP_GRAV_DT + #error McStas : You need PROP_GRAV_DT (McStas >= 1.4.3) to run this component + #endif + + /* + * G: (m/s^2) Gravitation acceleration along y axis [-9.81] + * Gx: (m/s^2) Gravitation acceleration along x axis [0] + * Gy: (m/s^2) Gravitation acceleration along y axis [-9.81] + * Gz: (m/s^2) Gravitation acceleration along z axis [0] + * mh: (1) m-value of material for left/right vert. mirrors + * mv: (1) m-value of material for top/bottom horz. mirrors + * mx: (1) m-value of material for left/right vert. mirrors + * my: (1) m-value of material for top/bottom horz. mirrors + */ + + typedef struct Gravity_guide_Vars { double gx; double gy; double gz; double nx[6], ny[6], nz[6]; double wx[6], wy[6], wz[6]; double A[6], norm_n2[6], norm_n[6]; - long N_reflection[7]; + long N_reflection[7]; double w1c, h1c; double w2c, h2c; double M[5]; @@ -156,177 +155,240 @@ SHARE double nzC[5], norm_n2xy[5], Axy[5]; double wav_lr, wav_tb, wav_z; double chamfer_z, chamfer_lr, chamfer_tb; - char compcurname[256]; + char compcurname[256]; double fc_freq, fc_phase; double warnings; } Gravity_guide_Vars_type; - void Gravity_guide_Init(Gravity_guide_Vars_type *aVars, - MCNUM a_w1, MCNUM a_h1, MCNUM a_w2, MCNUM a_h2, MCNUM a_l, MCNUM a_R0, - MCNUM a_Qc, MCNUM a_alpha, MCNUM a_m, MCNUM a_W, MCNUM a_nslit, MCNUM a_d, - MCNUM a_Gx, MCNUM a_Gy, MCNUM a_Gz, - MCNUM a_mleft, MCNUM a_mright, MCNUM a_mtop, MCNUM a_mbottom, MCNUM a_nhslit, - MCNUM a_wavy_lr, MCNUM a_wavy_tb, MCNUM a_wavy_z, MCNUM a_wavy, - MCNUM a_chamfers_z, MCNUM a_chamfers_lr, MCNUM a_chamfers_tb, MCNUM a_chamfers, - MCNUM a_nu, MCNUM a_phase, MCNUM a_aleft, MCNUM a_aright, MCNUM a_atop, MCNUM a_abottom) - { + void + Gravity_guide_Init (Gravity_guide_Vars_type* aVars, MCNUM a_w1, MCNUM a_h1, MCNUM a_w2, MCNUM a_h2, MCNUM a_l, MCNUM a_R0, MCNUM a_Qc, MCNUM a_alpha, MCNUM a_m, + MCNUM a_W, MCNUM a_nslit, MCNUM a_d, MCNUM a_Gx, MCNUM a_Gy, MCNUM a_Gz, MCNUM a_mleft, MCNUM a_mright, MCNUM a_mtop, MCNUM a_mbottom, + MCNUM a_nhslit, MCNUM a_wavy_lr, MCNUM a_wavy_tb, MCNUM a_wavy_z, MCNUM a_wavy, MCNUM a_chamfers_z, MCNUM a_chamfers_lr, + MCNUM a_chamfers_tb, MCNUM a_chamfers, MCNUM a_nu, MCNUM a_phase, MCNUM a_aleft, MCNUM a_aright, MCNUM a_atop, MCNUM a_abottom) { int i; - for (i=0; i<7; aVars->N_reflection[i++] = 0); - for (i=0; i<5; aVars->M[i++] = 0); - for (i=0; i<5; aVars->Alpha[i++] = 0); + for (i = 0; i < 7; aVars->N_reflection[i++] = 0) + ; + for (i = 0; i < 5; aVars->M[i++] = 0) + ; + for (i = 0; i < 5; aVars->Alpha[i++] = 0) + ; aVars->gx = a_Gx; /* The gravitation vector in the current component axis system */ aVars->gy = a_Gy; aVars->gz = a_Gz; - aVars->warnings=0; - - if (a_nslit <= 0 || a_nhslit <= 0) { fprintf(stderr,"%s: Fatal: no channel in this guide (nhslit or nslit=0).\n", aVars->compcurname); exit(-1); } - if (a_d < 0) { fprintf(stderr,"%s: Fatal: subdividing walls have negative thickness in this guide (d<0).\n", aVars->compcurname); exit(-1); } - aVars->w1c = (a_w1 - (a_nslit-1) *a_d)/(double)a_nslit; - aVars->w2c = (a_w2 - (a_nslit-1) *a_d)/(double)a_nslit; - aVars->h1c = (a_h1 - (a_nhslit-1)*a_d)/(double)a_nhslit; - aVars->h2c = (a_h2 - (a_nhslit-1)*a_d)/(double)a_nhslit; - - for (i=0; i <= 4; aVars->M[i++]=a_m); - for (i=0; i <= 4; aVars->Alpha[i++]=a_alpha); - if (a_mleft >= 0) aVars->M[1] =a_mleft ; - if (a_mright >= 0) aVars->M[2] =a_mright ; - if (a_mtop >= 0) aVars->M[3] =a_mtop ; - if (a_mbottom >= 0) aVars->M[4] =a_mbottom; - if (a_aleft >= 0) aVars->Alpha[1] =a_aleft ; - if (a_aright >= 0) aVars->Alpha[2] =a_aright ; - if (a_atop >= 0) aVars->Alpha[3] =a_atop ; - if (a_abottom >= 0) aVars->Alpha[4] =a_abottom; + aVars->warnings = 0; + + if (a_nslit <= 0 || a_nhslit <= 0) { + fprintf (stderr, "%s: Fatal: no channel in this guide (nhslit or nslit=0).\n", aVars->compcurname); + exit (-1); + } + if (a_d < 0) { + fprintf (stderr, "%s: Fatal: subdividing walls have negative thickness in this guide (d<0).\n", aVars->compcurname); + exit (-1); + } + aVars->w1c = (a_w1 - (a_nslit - 1) * a_d) / (double)a_nslit; + aVars->w2c = (a_w2 - (a_nslit - 1) * a_d) / (double)a_nslit; + aVars->h1c = (a_h1 - (a_nhslit - 1) * a_d) / (double)a_nhslit; + aVars->h2c = (a_h2 - (a_nhslit - 1) * a_d) / (double)a_nhslit; + + for (i = 0; i <= 4; aVars->M[i++] = a_m) + ; + for (i = 0; i <= 4; aVars->Alpha[i++] = a_alpha) + ; + if (a_mleft >= 0) + aVars->M[1] = a_mleft; + if (a_mright >= 0) + aVars->M[2] = a_mright; + if (a_mtop >= 0) + aVars->M[3] = a_mtop; + if (a_mbottom >= 0) + aVars->M[4] = a_mbottom; + if (a_aleft >= 0) + aVars->Alpha[1] = a_aleft; + if (a_aright >= 0) + aVars->Alpha[2] = a_aright; + if (a_atop >= 0) + aVars->Alpha[3] = a_atop; + if (a_abottom >= 0) + aVars->Alpha[4] = a_abottom; /* n: normal vectors to surfaces */ - aVars->nx[1] = a_l; aVars->ny[1] = 0; aVars->nz[1] = 0.5*(aVars->w2c-aVars->w1c); /* 1:+X left */ - aVars->nx[2] = -a_l; aVars->ny[2] = 0; aVars->nz[2] = -aVars->nz[1]; /* 2:-X right */ - aVars->nx[3] = 0; aVars->ny[3] = a_l; aVars->nz[3] = 0.5*(aVars->h2c-aVars->h1c); /* 3:+Y top */ - aVars->nx[4] = 0; aVars->ny[4] = -a_l; aVars->nz[4] = -aVars->nz[3]; /* 4:-Y bottom */ - aVars->nx[5] = 0; aVars->ny[5] = 0; aVars->nz[5] = a_l; /* 5:+Z exit */ - aVars->nx[0] = 0; aVars->ny[0] = 0; aVars->nz[0] = -a_l; /* 0:Z0 input */ + aVars->nx[1] = a_l; + aVars->ny[1] = 0; + aVars->nz[1] = 0.5 * (aVars->w2c - aVars->w1c); /* 1:+X left */ + aVars->nx[2] = -a_l; + aVars->ny[2] = 0; + aVars->nz[2] = -aVars->nz[1]; /* 2:-X right */ + aVars->nx[3] = 0; + aVars->ny[3] = a_l; + aVars->nz[3] = 0.5 * (aVars->h2c - aVars->h1c); /* 3:+Y top */ + aVars->nx[4] = 0; + aVars->ny[4] = -a_l; + aVars->nz[4] = -aVars->nz[3]; /* 4:-Y bottom */ + aVars->nx[5] = 0; + aVars->ny[5] = 0; + aVars->nz[5] = a_l; /* 5:+Z exit */ + aVars->nx[0] = 0; + aVars->ny[0] = 0; + aVars->nz[0] = -a_l; /* 0:Z0 input */ /* w: a point on these surfaces */ - aVars->wx[1] = +(aVars->w1c)/2; aVars->wy[1] = 0; aVars->wz[1] = 0; /* 1:+X left */ - aVars->wx[2] = -(aVars->w1c)/2; aVars->wy[2] = 0; aVars->wz[2] = 0; /* 2:-X right */ - aVars->wx[3] = 0; aVars->wy[3] = +(aVars->h1c)/2; aVars->wz[3] = 0; /* 3:+Y top */ - aVars->wx[4] = 0; aVars->wy[4] = -(aVars->h1c)/2; aVars->wz[4] = 0; /* 4:-Y bottom */ - aVars->wx[5] = 0; aVars->wy[5] = 0; aVars->wz[5] = a_l; /* 5:+Z exit */ - aVars->wx[0] = 0; aVars->wy[0] = 0; aVars->wz[0] = 0; /* 0:Z0 input */ - - for (i=0; i <= 5; i++) - { - aVars->A[i] = scalar_prod(aVars->nx[i], aVars->ny[i], aVars->nz[i], aVars->gx, aVars->gy, aVars->gz)/2; - aVars->norm_n2[i] = aVars->nx[i]*aVars->nx[i] + aVars->ny[i]*aVars->ny[i] + aVars->nz[i]*aVars->nz[i]; - if (aVars->norm_n2[i] <= 0) - { fprintf(stderr,"%s: Fatal: normal vector norm %i is null/negative ! check guide dimensions.\n", aVars->compcurname, i); exit(-1); } /* should never occur */ + aVars->wx[1] = +(aVars->w1c) / 2; + aVars->wy[1] = 0; + aVars->wz[1] = 0; /* 1:+X left */ + aVars->wx[2] = -(aVars->w1c) / 2; + aVars->wy[2] = 0; + aVars->wz[2] = 0; /* 2:-X right */ + aVars->wx[3] = 0; + aVars->wy[3] = +(aVars->h1c) / 2; + aVars->wz[3] = 0; /* 3:+Y top */ + aVars->wx[4] = 0; + aVars->wy[4] = -(aVars->h1c) / 2; + aVars->wz[4] = 0; /* 4:-Y bottom */ + aVars->wx[5] = 0; + aVars->wy[5] = 0; + aVars->wz[5] = a_l; /* 5:+Z exit */ + aVars->wx[0] = 0; + aVars->wy[0] = 0; + aVars->wz[0] = 0; /* 0:Z0 input */ + + for (i = 0; i <= 5; i++) { + aVars->A[i] = scalar_prod (aVars->nx[i], aVars->ny[i], aVars->nz[i], aVars->gx, aVars->gy, aVars->gz) / 2; + aVars->norm_n2[i] = aVars->nx[i] * aVars->nx[i] + aVars->ny[i] * aVars->ny[i] + aVars->nz[i] * aVars->nz[i]; + if (aVars->norm_n2[i] <= 0) { + fprintf (stderr, "%s: Fatal: normal vector norm %i is null/negative ! check guide dimensions.\n", aVars->compcurname, i); + exit (-1); + } /* should never occur */ else - aVars->norm_n[i] = sqrt(aVars->norm_n2[i]); + aVars->norm_n[i] = sqrt (aVars->norm_n2[i]); } /* partial computations for l/r/t/b sides, to save computing time */ - for (i=1; i <= 4; i++) - { /* stores nz that changes in case non box element (focus/defocus) */ - aVars->nzC[i] = aVars->nz[i]; /* partial xy terms */ - aVars->norm_n2xy[i]= aVars->nx[i]*aVars->nx[i] + aVars->ny[i]*aVars->ny[i]; - aVars->Axy[i] = (aVars->nx[i]*aVars->gx + aVars->ny[i]*aVars->gy)/2; + for (i = 1; i <= 4; i++) { /* stores nz that changes in case non box element (focus/defocus) */ + aVars->nzC[i] = aVars->nz[i]; /* partial xy terms */ + aVars->norm_n2xy[i] = aVars->nx[i] * aVars->nx[i] + aVars->ny[i] * aVars->ny[i]; + aVars->Axy[i] = (aVars->nx[i] * aVars->gx + aVars->ny[i] * aVars->gy) / 2; } /* handle waviness init */ - if (a_wavy && (!a_wavy_tb && !a_wavy_lr && !a_wavy_z)) - { aVars->wav_tb=aVars->wav_lr=aVars->wav_z=a_wavy; } - else - { aVars->wav_tb=a_wavy_tb; aVars->wav_lr=a_wavy_lr; aVars->wav_z=a_wavy_z; } - aVars->wav_tb *= DEG2RAD/(sqrt(8*log(2))); /* Convert from deg FWHM to rad Gaussian sigma */ - aVars->wav_lr *= DEG2RAD/(sqrt(8*log(2))); - aVars->wav_z *= DEG2RAD/(sqrt(8*log(2))); + if (a_wavy && (!a_wavy_tb && !a_wavy_lr && !a_wavy_z)) { + aVars->wav_tb = aVars->wav_lr = aVars->wav_z = a_wavy; + } else { + aVars->wav_tb = a_wavy_tb; + aVars->wav_lr = a_wavy_lr; + aVars->wav_z = a_wavy_z; + } + aVars->wav_tb *= DEG2RAD / (sqrt (8 * log (2))); /* Convert from deg FWHM to rad Gaussian sigma */ + aVars->wav_lr *= DEG2RAD / (sqrt (8 * log (2))); + aVars->wav_z *= DEG2RAD / (sqrt (8 * log (2))); /* handle chamfers init */ - if (a_chamfers && (!a_chamfers_z && !a_chamfers_lr && !a_chamfers_tb)) - { aVars->chamfer_z=aVars->chamfer_lr=aVars->chamfer_tb=a_chamfers; } - else - { - aVars->chamfer_z=a_chamfers_z; - aVars->chamfer_lr=a_chamfers_lr; - aVars->chamfer_tb=a_chamfers_tb; + if (a_chamfers && (!a_chamfers_z && !a_chamfers_lr && !a_chamfers_tb)) { + aVars->chamfer_z = aVars->chamfer_lr = aVars->chamfer_tb = a_chamfers; + } else { + aVars->chamfer_z = a_chamfers_z; + aVars->chamfer_lr = a_chamfers_lr; + aVars->chamfer_tb = a_chamfers_tb; } - aVars->fc_freq = a_nu; + aVars->fc_freq = a_nu; aVars->fc_phase = a_phase; } -#pragma acc routine seq - int Gravity_guide_Trace(double *dt, - Gravity_guide_Vars_type *aVars, - double cx, double cy, double cz, - double cvx, double cvy, double cvz, - double cxnum, double cxk, double cynum, double cyk, - double *cnx, double *cny, double *cnz, _class_particle* _particle) - { + #pragma acc routine seq + int + Gravity_guide_Trace (double* dt, Gravity_guide_Vars_type* aVars, double cx, double cy, double cz, double cvx, double cvy, double cvz, double cxnum, double cxk, + double cynum, double cyk, double* cnx, double* cny, double* cnz, _class_particle* _particle) { double B, C; - int ret=0; - int side=0; + int ret = 0; + int side = 0; double n1; - double dt0, dt_min=0; - int i; + double dt0, dt_min = 0; + int i; double loc_num, loc_nslit; - int i_slope=3; + int i_slope = 3; /* look if there is a previous intersection with guide sides */ /* A = 0.5 n.g; B = n.v; C = n.(r-W); */ /* 5=+Z side: n=(0, 0, -l) ; W = (0, 0, l) (at z=l, guide exit)*/ - B = aVars->nz[5]*cvz; C = aVars->nz[5]*(cz - aVars->wz[5]); - ret = solve_2nd_order(&dt0, NULL, aVars->A[5], B, C); - if (ret && dt0>1e-10) { dt_min = dt0; side=5; } + B = aVars->nz[5] * cvz; + C = aVars->nz[5] * (cz - aVars->wz[5]); + ret = solve_2nd_order (&dt0, NULL, aVars->A[5], B, C); + if (ret && dt0 > 1e-10) { + dt_min = dt0; + side = 5; + } - loc_num = cynum; loc_nslit = cyk; - for (i=4; i>0; i--) - { - if (i == 2) { i_slope=1; loc_num = cxnum; loc_nslit = cxk; } + loc_num = cynum; + loc_nslit = cyk; + for (i = 4; i > 0; i--) { + if (i == 2) { + i_slope = 1; + loc_num = cxnum; + loc_nslit = cxk; + } if (aVars->nzC[i_slope] != 0) { - n1 = loc_nslit - 2*(loc_num); /* slope of l/r/u/d sides depends on the channel ! */ - loc_num++; /* use partial computations to alter nz and A */ - aVars->nz[i]= aVars->nzC[i]*n1; - aVars->A[i] = aVars->Axy[i] + aVars->nz[i]*aVars->gz/2; + n1 = loc_nslit - 2 * (loc_num); /* slope of l/r/u/d sides depends on the channel ! */ + loc_num++; /* use partial computations to alter nz and A */ + aVars->nz[i] = aVars->nzC[i] * n1; + aVars->A[i] = aVars->Axy[i] + aVars->nz[i] * aVars->gz / 2; } - if (i < 3) - { B = aVars->nx[i]*cvx + aVars->nz[i]*cvz; C = aVars->nx[i]*(cx-aVars->wx[i]) + aVars->nz[i]*cz; } - else { B = aVars->ny[i]*cvy + aVars->nz[i]*cvz; C = aVars->ny[i]*(cy-aVars->wy[i]) + aVars->nz[i]*cz; } - ret = solve_2nd_order(&dt0, NULL, aVars->A[i], B, C); - if (ret && dt0>1e-10 && (dt0nzC[i] != 0) - { aVars->norm_n2[i] = aVars->norm_n2xy[i] + aVars->nz[i]*aVars->nz[i]; - aVars->norm_n[i] = sqrt(aVars->norm_n2[i]); } + if (i < 3) { + B = aVars->nx[i] * cvx + aVars->nz[i] * cvz; + C = aVars->nx[i] * (cx - aVars->wx[i]) + aVars->nz[i] * cz; + } else { + B = aVars->ny[i] * cvy + aVars->nz[i] * cvz; + C = aVars->ny[i] * (cy - aVars->wy[i]) + aVars->nz[i] * cz; + } + ret = solve_2nd_order (&dt0, NULL, aVars->A[i], B, C); + if (ret && dt0 > 1e-10 && (dt0 < dt_min || !dt_min)) { + dt_min = dt0; + side = i; + if (aVars->nzC[i] != 0) { + aVars->norm_n2[i] = aVars->norm_n2xy[i] + aVars->nz[i] * aVars->nz[i]; + aVars->norm_n[i] = sqrt (aVars->norm_n2[i]); + } } - } + } *dt = dt_min; /* handles waviness: rotate n vector */ - if (side > 0 && side < 5 && (aVars->wav_z || aVars->wav_lr || aVars->wav_tb)) - { - double nt_x, nt_y, nt_z; /* transverse vector */ - double nn_x, nn_y, nn_z; /* normal vector (tmp) */ + if (side > 0 && side < 5 && (aVars->wav_z || aVars->wav_lr || aVars->wav_tb)) { + double nt_x, nt_y, nt_z; /* transverse vector */ + double nn_x, nn_y, nn_z; /* normal vector (tmp) */ double phi; /* normal vector n_z = [ 0,0,1], n_t = n x n_z; */ - vec_prod(nt_x,nt_y,nt_z, aVars->nx[side],aVars->ny[side],aVars->nz[side], 0,0,1); + vec_prod (nt_x, nt_y, nt_z, aVars->nx[side], aVars->ny[side], aVars->nz[side], 0, 0, 1); /* rotate n with angle wavy_z around n_t -> nn */ if (aVars->wav_z) { phi = aVars->wav_z; - rotate(nn_x,nn_y,nn_z, aVars->nx[side],aVars->ny[side],aVars->nz[side], aVars->wav_z*randnorm(), nt_x,nt_y,nt_z); - } else { nn_x=aVars->nx[side]; nn_y=aVars->ny[side]; nn_z=aVars->nz[side]; } + rotate (nn_x, nn_y, nn_z, aVars->nx[side], aVars->ny[side], aVars->nz[side], aVars->wav_z * randnorm (), nt_x, nt_y, nt_z); + } else { + nn_x = aVars->nx[side]; + nn_y = aVars->ny[side]; + nn_z = aVars->nz[side]; + } /* rotate n with angle wavy_{x|y} around n_z -> nt */ - phi = (side <=2) ? aVars->wav_lr : aVars->wav_tb; + phi = (side <= 2) ? aVars->wav_lr : aVars->wav_tb; if (phi) { - rotate(nt_x,nt_y,nt_z, nn_x,nn_y,nn_z, phi*randnorm(), 0,0,1); - } else { nt_x=nn_x; nt_y=nn_y; nt_z=nn_z; } - *cnx=nt_x; *cny=nt_y; *cnz=nt_z; - } else - { *cnx=aVars->nx[side]; *cny=aVars->ny[side]; *cnz=aVars->nz[side]; } + rotate (nt_x, nt_y, nt_z, nn_x, nn_y, nn_z, phi * randnorm (), 0, 0, 1); + } else { + nt_x = nn_x; + nt_y = nn_y; + nt_z = nn_z; + } + *cnx = nt_x; + *cny = nt_y; + *cnz = nt_z; + } else { + *cnx = aVars->nx[side]; + *cny = aVars->ny[side]; + *cnz = aVars->nz[side]; + } return (side); } -%include "read_table-lib" + %include "read_table-lib" -#endif + #endif %} DECLARE @@ -338,57 +400,61 @@ DECLARE INITIALIZE %{ - double Gx=0, Gy=-GRAVITY, Gz=0; + double Gx = 0, Gy = -GRAVITY, Gz = 0; Coords mcLocG; int i; - if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) { - if (Table_Read(&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ - exit(fprintf(stderr,"Guide_gravity: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); - table_present=1; + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) { + if (Table_Read (&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ + exit (fprintf (stderr, "Guide_gravity: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); + table_present = 1; } else { - table_present=0; - if (W < 0 || R0 < 0 || Qc < 0) - { fprintf(stderr,"Guide_gravity: %s: W R0 Qc must be >0.\n", NAME_CURRENT_COMP); - exit(-1); } + table_present = 0; + if (W < 0 || R0 < 0 || Qc < 0) { + fprintf (stderr, "Guide_gravity: %s: W R0 Qc must be >0.\n", NAME_CURRENT_COMP); + exit (-1); + } } - if (nslit <= 0 || nhslit <= 0) - { fprintf(stderr,"Guide_gravity: %s: nslit nhslit must be >0.\n", NAME_CURRENT_COMP); - exit(-1); } + if (nslit <= 0 || nhslit <= 0) { + fprintf (stderr, "Guide_gravity: %s: nslit nhslit must be >0.\n", NAME_CURRENT_COMP); + exit (-1); + } - if (!w1 || !h1) - { fprintf(stderr,"Guide_gravity: %s: input window is closed (w1=h1=0).\n", NAME_CURRENT_COMP); - exit(-1); } + if (!w1 || !h1) { + fprintf (stderr, "Guide_gravity: %s: input window is closed (w1=h1=0).\n", NAME_CURRENT_COMP); + exit (-1); + } - if (d*(nslit-1) > w1) exit(fprintf(stderr, "Guide_gravity: %s: absorbing walls fill input window. No space left for transmission (d*(nslit-1) > w1).\n", NAME_CURRENT_COMP)); + if (d * (nslit - 1) > w1) + exit (fprintf (stderr, "Guide_gravity: %s: absorbing walls fill input window. No space left for transmission (d*(nslit-1) > w1).\n", NAME_CURRENT_COMP)); - if (!w2) w2=w1; - if (!h2) h2=h1; + if (!w2) + w2 = w1; + if (!h2) + h2 = h1; - if (mcgravitation) G=-GRAVITY; - mcLocG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,G,0)); - coords_get(mcLocG, &Gx, &Gy, &Gz); + if (mcgravitation) + G = -GRAVITY; + mcLocG = rot_apply (ROT_A_CURRENT_COMP, coords_set (0, G, 0)); + coords_get (mcLocG, &Gx, &Gy, &Gz); - strcpy(GVarsGlobal.compcurname, NAME_CURRENT_COMP); + strcpy (GVarsGlobal.compcurname, NAME_CURRENT_COMP); if (l > 0 && nelements > 0) { - Gravity_guide_Init(&GVarsGlobal, - w1, h1, w2, h2, l, R0, - Qc, alpha, m, W, nslit, d, - Gx, Gy, Gz, mleft, mright, mtop, - mbottom, nhslit, wavy_lr, wavy_tb, wavy_z, wavy, - chamfers_z, chamfers_lr, chamfers_tb, chamfers,nu,phase,aleft,aright,atop,abottom); - if (!G) for (i=0; i<5; GVarsGlobal.A[i++] = 0); + Gravity_guide_Init (&GVarsGlobal, w1, h1, w2, h2, l, R0, Qc, alpha, m, W, nslit, d, Gx, Gy, Gz, mleft, mright, mtop, mbottom, nhslit, wavy_lr, wavy_tb, + wavy_z, wavy, chamfers_z, chamfers_lr, chamfers_tb, chamfers, nu, phase, aleft, aright, atop, abottom); + if (!G) + for (i = 0; i < 5; GVarsGlobal.A[i++] = 0) + ; if (GVarsGlobal.fc_freq != 0 || GVarsGlobal.fc_phase != 0) { if (w1 != w2 || h1 != h2) - exit(fprintf(stderr,"Guide_gravity: %s: rotating slit pack must be straight (w1=w2 and h1=h2).\n", NAME_CURRENT_COMP)); - printf("Guide_gravity: %s: Fermi Chopper mode: frequency=%g [Hz] phase=%g [deg]\n", - NAME_CURRENT_COMP, GVarsGlobal.fc_freq, GVarsGlobal.fc_phase); + exit (fprintf (stderr, "Guide_gravity: %s: rotating slit pack must be straight (w1=w2 and h1=h2).\n", NAME_CURRENT_COMP)); + printf ("Guide_gravity: %s: Fermi Chopper mode: frequency=%g [Hz] phase=%g [deg]\n", NAME_CURRENT_COMP, GVarsGlobal.fc_freq, GVarsGlobal.fc_phase); } - } else printf("Guide_gravity: %s: unactivated (l=0 or nelements=0)\n", NAME_CURRENT_COMP); - + } else + printf ("Guide_gravity: %s: unactivated (l=0 or nelements=0)\n", NAME_CURRENT_COMP); %} TRACE @@ -399,167 +465,204 @@ TRACE if (l > 0 && nelements > 0) { double B, C, dt; - int ret, bounces = 0, i=0; + int ret, bounces = 0, i = 0; double this_width, this_height; - double angle=0; + double angle = 0; if (GVars.fc_freq != 0 || GVars.fc_phase != 0) { /* rotate neutron w/r to guide element */ /* approximation of rotating straight Fermi Chopper */ - Coords X = coords_set(x,y,z-l/2); /* current coordinates of neutron in centered static frame */ + Coords X = coords_set (x, y, z - l / 2); /* current coordinates of neutron in centered static frame */ Rotation R; - double dt=(-z+l/2)/vz; /* time shift to each center of slit package */ - angle=fmod(360*GVars.fc_freq*(t+dt)+GVars.fc_phase, 360); /* in deg */ + double dt = (-z + l / 2) / vz; /* time shift to each center of slit package */ + angle = fmod (360 * GVars.fc_freq * (t + dt) + GVars.fc_phase, 360); /* in deg */ /* modify angle so that Z0 guide side is always in front of incoming neutron */ - if (angle > 90 && angle < 270) { angle -= 180; } + if (angle > 90 && angle < 270) { + angle -= 180; + } angle *= DEG2RAD; - rot_set_rotation(R, 0, -angle, 0); /* will rotate neutron instead of comp: negative side */ + rot_set_rotation (R, 0, -angle, 0); /* will rotate neutron instead of comp: negative side */ /* apply rotation to centered coordinates */ - Coords RX = rot_apply(R, X); - coords_get(RX, &x, &y, &z); - z = z+l/2; + Coords RX = rot_apply (R, X); + coords_get (RX, &x, &y, &z); + z = z + l / 2; /* rotate speed */ - X = coords_set(vx,vy,vz); - RX = rot_apply(R, X); - coords_get(RX, &vx, &vy, &vz); + X = coords_set (vx, vy, vz); + RX = rot_apply (R, X); + coords_get (RX, &vx, &vy, &vz); } - for (i=0; i<7; GVars.N_reflection[i++] = 0); + for (i = 0; i < 7; GVars.N_reflection[i++] = 0) + ; /* propagate to box input (with gravitation) in comp local coords */ /* A = 0.5 n.g; B = n.v; C = n.(r-W); */ /* 0=Z0 side: n=(0, 0, -l) ; W = (0, 0, 0) (at z=0, guide input)*/ - B = -l*vz; C = -l*z; + B = -l * vz; + C = -l * z; - ret = solve_2nd_order(&dt, NULL, GVars.A[0], B, C); - if (ret==0) ABSORB; + ret = solve_2nd_order (&dt, NULL, GVars.A[0], B, C); + if (ret == 0) + ABSORB; - if (dt>0.0) PROP_GRAV_DT(dt, GVars.gx, GVars.gy, GVars.gz); else if (angle) ABSORB; + if (dt > 0.0) + PROP_GRAV_DT (dt, GVars.gx, GVars.gy, GVars.gz); + else if (angle) + ABSORB; GVars.N_reflection[6]++; - this_width = w1; + this_width = w1; this_height = h1; - /* check if we are in the box input, else absorb */ - if (fabs(x) > this_width/2 || fabs(y) > this_height/2) + /* check if we are in the box input, else absorb */ + if (fabs (x) > this_width / 2 || fabs (y) > this_height / 2) ABSORB; - else - { - double w_edge, w_adj; /* Channel displacement on X */ - double h_edge, h_adj; /* Channel displacement on Y */ - double w_chnum,h_chnum; /* channel indexes */ + else { + double w_edge, w_adj; /* Channel displacement on X */ + double h_edge, h_adj; /* Channel displacement on Y */ + double w_chnum, h_chnum; /* channel indexes */ SCATTER; /* X: Shift origin to center of channel hit (absorb if hit dividing walls) */ - x += w1/2.0; - w_chnum = floor(x/(GVars.w1c+d)); /* 0= right side, nslit+1=left side */ - w_edge = w_chnum*(GVars.w1c+d); - if(x - w_edge > GVars.w1c) - { - x -= w1/2.0; /* Re-adjust origin */ + x += w1 / 2.0; + w_chnum = floor (x / (GVars.w1c + d)); /* 0= right side, nslit+1=left side */ + w_edge = w_chnum * (GVars.w1c + d); + if (x - w_edge > GVars.w1c) { + x -= w1 / 2.0; /* Re-adjust origin */ ABSORB; } - w_adj = w_edge + (GVars.w1c)/2.0; - x -= w_adj; w_adj -= w1/2.0; + w_adj = w_edge + (GVars.w1c) / 2.0; + x -= w_adj; + w_adj -= w1 / 2.0; /* Y: Shift origin to center of channel hit (absorb if hit dividing walls) */ - y += h1/2.0; - h_chnum = floor(y/(GVars.h1c+d)); /* 0= lower side, nslit+1=upper side */ - h_edge = h_chnum*(GVars.h1c+d); - if(y - h_edge > GVars.h1c) - { - y -= h1/2.0; /* Re-adjust origin */ + y += h1 / 2.0; + h_chnum = floor (y / (GVars.h1c + d)); /* 0= lower side, nslit+1=upper side */ + h_edge = h_chnum * (GVars.h1c + d); + if (y - h_edge > GVars.h1c) { + y -= h1 / 2.0; /* Re-adjust origin */ ABSORB; } - h_adj = h_edge + (GVars.h1c)/2.0; - y -= h_adj; h_adj -= h1/2.0; + h_adj = h_edge + (GVars.h1c) / 2.0; + y -= h_adj; + h_adj -= h1 / 2.0; /* neutron is now in the input window of the guide */ /* do loops on reflections in the box */ - for(;;) - { + for (;;) { /* get intersections for all box sides */ - double q, nx,ny,nz; + double q, nx, ny, nz; double this_length; - int side=0; + int side = 0; bounces++; /* now look for intersection with guide sides and exit */ - side = Gravity_guide_Trace(&dt, &GVars, x, y, z, - vx, vy, vz, w_chnum, nslit, h_chnum, nhslit, - &nx, &ny, &nz, _particle); + side = Gravity_guide_Trace (&dt, &GVars, x, y, z, vx, vy, vz, w_chnum, nslit, h_chnum, nhslit, &nx, &ny, &nz, _particle); /* only positive dt are valid */ /* exit reflection loops if no intersection (neutron is after box) */ - if (side == 0 || dt <= 0) - { - if (GVars.warnings < 100) - fprintf(stderr,"%s: warning: neutron has entered guide, but can not exit !\n", GVars.compcurname); - GVars.warnings++; - x += w_adj; y += h_adj; ABSORB; } /* should never occur */ + if (side == 0 || dt <= 0) { + if (GVars.warnings < 100) + fprintf (stderr, "%s: warning: neutron has entered guide, but can not exit !\n", GVars.compcurname); + GVars.warnings++; + x += w_adj; + y += h_adj; + ABSORB; + } /* should never occur */ /* propagate to dt */ - PROP_GRAV_DT(dt, GVars.gx, GVars.gy, GVars.gz); + PROP_GRAV_DT (dt, GVars.gx, GVars.gy, GVars.gz); /* do reflection on speed for l/r/u/d sides */ if (side == 5) /* neutron reaches end of guide: end loop and exit comp */ - { GVars.N_reflection[side]++; x += w_adj; y += h_adj; SCATTER; x -= w_adj; y -= h_adj; break; } + { + GVars.N_reflection[side]++; + x += w_adj; + y += h_adj; + SCATTER; + x -= w_adj; + y -= h_adj; + break; + } /* else reflection on a guide wall */ - if(GVars.M[side] == 0 || Qc == 0 || R0 == 0) /* walls are absorbing */ - { x += w_adj; y += h_adj; ABSORB; } + if (GVars.M[side] == 0 || Qc == 0 || R0 == 0) /* walls are absorbing */ + { + x += w_adj; + y += h_adj; + ABSORB; + } /* handle chamfers */ - this_width = w1+(w2-w1)*z/l; - this_height= h1+(h2-h1)*z/l; - this_length= fmod(z, l/nelements); + this_width = w1 + (w2 - w1) * z / l; + this_height = h1 + (h2 - h1) * z / l; + this_length = fmod (z, l / nelements); /* absorb on input/output of element parts */ - if (GVars.chamfer_z && (this_lengthl/nelements-GVars.chamfer_z)) - { x += w_adj; y += h_adj; ABSORB; } + if (GVars.chamfer_z && (this_length < GVars.chamfer_z || this_length > l / nelements - GVars.chamfer_z)) { + x += w_adj; + y += h_adj; + ABSORB; + } /* absorb on l/r/t/b sides */ - if (GVars.chamfer_lr && (side==1 || side==2) && (fabs(y+h_adj)>this_height/2-GVars.chamfer_lr)) - { x += w_adj; y += h_adj; ABSORB; } - if (GVars.chamfer_tb && (side==3 || side==4) && (fabs(x+w_adj)>this_width/2- GVars.chamfer_tb)) - { x += w_adj; y += h_adj; ABSORB; } + if (GVars.chamfer_lr && (side == 1 || side == 2) && (fabs (y + h_adj) > this_height / 2 - GVars.chamfer_lr)) { + x += w_adj; + y += h_adj; + ABSORB; + } + if (GVars.chamfer_tb && (side == 3 || side == 4) && (fabs (x + w_adj) > this_width / 2 - GVars.chamfer_tb)) { + x += w_adj; + y += h_adj; + ABSORB; + } /* change/mirror velocity: h_f = v - n.2*n.v/|n|^2 */ GVars.N_reflection[side]++; /* GVars.norm_n2 > 0 was checked at INIT */ /* compute n.v using current values */ - B = scalar_prod(vx,vy,vz,nx,ny,nz); - dt = 2*B/GVars.norm_n2[side]; /* 2*n.v/|n|^2 */ - vx -= nx*dt; - vy -= ny*dt; - vz -= nz*dt; + B = scalar_prod (vx, vy, vz, nx, ny, nz); + dt = 2 * B / GVars.norm_n2[side]; /* 2*n.v/|n|^2 */ + vx -= nx * dt; + vy -= ny * dt; + vz -= nz * dt; /* compute q and modify neutron weight */ /* scattering q=|n_i-n_f| = V2Q*|vf - v| = V2Q*2*n.v/|n| */ - q = 2*V2Q*fabs(B)/GVars.norm_n[side]; + q = 2 * V2Q * fabs (B) / GVars.norm_n[side]; - if (table_present==1) - TableReflecFunc(q, &pTable, &B); + if (table_present == 1) + TableReflecFunc (q, &pTable, &B); else { - double par[] = {R0, Qc, GVars.Alpha[side], GVars.M[side], W}; - StdReflecFunc(q, par, &B); + double par[] = { R0, Qc, GVars.Alpha[side], GVars.M[side], W }; + StdReflecFunc (q, par, &B); } - if (B <= 0) { x += w_adj; y += h_adj; ABSORB; } - else p *= B; - x += w_adj; y += h_adj; SCATTER; x -= w_adj; y -= h_adj; + if (B <= 0) { + x += w_adj; + y += h_adj; + ABSORB; + } else + p *= B; + x += w_adj; + y += h_adj; + SCATTER; + x -= w_adj; + y -= h_adj; GVars.N_reflection[0]++; /* go to the next reflection */ - if (bounces > 1000) ABSORB; + if (bounces > 1000) + ABSORB; } /* end for */ - x += w_adj; y += h_adj; /* Re-adjust origin after SCATTER */ + x += w_adj; + y += h_adj; /* Re-adjust origin after SCATTER */ } if (GVars.fc_freq != 0 || GVars.fc_phase != 0) { /* rotate back neutron w/r to guide element */ /* approximation of rotating straight Fermi Chopper */ - Coords X = coords_set(x,y,z-l/2); /* current coordinates of neutron in centered static frame */ + Coords X = coords_set (x, y, z - l / 2); /* current coordinates of neutron in centered static frame */ Rotation R; - rot_set_rotation(R, 0, angle, 0); /* will rotate back neutron: positive side */ + rot_set_rotation (R, 0, angle, 0); /* will rotate back neutron: positive side */ /* apply rotation to centered coordinates */ - Coords RX = rot_apply(R, X); - coords_get(RX, &x, &y, &z); - z = z+l/2; + Coords RX = rot_apply (R, X); + coords_get (RX, &x, &y, &z); + z = z + l / 2; /* rotate speed */ - X = coords_set(vx,vy,vz); - RX = rot_apply(R, X); - coords_get(RX, &vx, &vy, &vz); + X = coords_set (vx, vy, vz); + RX = rot_apply (R, X); + coords_get (RX, &vx, &vy, &vz); } } /* if l */ @@ -570,10 +673,10 @@ TRACE FINALLY %{ -if (GVarsGlobal.warnings > 100) { - fprintf(stderr,"%s: warning: neutron has entered guide, but can not exit !\n", GVarsGlobal.compcurname); - fprintf(stderr,"%s: warning: This message has been repeated %g times\n", GVarsGlobal.compcurname, GVarsGlobal.warnings); -} + if (GVarsGlobal.warnings > 100) { + fprintf (stderr, "%s: warning: neutron has entered guide, but can not exit !\n", GVarsGlobal.compcurname); + fprintf (stderr, "%s: warning: This message has been repeated %g times\n", GVarsGlobal.compcurname, GVarsGlobal.warnings); + } %} @@ -581,64 +684,50 @@ MCDISPLAY %{ if (l > 0 && nelements > 0) { - int i,j,n; - double x1,x2,x3,x4; - double y1,y2,y3,y4; + int i, j, n; + double x1, x2, x3, x4; + double y1, y2, y3, y4; double nel = (nelements > 11 ? 11 : nelements); - - for (n=0; n0.\n", NAME_CURRENT_COMP); - exit(-1); } - //} + if (W < 0 || R0 < 0 || Qc < 0 || m < 0) { + fprintf (stderr, "Guide: %s: W R0 Qc must be >0.\n", NAME_CURRENT_COMP); + exit (-1); + } + //} %} TRACE %{ - double t1,t2; /* Intersection times. */ - double av,ah,bv,bh,cv1,cv2,ch1,ch2,d; /* Intermediate values */ - double weight; /* Internal probability weight */ - double vdotn_v1,vdotn_v2,vdotn_h1,vdotn_h2; /* Dot products. */ - int i; /* Which mirror hit? */ - double q; /* Q [1/AA] of reflection */ - double nlen2; /* Vector lengths squared */ + double t1, t2; /* Intersection times. */ + double av, ah, bv, bh, cv1, cv2, ch1, ch2, d; /* Intermediate values */ + double weight; /* Internal probability weight */ + double vdotn_v1, vdotn_v2, vdotn_h1, vdotn_h2; /* Dot products. */ + int i; /* Which mirror hit? */ + double q; /* Q [1/AA] of reflection */ + double 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 ww = .5 * (w2 - w1), hh = .5 * (h2 - h1); + double whalf = .5 * w1, hhalf = .5 * h1; /* Propagate neutron to guide entrance. */ PROP_Z0; @@ -108,113 +113,103 @@ TRACE absorbed in a GROUP construction, e.g. all neutrons - even the later absorbed ones are scattered at the guide entry. */ SCATTER; - if(x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) + if (x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) ABSORB; - for(;;) - { + 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 */ + 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; + cv1 = -whalf * l - z * ww; + cv2 = x * l; + ch1 = -hhalf * l - z * hh; + ch2 = y * l; /* Compute intersection times. */ - t1 = (l - z)/vz; + t1 = (l - z) / vz; i = 0; - if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) - { + if (vdotn_v1 < 0 && (t2 = (cv1 - cv2) / vdotn_v1) < t1) { t1 = t2; i = 1; } - if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) - { + if (vdotn_v2 < 0 && (t2 = (cv1 + cv2) / vdotn_v2) < t1) { t1 = t2; i = 2; } - if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) - { + if (vdotn_h1 < 0 && (t2 = (ch1 - ch2) / vdotn_h1) < t1) { t1 = t2; i = 3; } - if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) - { + 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; + 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. */ weight = 1.0; /* Initial internal weight factor */ - if(m == 0) + if (m == 0) ABSORB; // if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) // TableReflecFunc(q, &pTable, &weight); - //else { - double par[] = {R0, Qc, alpha, m, W}; - StdReflecFunc(q, par, &weight); - //} + // else { + double par[] = { R0, Qc, alpha, m, W }; + StdReflecFunc (q, par, &weight); + //} if (weight > 0) p *= weight; - else ABSORB; + else + ABSORB; SCATTER; } %} MCDISPLAY %{ - - 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); + + 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 diff --git a/mcstas-comps/optics/Guide_tapering.comp b/mcstas-comps/optics/Guide_tapering.comp index 1a78329e75..9fc8e0ad05 100644 --- a/mcstas-comps/optics/Guide_tapering.comp +++ b/mcstas-comps/optics/Guide_tapering.comp @@ -91,586 +91,546 @@ SHARE DECLARE %{ -double *w1c; -double *w2c; -double *ww; -double *hh; -double *whalf; -double *hhalf; -double *lwhalf; -double *lhhalf; -double *h1_in; -double *h2_out; -double *w1_in; -double *w2_out; -double l_seg; -double h12; -double h2; -double w12; -double w2; -double a_ell_q; -double b_ell_q; -double lbw; -double lbh; -double mxi; -double u1; -double u2; -double div1; -double p2_para; -double test; -double Div1; -int seg; -char *fu; -char *pos; -char file_name[1024]; -char *ep; -FILE *num; -double rotation_h; -double rotation_v; + double* w1c; + double* w2c; + double* ww; + double* hh; + double* whalf; + double* hhalf; + double* lwhalf; + double* lhhalf; + double* h1_in; + double* h2_out; + double* w1_in; + double* w2_out; + double l_seg; + double h12; + double h2; + double w12; + double w2; + double a_ell_q; + double b_ell_q; + double lbw; + double lbh; + double mxi; + double u1; + double u2; + double div1; + double p2_para; + double test; + double Div1; + int seg; + char* fu; + char* pos; + char file_name[1024]; + char* ep; + FILE* num; + double rotation_h; + double rotation_v; %} INITIALIZE %{ -int i,ii; + int i, ii; -rotation_h=0; -rotation_v=0; + rotation_h = 0; + rotation_v = 0; -// dynamic memory allocation is good -w1c = (double*)malloc(sizeof(double)*segno); - w2c = (double*)malloc(sizeof(double)*segno); - ww = (double*)malloc(sizeof(double)*segno); - hh = (double*)malloc(sizeof(double)*segno); - whalf = (double*)malloc(sizeof(double)*segno); - hhalf = (double*)malloc(sizeof(double)*segno); - lwhalf = (double*)malloc(sizeof(double)*segno); - lhhalf = (double*)malloc(sizeof(double)*segno); - h1_in = (double*)malloc(sizeof(double)*(segno+1)); - h2_out = (double*)malloc(sizeof(double)*(segno+1)); - w1_in = (double*)malloc(sizeof(double)*(segno+1)); - w2_out = (double*)malloc(sizeof(double)*(segno+1)); + // dynamic memory allocation is good + w1c = (double*)malloc (sizeof (double) * segno); + w2c = (double*)malloc (sizeof (double) * segno); + ww = (double*)malloc (sizeof (double) * segno); + hh = (double*)malloc (sizeof (double) * segno); + whalf = (double*)malloc (sizeof (double) * segno); + hhalf = (double*)malloc (sizeof (double) * segno); + lwhalf = (double*)malloc (sizeof (double) * segno); + lhhalf = (double*)malloc (sizeof (double) * segno); + h1_in = (double*)malloc (sizeof (double) * (segno + 1)); + h2_out = (double*)malloc (sizeof (double) * (segno + 1)); + w1_in = (double*)malloc (sizeof (double) * (segno + 1)); + w2_out = (double*)malloc (sizeof (double) * (segno + 1)); struct para { char st[128]; } segment[800]; - - if (W <=0) - { - fprintf(stderr,"Component: %s (Guide_tapering) W must \n", NAME_CURRENT_COMP); - fprintf(stderr," be positive\n"); - exit(-1); + + if (W <= 0) { + fprintf (stderr, "Component: %s (Guide_tapering) W must \n", NAME_CURRENT_COMP); + fprintf (stderr, " be positive\n"); + exit (-1); } - if (l <= 0) - { - fprintf(stderr,"Component: %s (Guide_tapering) real guide length \n", - NAME_CURRENT_COMP); - fprintf(stderr," is <= ZERO ! \n"); - exit(-1); + if (l <= 0) { + fprintf (stderr, "Component: %s (Guide_tapering) real guide length \n", NAME_CURRENT_COMP); + fprintf (stderr, " is <= ZERO ! \n"); + exit (-1); } - if (mcgravitation) fprintf(stderr,"WARNING: Guide_tapering: %s: " - "This component produces wrong results with gravitation !\n" - "Use Guide_gravity.\n", - NAME_CURRENT_COMP); - seg=segno; - l_seg=l/(seg); - h12 = h1/2.0; - if (option != NULL) - { - fu = (char*)malloc(sizeof(char)*(strlen(option)+1)); - strcpy(fu,option); + if (mcgravitation) + fprintf (stderr, + "WARNING: Guide_tapering: %s: " + "This component produces wrong results with gravitation !\n" + "Use Guide_gravity.\n", + NAME_CURRENT_COMP); + seg = segno; + l_seg = l / (seg); + h12 = h1 / 2.0; + if (option != NULL) { + fu = (char*)malloc (sizeof (char) * (strlen (option) + 1)); + strcpy (fu, option); } else { - exit(-1); + exit (-1); } /* handle guide geometry ================================================== */ - if (!strcmp(fu,"elliptical")) - { - /* calculate parameter b of elliptical equestion - vertical mirrors */ - /* (l+linh+louth) -> distance between focal points */ - /* printf("A1 \n"); */ - lbh = l + linh + louth; - if (linh == 0 && louth == 0 ) - { - /* plane mirrors (vertical) */ - b_ell_q = 0; - h2 = h1; - } else { - /* elliptical mirrors */ - u1 = sqrt((linh*linh)+(h12*h12)); - u2 = sqrt((h12*h12) + ((l+louth)*(l+louth))); - a_ell_q = ((u1 + u2)/2.0)*((u1 + u2)/2.0); - b_ell_q = a_ell_q - ((lbh/2.0)*(lbh/2.0)); + if (!strcmp (fu, "elliptical")) { + /* calculate parameter b of elliptical equestion - vertical mirrors */ + /* (l+linh+louth) -> distance between focal points */ + /* printf("A1 \n"); */ + lbh = l + linh + louth; + if (linh == 0 && louth == 0) { + /* plane mirrors (vertical) */ + b_ell_q = 0; + h2 = h1; + } else { + /* elliptical mirrors */ + u1 = sqrt ((linh * linh) + (h12 * h12)); + u2 = sqrt ((h12 * h12) + ((l + louth) * (l + louth))); + a_ell_q = ((u1 + u2) / 2.0) * ((u1 + u2) / 2.0); + b_ell_q = a_ell_q - ((lbh / 2.0) * (lbh / 2.0)); + /* calculate heigth of guide exit (h2) */ + div1 = ((lbh / 2.0 - louth) * (lbh / 2.0 - louth)) / a_ell_q; + h2 = sqrt (b_ell_q * (1.0 - div1)); + h2 = h2 * 2.0; + } + } else if (!strcmp (fu, "parabolical")) { + if ((linh > 0) && (louth > 0)) { + fprintf (stderr, "Component: %s (Guide_tapering) Two focal\n", NAME_CURRENT_COMP); + fprintf (stderr, " points lout and linh are not allowed! \n"); + free (fu); + exit (-1); + } + if (louth == 0 && linh == 0) { + /* plane mirrors (vertical) */ + h2 = h1; + } else { + /* parabolical mirrors */ + if (linh == 0) { + Div1 = ((2.0 * louth + 2.0 * l) * (2.0 * louth + 2.0 * l)) / 4.0; + p2_para = ((sqrt (Div1 + (h12 * h12))) - (louth + l)) * 2.0; /* calculate heigth of guide exit (h2) */ - div1 = ((lbh/2.0-louth)*(lbh/2.0-louth))/a_ell_q; - h2 = sqrt(b_ell_q*(1.0-div1)); - h2 = h2*2.0; - } - } else if (!strcmp(fu,"parabolical")) { - if ((linh > 0) && (louth > 0)) - { - fprintf(stderr,"Component: %s (Guide_tapering) Two focal\n",NAME_CURRENT_COMP); - fprintf(stderr," points lout and linh are not allowed! \n"); - free(fu);exit(-1); - } - if (louth == 0 && linh == 0) - { - /* plane mirrors (vertical) */ - h2 = h1; - } else { - /* parabolical mirrors */ - if (linh == 0) - { - Div1=((2.0*louth+2.0*l)*(2.0*louth+2.0*l))/4.0; - p2_para=((sqrt(Div1+(h12*h12)))-(louth+l))*2.0; - /* calculate heigth of guide exit (h2) */ - h2 = sqrt(p2_para*(louth+p2_para/4.0)); - h2 = h2*2.0; - } else { - /* anti-trompete */ - Div1=((2.0*linh)*(2.0*linh))/4.0; - p2_para=((sqrt(Div1+(h12*h12)))-linh)*2.0; - /* calculate heigth of guide exit (h2) */ - h2 = sqrt(p2_para*(l+linh+p2_para/4.0)); - h2 = h2*2.0; - } - } - } else if (!strncmp(fu,"file",4)) { - pos = strtok(fu,"="); - while ((pos=strtok(0,"="))) - { - strcpy(file_name,pos); - } - if ((num=fopen(file_name,"r")) == NULL) - { - fprintf(stderr,"Component: %s (Guide_tapering)\n",NAME_CURRENT_COMP); - fprintf(stderr," File %s not found! \n", file_name); - free(fu);exit(-1); - } else { - ii = 0; - /* Use ret==NULL as termination criterion on while, otherwise - the reading may on some systems continue until "800" segments */ - char dymmy=1; - char *ret=&dymmy; - while (!feof(num) && ret) - { - ret = fgets(segment[ii].st,128,num); - if (ii > 799 ) { - fprintf(stderr,"%s: Number of segments is limited to 800 !! \n",NAME_CURRENT_COMP); - free(fu);exit(-1); - } - ii++; - } - fclose(num); - ii--; - } - seg = ii-3; - l_seg=l/seg; - for (i=3;i 799) { + fprintf (stderr, "%s: Number of segments is limited to 800 !! \n", NAME_CURRENT_COMP); + free (fu); + exit (-1); } - h1_in[i-3] = strtod(strtok(segment[i].st," "), &ep); - h2_out[i-3] = strtod(strtok(0," "), &ep); - w1_in[i-3] = strtod(strtok(0," "), &ep); - w2_out[i-3] = strtod(strtok(0," "), &ep); - } - h1 = h1_in[0]; - h2 = h2_out[seg-1]; - w1 = w1_in[0]; - w2 = w2_out[seg-1]; - for (i=0;i 0)) { + for (i = 1; i < (seg + 1); i++) { + h1_in[i] = (sqrt ((p2_para / 4.0 + louth + (l_seg * ii)) * p2_para)) * 2.0; + ii = ii - 1; + h2_out[i - 1] = h1_in[i]; } - } else { - if ((linh == 0) && (louth > 0)) - { - for (i=1;i<(seg+1);i++) - { - h1_in[i] = (sqrt((p2_para/4.0+louth+(l_seg*ii))*p2_para))*2.0; - ii=ii-1; - h2_out[i-1] = h1_in[i]; - } - } else { - for (i=1;i<(seg+1);i++) - { - h1_in[i] = (sqrt((p2_para/4.0+linh+(l_seg*i))*p2_para))*2.0; - h2_out[i-1] = h1_in[i]; - } + } else { + for (i = 1; i < (seg + 1); i++) { + h1_in[i] = (sqrt ((p2_para / 4.0 + linh + (l_seg * i)) * p2_para)) * 2.0; + h2_out[i - 1] = h1_in[i]; } - } + } + } } /* compute each value for horizontal mirrors */ - w12 = w1/2.0; - if (!strcmp(fu,"elliptical")) - { + w12 = w1 / 2.0; + if (!strcmp (fu, "elliptical")) { /* calculate lbw the distance between focal points of horizontal mirrors */ lbw = l + linw + loutw; /* calculate parameter b of elliptical equestion - horizontal mirrors */ - if (linw == 0 && loutw == 0 ) - { - /* plane mirrors (horizontal) */ - b_ell_q = 0; - w2 = w1; + if (linw == 0 && loutw == 0) { + /* plane mirrors (horizontal) */ + b_ell_q = 0; + w2 = w1; + } else { + /* elliptical mirrors */ + u1 = sqrt ((linw * linw) + (w12 * w12)); + u2 = sqrt ((w12 * w12) + ((l + loutw) * (l + loutw))); + a_ell_q = ((u1 + u2) / 2.0) * ((u1 + u2) / 2.0); + b_ell_q = a_ell_q - ((lbw / 2.0) * (lbw / 2.0)); + /* calculate weigth of guide exit (w2) */ + div1 = ((lbw / 2.0 - loutw) * (lbw / 2.0 - loutw)) / a_ell_q; + w2 = sqrt (b_ell_q * (1.0 - div1)); + w2 = w2 * 2.0; + } + } else if (!strcmp (fu, "parabolical")) { + if ((linw > 0) && (loutw > 0)) { + fprintf (stderr, "Component: %s (Guide_tapering) Two focal\n", NAME_CURRENT_COMP); + fprintf (stderr, " points linw and loutw are not allowed! \n"); + free (fu); + exit (-1); + } + if (loutw == 0 && linw == 0) { + /* plane mirrors (horizontal) */ + w2 = w1; } else { - /* elliptical mirrors */ - u1 = sqrt((linw*linw)+(w12*w12)); - u2 = sqrt((w12*w12) + ((l+loutw)*(l+loutw))); - a_ell_q = ((u1 + u2)/2.0)*((u1 + u2)/2.0); - b_ell_q = a_ell_q - ((lbw/2.0)*(lbw/2.0)); - /* calculate weigth of guide exit (w2) */ - div1 = ((lbw/2.0-loutw)*(lbw/2.0-loutw))/a_ell_q; - w2 = sqrt(b_ell_q*(1.0-div1)); - w2 = w2*2.0; - } - } else if (!strcmp(fu,"parabolical")) { - if ((linw > 0) && (loutw > 0)) - { - fprintf(stderr,"Component: %s (Guide_tapering) Two focal\n",NAME_CURRENT_COMP); - fprintf(stderr," points linw and loutw are not allowed! \n"); - free(fu);exit(-1); - } - if (loutw == 0 && linw == 0) - { - /* plane mirrors (horizontal) */ - w2 = w1; - } else { - if (linw == 0) - { - /* parabolical mirrors */ - Div1=((2.0*loutw+2.0*l)*(2.0*loutw+2.0*l))/4.0; - p2_para=((sqrt(Div1+(w12*w12)))-(loutw+l))*2.0; - /* calculate weigth of guide exit (w2) */ - w2 = sqrt(p2_para*(loutw+p2_para/4.0)); - w2 = w2*2.0; - } else { - /* anti-trompete */ - Div1=((2.0*linw)*(2.0*linw))/4.0; - p2_para=((sqrt(Div1+(w12*w12)))-linw)*2.0; - /* calculate heigth of guide exit (w2) */ - w2 = sqrt(p2_para*(l+linw+p2_para/4.0)); - w2 = w2*2.0; - } - } + if (linw == 0) { + /* parabolical mirrors */ + Div1 = ((2.0 * loutw + 2.0 * l) * (2.0 * loutw + 2.0 * l)) / 4.0; + p2_para = ((sqrt (Div1 + (w12 * w12))) - (loutw + l)) * 2.0; + /* calculate weigth of guide exit (w2) */ + w2 = sqrt (p2_para * (loutw + p2_para / 4.0)); + w2 = w2 * 2.0; + } else { + /* anti-trompete */ + Div1 = ((2.0 * linw) * (2.0 * linw)) / 4.0; + p2_para = ((sqrt (Div1 + (w12 * w12))) - linw) * 2.0; + /* calculate heigth of guide exit (w2) */ + w2 = sqrt (p2_para * (l + linw + p2_para / 4.0)); + w2 = w2 * 2.0; + } + } } - fprintf(stderr,"Component: %s (Guide_tapering)\n",NAME_CURRENT_COMP); - fprintf(stderr," Width at the guide exit (w2): %lf \n", w2); - if (w2 <= 0) - { - fprintf(stderr,"Component: %s (Guide_tapering)\n", NAME_CURRENT_COMP); - fprintf(stderr," Width at the guide exit (w2) was calculated\n"); - fprintf(stderr," <=0; Please change the parameter w1 and/or\n"); - fprintf(stderr," l! \n"); - free(fu);exit(-1); + fprintf (stderr, "Component: %s (Guide_tapering)\n", NAME_CURRENT_COMP); + fprintf (stderr, " Width at the guide exit (w2): %lf \n", w2); + if (w2 <= 0) { + fprintf (stderr, "Component: %s (Guide_tapering)\n", NAME_CURRENT_COMP); + fprintf (stderr, " Width at the guide exit (w2) was calculated\n"); + fprintf (stderr, " <=0; Please change the parameter w1 and/or\n"); + fprintf (stderr, " l! \n"); + free (fu); + exit (-1); } - if (!strcmp(fu,"elliptical")) - { - w1_in[0]=w1; - for (i=1;i 0)) { + for (i = 1; i < (seg + 1); i++) { + w1_in[i] = (sqrt ((p2_para / 4 + loutw + (l_seg * ii)) * p2_para)) * 2; + ii = ii - 1; + w2_out[i - 1] = w1_in[i]; } - } else { - if ((linw == 0) && (loutw > 0)) - { - for (i=1;i<(seg+1);i++) - { - w1_in[i] = (sqrt((p2_para/4+loutw+(l_seg*ii))*p2_para))*2; - ii=ii-1; - w2_out[i-1] = w1_in[i]; - } - } else { - for (i=1;i<(seg+1);i++) - { - w1_in[i] = (sqrt((p2_para/4+linw+(l_seg*i))*p2_para))*2; - w2_out[i-1] = w1_in[i]; - } + } else { + for (i = 1; i < (seg + 1); i++) { + w1_in[i] = (sqrt ((p2_para / 4 + linw + (l_seg * i)) * p2_para)) * 2; + w2_out[i - 1] = w1_in[i]; } - } + } + } } - free(fu); - for (i=0;i= w1_in[ii]/2.0 || y <= -hhalf[ii] || y >= hhalf[ii]) + ts = (zr - z) / vz; + PROP_DT (ts); + if (x <= w1_in[ii] / -2.0 || x >= w1_in[ii] / 2.0 || y <= -hhalf[ii] || y >= hhalf[ii]) ABSORB; /* Shift origin to center of channel hit (absorb if hit dividing walls) */ - x += w1_in[ii]/2.0; - edge = floor(x/w1c[ii])*w1c[ii]; - if(x - edge > w1c[ii]) - { - x -= w1_in[ii]/2.0; /* Re-adjust origin */ + x += w1_in[ii] / 2.0; + edge = floor (x / w1c[ii]) * w1c[ii]; + if (x - edge > w1c[ii]) { + x -= w1_in[ii] / 2.0; /* Re-adjust origin */ ABSORB; } - x -= (edge + (w1c[ii]/2.0)); - hadj = edge + (w1c[ii]/2.0) - w1_in[ii]/2.0; - for(;;) - { + x -= (edge + (w1c[ii] / 2.0)); + hadj = edge + (w1c[ii] / 2.0) - w1_in[ii] / 2.0; + for (;;) { /* Compute the dot products of v and n for the four mirrors. */ - ts=(zr-z)/vz; - av = l_seg*vx; bv = ww[ii]*vz; - ah = l_seg*vy; bh = hh[ii]*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 */ + ts = (zr - z) / vz; + av = l_seg * vx; + bv = ww[ii] * vz; + ah = l_seg * vy; + bh = hh[ii] * 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[ii]*l_seg - (z-zr)*ww[ii]; cv2 = x*l_seg; - ch1 = -hhalf[ii]*l_seg - (z-zr)*hh[ii]; ch2 = y*l_seg; + cv1 = -whalf[ii] * l_seg - (z - zr) * ww[ii]; + cv2 = x * l_seg; + ch1 = -hhalf[ii] * l_seg - (z - zr) * hh[ii]; + ch2 = y * l_seg; /* Compute intersection times. */ - t1 = (zr + l_seg - z)/vz; + t1 = (zr + l_seg - z) / vz; i = 0; - if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) - { + if (vdotn_v1 < 0 && (t2 = (cv1 - cv2) / vdotn_v1) < t1) { t1 = t2; i = 1; } - if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) - { + if (vdotn_v2 < 0 && (t2 = (cv1 + cv2) / vdotn_v2) < t1) { t1 = t2; i = 2; } - if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) - { + if (vdotn_h1 < 0 && (t2 = (ch1 - ch2) / vdotn_h1) < t1) { t1 = t2; i = 3; } - if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) - { + if (vdotn_h2 < 0 && (t2 = (ch1 + ch2) / vdotn_h2) < t1) { t1 = t2; i = 4; } - if(i == 0) - { - break; /* Neutron left guide. */ + if (i == 0) { + break; /* Neutron left guide. */ } - PROP_DT(t1); - switch(i) - { - case 1: /* Left vertical mirror */ - nlen2 = l_seg*l_seg + ww[ii]*ww[ii]; - q = V2Q*(-2)*vdotn_v1/sqrt(nlen2); - dd = 2*vdotn_v1/nlen2; - vx = vx - dd*l_seg; - vz = vz - dd*ww[ii]; - break; - case 2: /* Right vertical mirror */ - nlen2 = l_seg*l_seg + ww[ii]*ww[ii]; - q = V2Q*(-2)*vdotn_v2/sqrt(nlen2); - dd = 2*vdotn_v2/nlen2; - vx = vx + dd*l_seg; - vz = vz - dd*ww[ii]; - break; - case 3: /* Lower horizontal mirror */ - nlen2 = l_seg*l_seg + hh[ii]*hh[ii]; - q = V2Q*(-2)*vdotn_h1/sqrt(nlen2); - dd = 2*vdotn_h1/nlen2; - vy = vy - dd*l_seg; - vz = vz - dd*hh[ii]; - break; - case 4: /* Upper horizontal mirror */ - nlen2 = l_seg*l_seg + hh[ii]*hh[ii]; - q = V2Q*(-2)*vdotn_h2/sqrt(nlen2); - dd = 2*vdotn_h2/nlen2; - vy = vy + dd*l_seg; - vz = vz - dd*hh[ii]; - break; + PROP_DT (t1); + switch (i) { + case 1: /* Left vertical mirror */ + nlen2 = l_seg * l_seg + ww[ii] * ww[ii]; + q = V2Q * (-2) * vdotn_v1 / sqrt (nlen2); + dd = 2 * vdotn_v1 / nlen2; + vx = vx - dd * l_seg; + vz = vz - dd * ww[ii]; + break; + case 2: /* Right vertical mirror */ + nlen2 = l_seg * l_seg + ww[ii] * ww[ii]; + q = V2Q * (-2) * vdotn_v2 / sqrt (nlen2); + dd = 2 * vdotn_v2 / nlen2; + vx = vx + dd * l_seg; + vz = vz - dd * ww[ii]; + break; + case 3: /* Lower horizontal mirror */ + nlen2 = l_seg * l_seg + hh[ii] * hh[ii]; + q = V2Q * (-2) * vdotn_h1 / sqrt (nlen2); + dd = 2 * vdotn_h1 / nlen2; + vy = vy - dd * l_seg; + vz = vz - dd * hh[ii]; + break; + case 4: /* Upper horizontal mirror */ + nlen2 = l_seg * l_seg + hh[ii] * hh[ii]; + q = V2Q * (-2) * vdotn_h2 / sqrt (nlen2); + dd = 2 * vdotn_h2 / nlen2; + vy = vy + dd * l_seg; + vz = vz - dd * hh[ii]; + break; } /* Now compute reflectivity. */ - if((i <= 2 && mx == 0) || (i > 2 && my == 0)) - { + if ((i <= 2 && mx == 0) || (i > 2 && my == 0)) { x += hadj; /* Re-adjust origin */ ABSORB; } else { - double ref=1; - if (i <= 2) - { - double m = (mx > 0 ? mx : fabs(mx*w1/w1_in[ii])); - double par[] = {R0, Qcx, alphax, m, W}; - StdReflecFunc(q, par, &ref); + double ref = 1; + if (i <= 2) { + double m = (mx > 0 ? mx : fabs (mx * w1 / w1_in[ii])); + double par[] = { R0, Qcx, alphax, m, W }; + StdReflecFunc (q, par, &ref); if (ref > 0) p *= ref; else { x += hadj; /* Re-adjust origin */ - ABSORB; /* Cutoff ~ 1E-10 */ + ABSORB; /* Cutoff ~ 1E-10 */ } } else { - double m = (my > 0 ? my : fabs(my*h1/h1_in[ii])); - double par[] = {R0, Qcy, alphay, m, W}; - StdReflecFunc(q, par, &ref); + double m = (my > 0 ? my : fabs (my * h1 / h1_in[ii])); + double par[] = { R0, Qcy, alphay, m, W }; + StdReflecFunc (q, par, &ref); if (ref > 0) p *= ref; else { x += hadj; /* Re-adjust origin */ - ABSORB; /* Cutoff ~ 1E-10 */ + ABSORB; /* Cutoff ~ 1E-10 */ } } } - x += hadj; SCATTER; x -= hadj; + x += hadj; + SCATTER; + x -= hadj; } /* loop on reflections inside segment */ x += hadj; /* Re-adjust origin */ /* rotate neutron according to actual guide curvature */ if (rotation_h) { double nvx, nvy, nvz; - rotate(nvx,nvy,nvz, vx,vy,vz, -rotation_h, 0,1,0); - vx = nvx; vy=nvy; vz=nvz; + rotate (nvx, nvy, nvz, vx, vy, vz, -rotation_h, 0, 1, 0); + vx = nvx; + vy = nvy; + vz = nvz; } if (rotation_v) { double nvx, nvy, nvz; - rotate(nvx,nvy,nvz, vx,vy,vz, -rotation_v, 1,0,0); - vx = nvx; vy=nvy; vz=nvz; + rotate (nvx, nvy, nvz, vx, vy, vz, -rotation_v, 1, 0, 0); + vx = nvx; + vy = nvy; + vz = nvz; } } /* loop on segments */ - %} FINALLY %{ - free(w1c); - free(w2c); - free(ww); - free(hh); - free(whalf); - free(hhalf); - free(lwhalf); - free(lhhalf); - free(h1_in); - free(h2_out); - free(w1_in); - free(w2_out); + free (w1c); + free (w2c); + free (ww); + free (hh); + free (whalf); + free (hhalf); + free (lwhalf); + free (lhhalf); + free (h1_in); + free (h2_out); + free (w1_in); + free (w2_out); %} MCDISPLAY %{ - int i,ii; + int i, ii; - for (ii=0; ii < seg; ii++) - { - multiline(5, - -w1_in[ii]/2.0, -h1_in[ii]/2.0,l_seg*(double)ii, - -w2_out[ii]/2.0, -h2_out[ii]/2.0,l_seg*((double)ii+1.0), - -w2_out[ii]/2.0, h2_out[ii]/2.0,l_seg*((double)ii+1.0), - -w1_in[ii]/2.0, h1_in[ii]/2.0,l_seg*(double)ii, - -w1_in[ii]/2.0, -h1_in[ii]/2.0,l_seg*(double)ii); - multiline(5, - w1_in[ii]/2.0, -h1_in[ii]/2.0,l_seg*(double)ii, - w2_out[ii]/2.0, -h2_out[ii]/2.0,l_seg*((double)ii+1.0), - w2_out[ii]/2.0, h2_out[ii]/2.0,l_seg*((double)ii+1.0), - w1_in[ii]/2.0, h1_in[ii]/2.0,l_seg*(double)ii, - w1_in[ii]/2.0, -h1_in[ii]/2.0,l_seg*(double)ii); + for (ii = 0; ii < seg; ii++) { + multiline (5, -w1_in[ii] / 2.0, -h1_in[ii] / 2.0, l_seg * (double)ii, -w2_out[ii] / 2.0, -h2_out[ii] / 2.0, l_seg * ((double)ii + 1.0), -w2_out[ii] / 2.0, + h2_out[ii] / 2.0, l_seg * ((double)ii + 1.0), -w1_in[ii] / 2.0, h1_in[ii] / 2.0, l_seg * (double)ii, -w1_in[ii] / 2.0, -h1_in[ii] / 2.0, + l_seg * (double)ii); + multiline (5, w1_in[ii] / 2.0, -h1_in[ii] / 2.0, l_seg * (double)ii, w2_out[ii] / 2.0, -h2_out[ii] / 2.0, l_seg * ((double)ii + 1.0), w2_out[ii] / 2.0, + h2_out[ii] / 2.0, l_seg * ((double)ii + 1.0), w1_in[ii] / 2.0, h1_in[ii] / 2.0, l_seg * (double)ii, w1_in[ii] / 2.0, -h1_in[ii] / 2.0, + l_seg * (double)ii); } - line(-w1/2.0, -h1/2.0, 0.0, w1/2.0, -h1/2.0, 0.0); - line(-w1/2.0, h1/2.0, 0.0, w1/2.0, h1/2.0, 0.0); - for(i=0; i= whalf || y <= -hhalf || y >= hhalf) + if (x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) ABSORB; - for(;;) - { + for (;;) { /* Compute the dot products of v and n for the four mirrors. */ - av = -l*vx ; bv = f_h*vz; - ah = -l*vy ; bh = f_v*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 */ + av = -l * vx; + bv = f_h * vz; + ah = -l * vy; + bh = f_v * 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*f_h; cv2 = x*l; - ch1 = -hhalf*l - z*f_v; ch2 = y*l; + cv1 = -whalf * l - z * f_h; + cv2 = x * l; + ch1 = -hhalf * l - z * f_v; + ch2 = y * l; /* Compute intersection times. */ - t_min = (l - z)/vz; - /* printf(" (x,y,z)=(%g %g %g) (vx,vy,vz)=(%g %g %g) Exit time : %g \n", - x,y,z,vx,vy,vz,t_min); */ + t_min = (l - z) / vz; + /* printf(" (x,y,z)=(%g %g %g) (vx,vy,vz)=(%g %g %g) Exit time : %g \n", + x,y,z,vx,vy,vz,t_min); */ i = 0; - if(vdotn_v1 < 0 && (t_tmp = (cv1 + cv2)/vdotn_v1) < t_min) - { + if (vdotn_v1 < 0 && (t_tmp = (cv1 + cv2) / vdotn_v1) < t_min) { t_min = t_tmp; i = 1; -/* printf("Left vertical: t=%g \n",t_min); */ + /* printf("Left vertical: t=%g \n",t_min); */ } - if(vdotn_v2 < 0 && (t_tmp = (cv1 - cv2)/vdotn_v2) < t_min) - { + if (vdotn_v2 < 0 && (t_tmp = (cv1 - cv2) / vdotn_v2) < t_min) { t_min = t_tmp; i = 2; -/* printf("Right vertical: t=%g \n",t_min); */ + /* printf("Right vertical: t=%g \n",t_min); */ } - if(vdotn_h1 < 0 && (t_tmp = (ch1 + ch2)/vdotn_h1) < t_min) - { + if (vdotn_h1 < 0 && (t_tmp = (ch1 + ch2) / vdotn_h1) < t_min) { t_min = t_tmp; i = 3; -/* printf("Lower horizontal: t=%g \n",t_min); */ + /* printf("Lower horizontal: t=%g \n",t_min); */ } - if(vdotn_h2 < 0 && (t_tmp = (ch1 - ch2)/vdotn_h2) < t_min) - { + if (vdotn_h2 < 0 && (t_tmp = (ch1 - ch2) / vdotn_h2) < t_min) { t_min = t_tmp; i = 4; -/* printf("Upper horizontal: t=%g \n",t_min); */ + /* printf("Upper horizontal: t=%g \n",t_min); */ } - if(i == 0) - break; /* Neutron left guide. */ - PROP_DT(t_min); + if (i == 0) + break; /* Neutron left guide. */ + PROP_DT (t_min); -/* ******* Recalculate dot products ********* */ + /* ******* Recalculate dot products ********* */ - d_z=DEG2RAD*eta_z*randnorm(); - d_xy=DEG2RAD*eta_xy*randnorm(); + d_z = DEG2RAD * eta_z * randnorm (); + d_xy = DEG2RAD * eta_xy * randnorm (); -/* Now the normal vector is rotated. To 1st order in waviness and 2nd order - in f=(w2-w1)/l and (f times waviness) the rotation matrix for - the left vertical mirror is: + /* Now the normal vector is rotated. To 1st order in waviness and 2nd order + in f=(w2-w1)/l and (f times waviness) the rotation matrix for + the left vertical mirror is: - { 1 d_xy d_z } - { -d_xy 1 d_xy f_h } (for the right vertical mirror the ) - { d_z -d_xy f_h 1 } (terms d_xy f_h changes sign ) + { 1 d_xy d_z } + { -d_xy 1 d_xy f_h } (for the right vertical mirror the ) + { d_z -d_xy f_h 1 } (terms d_xy f_h changes sign ) -the left vertical normal vector is { -l, 0, f_h } + the left vertical normal vector is { -l, 0, f_h } -giving the rotated normal vector { -l + f_h d_z, l d_xy, f_h - l d_z } + giving the rotated normal vector { -l + f_h d_z, l d_xy, f_h - l d_z } -for the right vertical mirror the normal vector is { l, 0, f_h } + for the right vertical mirror the normal vector is { l, 0, f_h } -and the rotated right normal vector is { l + f_h d_z, -l d_xy, f_h + l d_z } + and the rotated right normal vector is { l + f_h d_z, -l d_xy, f_h + l d_z } -The top horizontal mirror must be (something like) + The top horizontal mirror must be (something like) - { 1 -d_xy d_xy f_h } - { d_xy 1 d_z } (for the bottom horizontal mirror the ) - { -d_xy f_h d_z 1 } (terms d_xy f_h changes sign ) + { 1 -d_xy d_xy f_h } + { d_xy 1 d_z } (for the bottom horizontal mirror the ) + { -d_xy f_h d_z 1 } (terms d_xy f_h changes sign ) -The top horizontal normal vector is { 0, -l, f_v} + The top horizontal normal vector is { 0, -l, f_v} -giving the rotated normal vector { l d_xy, -l + f_v d_z, f_v - l d_z } + giving the rotated normal vector { l d_xy, -l + f_v d_z, f_v - l d_z } -for the bottom mirror the normal vector is { 0, l, f_h } + for the bottom mirror the normal vector is { 0, l, f_h } -and the rotated bottom normal vector is { -l d_xy, l + f_v d_z, f_v + l d_z } + and the rotated bottom normal vector is { -l d_xy, l + f_v d_z, f_v + l d_z } -*/ + */ - switch(i) - { - case 1: /* Left vertical mirror */ - m0=m1; w=W1; alpha0=alpha1; - norm_n2 = (-l+d_z*f_h)*(-l+d_z*f_h)+(d_xy*l)*(d_xy*l) - +(f_h-d_z*l)*(f_h-d_z*l); /* Square of length of n vector */ - vdotn = (vx*(-l+f_h*d_z)+ vy*(l*d_xy)+ vz*(f_h-l*d_z) ); - q = 2 * V2Q * fabs(vdotn) / sqrt(norm_n2); - dvx = -2*(-l+f_h*d_z)*vdotn/norm_n2; - dvy = -2*(l*d_xy)*vdotn/norm_n2; - dvz = -2*(f_h-l*d_z)*vdotn/norm_n2; - break; - case 2: /* Right vertical mirror */ - m0=m2; w=W2; alpha0=alpha2; - norm_n2 = (l+d_z*f_h)*(l+d_z*f_h)+(-d_xy*l)*(-d_xy*l) - +(f_h+d_z*l)*(f_h+d_z*l); /* Square of length of n vector */ - vdotn = (vx*(l+f_h*d_z)+ vy*(-l*d_xy)+ vz*(f_h+l*d_z) ); - q = 2 * V2Q * fabs(vdotn) / sqrt(norm_n2); - dvx = -2*(l+f_h*d_z)*vdotn/norm_n2; - dvy = -2*(-l*d_xy)*vdotn/norm_n2; - dvz = -2*(f_h+l*d_z)*vdotn/norm_n2; - break; - case 3: /* Lower horizontal mirror */ - m0=m3; w=W3; alpha0=alpha3; - norm_n2 = (d_xy*l)*(d_xy*l)+(-l+d_z*f_v)*(-l+d_z*f_v) - +(f_v-d_z*l)*(f_v-d_z*l); /* Square of length of n vector */ - vdotn = (vx*(l*d_xy)+ vy*(-l+f_v*d_z)+ vz*(f_v-l*d_z) ); - q = 2 * V2Q * fabs(vdotn) / sqrt(norm_n2); - dvx = -2*(l*d_xy)*vdotn/norm_n2; - dvy = -2*(-l+f_v*d_z)*vdotn/norm_n2; - dvz = -2*(f_v-l*d_z)*vdotn/norm_n2; - break; - case 4: /* Upper horizontal mirror */ - m0=m4; w=W4; alpha0=alpha4; - norm_n2 = (-d_xy*l)*(-d_xy*l)+(l+d_z*f_v)*(l+d_z*f_v) - +(f_v+d_z*l)*(f_v+d_z*l); /* Square of length of n vector */ - vdotn = (vx*(-l*d_xy)+ vy*(l+f_v*d_z)+ vz*(f_v+l*d_z) ); - q = 2 * V2Q * fabs(vdotn) / sqrt(norm_n2); - dvx = -2*(-l*d_xy)*vdotn/norm_n2; - dvy = -2*(l+f_v*d_z)*vdotn/norm_n2; - dvz = -2*(f_v+l*d_z)*vdotn/norm_n2; - break; - default: - printf("Fatal error: No guide wall hit"); - exit(1); + switch (i) { + case 1: /* Left vertical mirror */ + m0 = m1; + w = W1; + alpha0 = alpha1; + norm_n2 = (-l + d_z * f_h) * (-l + d_z * f_h) + (d_xy * l) * (d_xy * l) + (f_h - d_z * l) * (f_h - d_z * l); /* Square of length of n vector */ + vdotn = (vx * (-l + f_h * d_z) + vy * (l * d_xy) + vz * (f_h - l * d_z)); + q = 2 * V2Q * fabs (vdotn) / sqrt (norm_n2); + dvx = -2 * (-l + f_h * d_z) * vdotn / norm_n2; + dvy = -2 * (l * d_xy) * vdotn / norm_n2; + dvz = -2 * (f_h - l * d_z) * vdotn / norm_n2; + break; + case 2: /* Right vertical mirror */ + m0 = m2; + w = W2; + alpha0 = alpha2; + norm_n2 = (l + d_z * f_h) * (l + d_z * f_h) + (-d_xy * l) * (-d_xy * l) + (f_h + d_z * l) * (f_h + d_z * l); /* Square of length of n vector */ + vdotn = (vx * (l + f_h * d_z) + vy * (-l * d_xy) + vz * (f_h + l * d_z)); + q = 2 * V2Q * fabs (vdotn) / sqrt (norm_n2); + dvx = -2 * (l + f_h * d_z) * vdotn / norm_n2; + dvy = -2 * (-l * d_xy) * vdotn / norm_n2; + dvz = -2 * (f_h + l * d_z) * vdotn / norm_n2; + break; + case 3: /* Lower horizontal mirror */ + m0 = m3; + w = W3; + alpha0 = alpha3; + norm_n2 = (d_xy * l) * (d_xy * l) + (-l + d_z * f_v) * (-l + d_z * f_v) + (f_v - d_z * l) * (f_v - d_z * l); /* Square of length of n vector */ + vdotn = (vx * (l * d_xy) + vy * (-l + f_v * d_z) + vz * (f_v - l * d_z)); + q = 2 * V2Q * fabs (vdotn) / sqrt (norm_n2); + dvx = -2 * (l * d_xy) * vdotn / norm_n2; + dvy = -2 * (-l + f_v * d_z) * vdotn / norm_n2; + dvz = -2 * (f_v - l * d_z) * vdotn / norm_n2; + break; + case 4: /* Upper horizontal mirror */ + m0 = m4; + w = W4; + alpha0 = alpha4; + norm_n2 = (-d_xy * l) * (-d_xy * l) + (l + d_z * f_v) * (l + d_z * f_v) + (f_v + d_z * l) * (f_v + d_z * l); /* Square of length of n vector */ + vdotn = (vx * (-l * d_xy) + vy * (l + f_v * d_z) + vz * (f_v + l * d_z)); + q = 2 * V2Q * fabs (vdotn) / sqrt (norm_n2); + dvx = -2 * (-l * d_xy) * vdotn / norm_n2; + dvy = -2 * (l + f_v * d_z) * vdotn / norm_n2; + dvz = -2 * (f_v + l * d_z) * vdotn / norm_n2; + break; + default: + printf ("Fatal error: No guide wall hit"); + exit (1); } /* Now compute reflectivity. */ { - double par[] = {R0, Qc, alpha0, m0, w}; - StdReflecFunc(q, par, &R); - if (R > 0) - p *= R; - else ABSORB; + double par[] = { R0, Qc, alpha0, m0, w }; + StdReflecFunc (q, par, &R); + if (R > 0) + p *= R; + else + ABSORB; } vx += dvx; vy += dvy; @@ -279,23 +292,13 @@ MCDISPLAY double x; int i; - - 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); + 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 diff --git a/mcstas-comps/optics/He3_cell.comp b/mcstas-comps/optics/He3_cell.comp index f13a37cebb..ae88bf15cf 100644 --- a/mcstas-comps/optics/He3_cell.comp +++ b/mcstas-comps/optics/He3_cell.comp @@ -55,102 +55,102 @@ DECLARE INITIALIZE %{ if (radius && !xwidth && !yheight && length) { - geom=0; // Cylindrical geometry + geom = 0; // Cylindrical geometry } else if (radius && !xwidth && !yheight && !length) { - geom=1; // Spherical geometry + geom = 1; // Spherical geometry } else if (!radius && xwidth && yheight && length) { // Box geometry - geom=2; + geom = 2; } else { - fprintf(stderr,"You are runnning He3_cell component %s with a mixed cylindrical/box shape geometry, this is not supported!\n",_comp->_name); - exit(-1); + fprintf (stderr, "You are runnning He3_cell component %s with a mixed cylindrical/box shape geometry, this is not supported!\n", _comp->_name); + exit (-1); } %} TRACE %{ - double t0,t1; /* time that neutron enters and leaves gas (s) */ - double v,lambda; /* neutron velocity and wavelength (ms-1, Anstroms) */ - double l_full; /* path length of neutron through gas (m) */ - double dt0; /* time neutron spends in the gas (s) */ - double opacity; /* opacity of the gas for this neutron (dimless) */ - double omega; /* angle through which polarisation precesses - over the path through the cell (radians) */ - double px,py,pz; /* auxilliary vector polarisation (-1 to +1) */ - double bnx,bny,bnz; /* normal vector parallel to the magnetic field*/ - - const double gyro = 1.832e8; /*absolute value of the gyromagnetic ratio of the neutron (1/(s.T))*/ + double t0, t1; /* time that neutron enters and leaves gas (s) */ + double v, lambda; /* neutron velocity and wavelength (ms-1, Anstroms) */ + double l_full; /* path length of neutron through gas (m) */ + double dt0; /* time neutron spends in the gas (s) */ + double opacity; /* opacity of the gas for this neutron (dimless) */ + double omega; /* angle through which polarisation precesses + over the path through the cell (radians) */ + double px, py, pz; /* auxilliary vector polarisation (-1 to +1) */ + double bnx, bny, bnz; /* normal vector parallel to the magnetic field*/ + + const double gyro = 1.832e8; /*absolute value of the gyromagnetic ratio of the neutron (1/(s.T))*/ const double opac_cnv = 7.33; /*opacity conversion factor to express opacity in (bar.m.angstrom)*/ int intersect; if (!geom) { // Cylindrical geometry - /* calculate the intersection times with the volume of gas, if the neutron - goes through the cell, continue with calculation otherwise all done. - Note that y and z are swapped - this is because the cylindrical axis of - a 3He cell lies along the beam. */ - intersect=cylinder_intersect(&t0,&t1,x,z,y,vx,vz,vy,radius,length); - } else if (geom==1) { + /* calculate the intersection times with the volume of gas, if the neutron + goes through the cell, continue with calculation otherwise all done. + Note that y and z are swapped - this is because the cylindrical axis of + a 3He cell lies along the beam. */ + intersect = cylinder_intersect (&t0, &t1, x, z, y, vx, vz, vy, radius, length); + } else if (geom == 1) { // Spherical geometry - intersect=sphere_intersect(&t0,&t1,x,y,z,vx,vy,vz,radius); - } else if (geom==2) { + intersect = sphere_intersect (&t0, &t1, x, y, z, vx, vy, vz, radius); + } else if (geom == 2) { // Box geometry - intersect=box_intersect(&t0,&t1,x,y,z,vx,vy,vz,xwidth,yheight,length); + intersect = box_intersect (&t0, &t1, x, y, z, vx, vy, vz, xwidth, yheight, length); } - - if(intersect) - { + + if (intersect) { /* Calculate the neutron velocity and wavelength */ - v=sqrt(vx*vx+vy*vy+vz*vz); - lambda=2*PI/(V2K*v); + v = sqrt (vx * vx + vy * vy + vz * vz); + lambda = 2 * PI / (V2K * v); /* Calculate the path length of the neutron through the gas */ - dt0=t1-t0; - l_full=v*dt0; + dt0 = t1 - t0; + l_full = v * dt0; /* Calculate the opacity of the cell for the path length travelled */ - opacity=pressure*l_full*lambda*opac_cnv; + opacity = pressure * l_full * lambda * opac_cnv; /* propagate the polarisation accross the cell (assuming a constant magnetic field). The actual interaction point is not taken into account as only the parallel and perpendicular components are important. */ - omega=dt0*gyro*sqrt(bx*bx+by*by+bz*bz); - rotate(px,py,pz,sx,sy,sz,omega,bx,by,bz); - sx=px; - sy=py; - sz=pz; + omega = dt0 * gyro * sqrt (bx * bx + by * by + bz * bz); + rotate (px, py, pz, sx, sy, sz, omega, bx, by, bz); + sx = px; + sy = py; + sz = pz; /* adjust the neutron weight according to spin state relative to the 3He nuclei - antiparallel spins are as good as absorbed, whereas parallel spins are transmitted (depending upon degree of polarisation of gas */ - bnx=bx;bny=by;bnz=bz; - NORM(bnx,bny,bnz); - double pm1=scalar_prod(sx,sy,sz,bnx,bny,bnz); - double phiu,phid,T, Tup,Tdown; + bnx = bx; + bny = by; + bnz = bz; + NORM (bnx, bny, bnz); + double pm1 = scalar_prod (sx, sy, sz, bnx, bny, bnz); + double phiu, phid, T, Tup, Tdown; - phiu=((pm1)+1)/2.0; - phid=(1-(pm1))/2.0; - Tup=exp(-opacity*(1.0-p3he)); - Tdown=exp(-opacity*(1.0+p3he)); + phiu = ((pm1) + 1) / 2.0; + phid = (1 - (pm1)) / 2.0; + Tup = exp (-opacity * (1.0 - p3he)); + Tdown = exp (-opacity * (1.0 + p3he)); - p*=phiu*Tup + phid*Tdown; + p *= phiu * Tup + phid * Tdown; /*set the outgoing polarization vector without touching the part perpendicular to the polarisation of the gas . Perpendicular comp: P_=S - P// = S - (S.b_n)b_n Parallel comp: P// = Pn bn, where Pn is the polarisation efficiency.*/ - px=sx - pm1*bnx; - py=sy - pm1*bny; - pz=sz - pm1*bnz; - + px = sx - pm1 * bnx; + py = sy - pm1 * bny; + pz = sz - pm1 * bnz; - double Pn=(Tup-Tdown)/(Tup+Tdown); - sx=px + Pn*bnx; - sy=py + Pn*bny; - sz=pz + Pn*bnz; + double Pn = (Tup - Tdown) / (Tup + Tdown); + sx = px + Pn * bnx; + sy = py + Pn * bny; + sz = pz + Pn * bnz; SCATTER; } @@ -159,16 +159,16 @@ TRACE MCDISPLAY %{ if (!geom) { - circle("xy",0.0,0.0,-length/2.0,radius); - circle("xy",0.0,0.0,length/2.0,radius); - line(0.0,radius,-length/2.0,0.0,radius,length/2.0); - line(radius,0.0,-length/2.0,radius,0.0,length/2.0); - line(0.0,-radius,-length/2.0,0.0,-radius,length/2.0); - line(-radius,0.0,-length/2.0,-radius,0.0,length/2.0); - } else if(geom==1) { - sphere(0,0,0,radius); - } else if(geom==2) { - box(0,0,0,xwidth,yheight,length,0,0,0,1); + circle ("xy", 0.0, 0.0, -length / 2.0, radius); + circle ("xy", 0.0, 0.0, length / 2.0, radius); + line (0.0, radius, -length / 2.0, 0.0, radius, length / 2.0); + line (radius, 0.0, -length / 2.0, radius, 0.0, length / 2.0); + line (0.0, -radius, -length / 2.0, 0.0, -radius, length / 2.0); + line (-radius, 0.0, -length / 2.0, -radius, 0.0, length / 2.0); + } else if (geom == 1) { + sphere (0, 0, 0, radius); + } else if (geom == 2) { + box (0, 0, 0, xwidth, yheight, length, 0, 0, 0, 1); } %} diff --git a/mcstas-comps/optics/Mask.comp b/mcstas-comps/optics/Mask.comp index 656fc38066..8fa7a730dc 100644 --- a/mcstas-comps/optics/Mask.comp +++ b/mcstas-comps/optics/Mask.comp @@ -60,10 +60,9 @@ SETTING PARAMETERS (xwidth, yheight, string mask, invert=0, virtual=0) SHARE %{ %include "read_table-lib" -#if USE_PNG -#include -#endif - + #if USE_PNG + #include + #endif %} DECLARE @@ -82,190 +81,182 @@ DECLARE INITIALIZE %{ - + /*do some checks on input parameters*/ - if (invert){ + if (invert) { /*invert should be either 0 or one*/ - invert=1; + invert = 1; } - do{ -#if USE_PNG - if (strstr(mask+strlen(mask)-4,".png")!=NULL){ + do { + #if USE_PNG + if (strstr (mask + strlen (mask) - 4, ".png") != NULL) { /*filename ends with .png - use libpng to read the mask*/ /*read file and insert mask values into table*/ /*copied form libpng docs*/ - int is_png=0; - const int number=1; + int is_png = 0; + const int number = 1; char header[8]; - const int ERROR=1; - const int NOT_PNG=2; + const int ERROR = 1; + const int NOT_PNG = 2; - FILE *fp = fopen(mask, "rb"); - if (!fp){ - fprintf(stderr,"Error(%s): cant open file %s for reading\n", NAME_CURRENT_COMP,mask); - exit(1); + FILE* fp = fopen (mask, "rb"); + if (!fp) { + fprintf (stderr, "Error(%s): cant open file %s for reading\n", NAME_CURRENT_COMP, mask); + exit (1); } - fread(header, 1, number, fp); - is_png = !png_sig_cmp(header, 0, number); + fread (header, 1, number, fp); + is_png = !png_sig_cmp (header, 0, number); - if (!is_png){ - fprintf(stderr,"Error(%s): %s does not appear to be a png file\n", NAME_CURRENT_COMP,mask); - exit(1); + if (!is_png) { + fprintf (stderr, "Error(%s): %s does not appear to be a png file\n", NAME_CURRENT_COMP, mask); + exit (1); } - //png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn); - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + // png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn); + png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); /*last two arguments are error handling functions*/ - if (!png_ptr){ - fprintf(stderr,"Error(%s): Could not set up the png reading buffer structure\n", NAME_CURRENT_COMP); - exit(1); + if (!png_ptr) { + fprintf (stderr, "Error(%s): Could not set up the png reading buffer structure\n", NAME_CURRENT_COMP); + exit (1); } - png_init_io(png_ptr,fp); + png_init_io (png_ptr, fp); /*we used number bytes of the png file to indentify it as being png*/ - png_set_sig_bytes(png_ptr, number); + png_set_sig_bytes (png_ptr, number); - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr){ - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - exit(1); + png_infop info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) { + png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + exit (1); } - /*do read the image using the high level interface and apply the transform + /*do read the image using the high level interface and apply the transform * toexpand 1, 2, and 4 bits to bytes*/ - png_read_png(png_ptr,info_ptr, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_EXPAND, NULL); + png_read_png (png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); /*image is now available in png_ptr - extfact dimensions*/ - int height=png_get_image_height(png_ptr,info_ptr); - int width=png_get_image_width(png_ptr,info_ptr); - int bd=png_get_bit_depth(png_ptr,info_ptr); - if(bd<8){ - bd=8; + int height = png_get_image_height (png_ptr, info_ptr); + int width = png_get_image_width (png_ptr, info_ptr); + int bd = png_get_bit_depth (png_ptr, info_ptr); + if (bd < 8) { + bd = 8; } - unsigned int ct=png_get_color_type(png_ptr,info_ptr); + unsigned int ct = png_get_color_type (png_ptr, info_ptr); - Table_Init(&(table),height,width); + Table_Init (&(table), height, width); - png_bytep *row_pointers=png_get_rows(png_ptr,info_ptr); - printf("I just read a png image with size %d by %d, bit depth %d, and color type %d\n",width, height, bd, ct); - fclose(fp); + png_bytep* row_pointers = png_get_rows (png_ptr, info_ptr); + printf ("I just read a png image with size %d by %d, bit depth %d, and color type %d\n", width, height, bd, ct); + fclose (fp); - int j,r,c,tuplelen; + int j, r, c, tuplelen; unsigned long tuple_normalizer; - switch (ct){ - case PNG_COLOR_TYPE_GRAY: - if(bd==8){ - tuplelen=1; - tuple_normalizer=0xFF; - }else if(bd==16){ - tuplelen=2; - tuple_normalizer=0xFFFF; - } - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - if(bd==8){ - tuplelen=2; - tuple_normalizer=0xFFFF; - }else if(bd==16){ - tuplelen=2; - tuple_normalizer=0xFFFFFFFF; - } - break; - case PNG_COLOR_TYPE_RGB: - if(bd==8){ - tuplelen=3; - tuple_normalizer=0xFFFFFF; - }else if(bd==16){ - tuplelen=3; - tuple_normalizer=0xFFFFFFFFFFFF; - } - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - if(bd==8){ - tuplelen=4; - tuple_normalizer=0xFFFFFFFF; - }else if (bd==16){ - tuplelen=4; - tuple_normalizer=0xFFFFFFFFFFFFFFFF; - } - break; - default: - fprintf(stderr,"Error (%s): Unsupported type of png image (allowed are GRAY, GRAY_ALPHA, RGB, RGB_ALPHA)\n","NAME_CURRENT_COMP"); - exit(1); + switch (ct) { + case PNG_COLOR_TYPE_GRAY: + if (bd == 8) { + tuplelen = 1; + tuple_normalizer = 0xFF; + } else if (bd == 16) { + tuplelen = 2; + tuple_normalizer = 0xFFFF; + } + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (bd == 8) { + tuplelen = 2; + tuple_normalizer = 0xFFFF; + } else if (bd == 16) { + tuplelen = 2; + tuple_normalizer = 0xFFFFFFFF; + } + break; + case PNG_COLOR_TYPE_RGB: + if (bd == 8) { + tuplelen = 3; + tuple_normalizer = 0xFFFFFF; + } else if (bd == 16) { + tuplelen = 3; + tuple_normalizer = 0xFFFFFFFFFFFF; + } + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + if (bd == 8) { + tuplelen = 4; + tuple_normalizer = 0xFFFFFFFF; + } else if (bd == 16) { + tuplelen = 4; + tuple_normalizer = 0xFFFFFFFFFFFFFFFF; + } + break; + default: + fprintf (stderr, "Error (%s): Unsupported type of png image (allowed are GRAY, GRAY_ALPHA, RGB, RGB_ALPHA)\n", "NAME_CURRENT_COMP"); + exit (1); } - for (r=0;rxmin && xymin && y xmin && x < xmax && y > ymin && y < ymax) { + i = floor ((x - xmin) * nx / (xwidth)); + j = floor ((y - ymin) * ny / (yheight)); + if (invert) { + masking = Table_Index (table, j, i); + } else { + masking = 1.0 - Table_Index (table, j, i); } - if(!virtual){ - p*=masking; + if (!virtual) { + p *= masking; } SCATTER; } - - - %} MCDISPLAY %{ /* A bit ugly; hard-coded dimensions. */ - - rectangle("xy",0,0,0,xwidth,yheight); + + rectangle ("xy", 0, 0, 0, xwidth, yheight); %} END diff --git a/mcstas-comps/optics/Mirror.comp b/mcstas-comps/optics/Mirror.comp index 872084548c..d4490598b7 100644 --- a/mcstas-comps/optics/Mirror.comp +++ b/mcstas-comps/optics/Mirror.comp @@ -65,52 +65,52 @@ SHARE DECLARE %{ -t_Table pTable; + t_Table pTable; %} INITIALIZE %{ -if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) { - if (Table_Read(&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ - exit(fprintf(stderr,"Mirror: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) { + if (Table_Read (&pTable, reflect, 1) <= 0) /* read 1st block data from file into pTable */ + exit (fprintf (stderr, "Mirror: %s: can not read file %s\n", NAME_CURRENT_COMP, reflect)); } %} TRACE %{ double dt, q, B; - char intersect=0; + char intersect = 0; /* First check if neutron has the right direction. */ - if(vz != 0.0 && (dt = -z/vz) >= 0) - { + if (vz != 0.0 && (dt = -z / vz) >= 0) { double old_x = x, old_y = y; - x += vx*dt; - y += vy*dt; + x += vx * dt; + y += vy * dt; /* Now check if neutron intersects mirror. */ - intersect = (center == 0 ? - x >= 0 && x <= xwidth && y >= 0 && y <= yheight : - x>= -xwidth/2 && x<=xwidth/2 && y >= -yheight/2 && y <= yheight/2); + intersect = (center == 0 ? x >= 0 && x <= xwidth && y >= 0 && y <= yheight : x >= -xwidth / 2 && x <= xwidth / 2 && y >= -yheight / 2 && y <= yheight / 2); if (intersect) { z = 0; t += dt; - q = fabs(2*vz*V2Q); + q = fabs (2 * vz * V2Q); vz = -vz; /* Reflectivity (see component Guide). */ - if (reflect && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) - TableReflecFunc(q, &pTable, &B); + if (reflect && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) + TableReflecFunc (q, &pTable, &B); else { - double par[] = {R0, Qc, alpha, m, W}; - StdReflecFunc(q, par, &B); + double par[] = { R0, Qc, alpha, m, W }; + StdReflecFunc (q, par, &B); } /* now handle either probability when transmit or weight */ if (!transmit) { - if (B <= 0) ABSORB; + if (B <= 0) + ABSORB; p *= B; SCATTER; } else { /* transmit when rand > B: restore original vz */ - if (B == 0 || rand01() >= B) { vz = -vz; } + if (B == 0 || rand01 () >= B) { + vz = -vz; + } SCATTER; } } @@ -126,18 +126,18 @@ TRACE MCDISPLAY %{ double xmax, xmin, ymax, ymin; - if (center == 0) { - xmax= xwidth; xmin=0; - ymax= yheight; ymin=0; + xmax = xwidth; + xmin = 0; + ymax = yheight; + ymin = 0; } else { - xmax= xwidth/2; xmin=-xmax; - ymax= yheight/2; ymin=-ymax; + xmax = xwidth / 2; + xmin = -xmax; + ymax = yheight / 2; + ymin = -ymax; } - polygon(4, (double)xmin, (double)ymin, 0.0, - (double)xmax, (double)ymin, 0.0, - (double)xmax, (double)ymax, 0.0, - (double)xmin, (double)ymax, 0.0); + polygon (4, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0); %} END diff --git a/mcstas-comps/optics/Monochromator_curved.comp b/mcstas-comps/optics/Monochromator_curved.comp index 5bc51ec9ba..625bc0603c 100644 --- a/mcstas-comps/optics/Monochromator_curved.comp +++ b/mcstas-comps/optics/Monochromator_curved.comp @@ -101,12 +101,13 @@ RV=0, RH=0, DM=0, mosaic=0, width=0, height=0, verbose=0, order=0) SHARE %{ -#pragma acc routine -double GAUSS_monocurved(double x, double mean, double rms){ - return (exp(-((x)-(mean))*((x)-(mean))/(2*(rms)*(rms)))/(sqrt(2*PI)*(rms))); -} + #pragma acc routine + double + GAUSS_monocurved (double x, double mean, double rms) { + return (exp (-((x) - (mean)) * ((x) - (mean)) / (2 * (rms) * (rms))) / (sqrt (2 * PI) * (rms))); + } -%include "read_table-lib" + %include "read_table-lib" %} USERVARS %{ @@ -126,8 +127,8 @@ DECLARE t_Table tTable; int rTableFlag; int tTableFlag; - double *tiltH; - double *tiltV; + double* tiltH; + double* tiltV; char ncol_var[128]; char nrow_var[128]; %} @@ -137,150 +138,168 @@ INITIALIZE int i; if (mosaic != 0) { - mos_rms_y = MIN2RAD*mosaic/sqrt(8*log(2)); - mos_rms_z = mos_rms_y; } - else { - mos_rms_y = MIN2RAD*mosaich/sqrt(8*log(2)); - mos_rms_z = MIN2RAD*mosaicv/sqrt(8*log(2)); } + mos_rms_y = MIN2RAD * mosaic / sqrt (8 * log (2)); + mos_rms_z = mos_rms_y; + } else { + mos_rms_y = MIN2RAD * mosaich / sqrt (8 * log (2)); + mos_rms_z = MIN2RAD * mosaicv / sqrt (8 * log (2)); + } mos_rms_max = mos_rms_y > mos_rms_z ? mos_rms_y : mos_rms_z; mono_Q = Q; - if (DM != 0) mono_Q = 2*PI/DM; - - if (mono_Q <= 0) { fprintf(stderr,"Monochromator_curved: %s: Error scattering vector Q = 0\n", NAME_CURRENT_COMP); exit(-1); } - if (r0 < 0) { fprintf(stderr,"Monochromator_curved: %s: Error reflectivity r0 is negative\n", NAME_CURRENT_COMP); exit(-1); } - if (r0 == 0) { fprintf(stderr,"Monochromator_curved: %s: Reflectivity r0 is null. Ignoring component.\n", NAME_CURRENT_COMP); } - if (NH*NV == 0) { fprintf(stderr,"Monochromator_curved: %s: no slabs ??? (NH or NV=0)\n", NAME_CURRENT_COMP); exit(-1); } - - - if (verbose && r0) - { - printf("Monochromator_curved: component %s Q=%.3g Angs-1 (DM=%.4g Angs)\n", NAME_CURRENT_COMP, mono_Q, 2*PI/mono_Q); - if (NH*NV == 1) printf(" flat.\n"); - else - { if (NH > 1) - { printf(" horizontal: %i blades", (int)NH); - if (RH != 0) printf(" focusing with RH=%.3g [m]", RH); - printf("\n"); + if (DM != 0) + mono_Q = 2 * PI / DM; + + if (mono_Q <= 0) { + fprintf (stderr, "Monochromator_curved: %s: Error scattering vector Q = 0\n", NAME_CURRENT_COMP); + exit (-1); + } + if (r0 < 0) { + fprintf (stderr, "Monochromator_curved: %s: Error reflectivity r0 is negative\n", NAME_CURRENT_COMP); + exit (-1); + } + if (r0 == 0) { + fprintf (stderr, "Monochromator_curved: %s: Reflectivity r0 is null. Ignoring component.\n", NAME_CURRENT_COMP); + } + if (NH * NV == 0) { + fprintf (stderr, "Monochromator_curved: %s: no slabs ??? (NH or NV=0)\n", NAME_CURRENT_COMP); + exit (-1); + } + + if (verbose && r0) { + printf ("Monochromator_curved: component %s Q=%.3g Angs-1 (DM=%.4g Angs)\n", NAME_CURRENT_COMP, mono_Q, 2 * PI / mono_Q); + if (NH * NV == 1) + printf (" flat.\n"); + else { + if (NH > 1) { + printf (" horizontal: %i blades", (int)NH); + if (RH != 0) + printf (" focusing with RH=%.3g [m]", RH); + printf ("\n"); } - if (NV > 1) - { printf(" vertical: %i blades", (int)NV); - if (RV != 0) printf(" focusing with RV=%.3g [m]", RV); - printf("\n"); + if (NV > 1) { + printf (" vertical: %i blades", (int)NV); + if (RV != 0) + printf (" focusing with RV=%.3g [m]", RV); + printf ("\n"); } } } - if (reflect != NULL && r0 && strlen(reflect) && strcmp(reflect,"NULL") && strcmp(reflect,"0")) - { - if (verbose) fprintf(stdout, "Monochromator_curved: %s: Reflectivity data (k, R) from %s\n", NAME_CURRENT_COMP, reflect); - Table_Read(&rTable, reflect, 1); /* read 1st block data from file into rTable */ - Table_Rebin(&rTable); /* rebin as evenly, increasing array */ - if (rTable.rows < 2) Table_Free(&rTable); - if (verbose) Table_Info(rTable); + if (reflect != NULL && r0 && strlen (reflect) && strcmp (reflect, "NULL") && strcmp (reflect, "0")) { + if (verbose) + fprintf (stdout, "Monochromator_curved: %s: Reflectivity data (k, R) from %s\n", NAME_CURRENT_COMP, reflect); + Table_Read (&rTable, reflect, 1); /* read 1st block data from file into rTable */ + Table_Rebin (&rTable); /* rebin as evenly, increasing array */ + if (rTable.rows < 2) + Table_Free (&rTable); + if (verbose) + Table_Info (rTable); rTableFlag = 1; } else { rTableFlag = 0; } - if (transmit != NULL && strlen(transmit) && strcmp(transmit,"NULL") && strcmp(transmit,"0")) - { - if (verbose) fprintf(stdout, "Monochromator_curved: %s: Transmission data (k, T) from %s\n", NAME_CURRENT_COMP, transmit); - Table_Read(&tTable, transmit, 1); /* read 1st block data from file into rTable */ - Table_Rebin(&tTable); /* rebin as evenly, increasing array */ - if (tTable.rows < 2) Table_Free(&tTable); - if (verbose) Table_Info(tTable); + if (transmit != NULL && strlen (transmit) && strcmp (transmit, "NULL") && strcmp (transmit, "0")) { + if (verbose) + fprintf (stdout, "Monochromator_curved: %s: Transmission data (k, T) from %s\n", NAME_CURRENT_COMP, transmit); + Table_Read (&tTable, transmit, 1); /* read 1st block data from file into rTable */ + Table_Rebin (&tTable); /* rebin as evenly, increasing array */ + if (tTable.rows < 2) + Table_Free (&tTable); + if (verbose) + Table_Info (tTable); tTableFlag = 1; } else { tTableFlag = 0; } - if (width == 0) SlabWidth = zwidth; - else SlabWidth = (width+gap)/NH - gap; - if (height == 0) SlabHeight = yheight; - else SlabHeight = (height+gap)/NV - gap; + if (width == 0) + SlabWidth = zwidth; + else + SlabWidth = (width + gap) / NH - gap; + if (height == 0) + SlabHeight = yheight; + else + SlabHeight = (height + gap) / NV - gap; - tiltH=calloc((int)2*(NH+1),sizeof(double)); - tiltV=calloc((int)2*(NV+1),sizeof(double)); + tiltH = calloc ((int)2 * (NH + 1), sizeof (double)); + tiltV = calloc ((int)2 * (NV + 1), sizeof (double)); - if (!tiltH) printf("Monochromator_curved: %s: Warning: not enough memory to allocate tilts (NH=%i).\n", NAME_CURRENT_COMP, NH); + if (!tiltH) + printf ("Monochromator_curved: %s: Warning: not enough memory to allocate tilts (NH=%i).\n", NAME_CURRENT_COMP, NH); else if (RH) { /* pre-compute tilts */ - for (i=0;i<=NH;i++){ - tiltH[i]=asin((i-(NH+1)/2.0)*(SlabWidth+gap)/RH); + for (i = 0; i <= NH; i++) { + tiltH[i] = asin ((i - (NH + 1) / 2.0) * (SlabWidth + gap) / RH); } } - if (!tiltV) printf("Monochromator_curved: %s: Warning: not enough memory to allocate tilts (NV=%i).\n", NAME_CURRENT_COMP, NV); + if (!tiltV) + printf ("Monochromator_curved: %s: Warning: not enough memory to allocate tilts (NV=%i).\n", NAME_CURRENT_COMP, NV); else if (RV) { - for (i=0;i<=NV;i++){ - tiltV[i]=-asin((i-(NV+1)/2.0)*(SlabHeight+gap)/RV); + for (i = 0; i <= NV; i++) { + tiltV[i] = -asin ((i - (NV + 1) / 2.0) * (SlabHeight + gap) / RV); } } - sprintf(ncol_var,"ncol_%ld",_comp->_index); - sprintf(nrow_var,"nrow_%ld",_comp->_index); - + sprintf (ncol_var, "ncol_%ld", _comp->_index); + sprintf (nrow_var, "nrow_%ld", _comp->_index); %} TRACE %{ double dt; - double Gauss_X[] = {-0.987992518020485, -0.937273392400706, -0.848206583410427, - -0.724417731360170, -0.570972172608539, -0.394151347077563, - -0.201194093997435, 0, 0.201194093997435, - 0.394151347077563, 0.570972172608539, 0.724417731360170, - 0.848206583410427, 0.937273392400706, 0.987992518020485}; - double Gauss_W[] = {0.030753241996117, 0.070366047488108, 0.107159220467172, - 0.139570677926154, 0.166269205816994, 0.186161000115562, - 0.198431485327111, 0.202578241925561, 0.198431485327111, - 0.186161000115562, 0.166269205816994, 0.139570677926154, - 0.107159220467172, 0.070366047488108, 0.030753241996117}; - - if(vx != 0.0 && (dt = -x/vx) >= 0.0 && r0) - { /* Moving towards crystal? */ - double zmin,zmax, ymin,ymax; - double yy,zz; - - zmax = ((NH*(SlabWidth+gap))-gap)/2; + double Gauss_X[] + = { -0.987992518020485, -0.937273392400706, -0.848206583410427, -0.724417731360170, -0.570972172608539, -0.394151347077563, -0.201194093997435, 0, + 0.201194093997435, 0.394151347077563, 0.570972172608539, 0.724417731360170, 0.848206583410427, 0.937273392400706, 0.987992518020485 }; + double Gauss_W[] + = { 0.030753241996117, 0.070366047488108, 0.107159220467172, 0.139570677926154, 0.166269205816994, 0.186161000115562, 0.198431485327111, 0.202578241925561, + 0.198431485327111, 0.186161000115562, 0.166269205816994, 0.139570677926154, 0.107159220467172, 0.070366047488108, 0.030753241996117 }; + + if (vx != 0.0 && (dt = -x / vx) >= 0.0 && r0) { /* Moving towards crystal? */ + double zmin, zmax, ymin, ymax; + double yy, zz; + + zmax = ((NH * (SlabWidth + gap)) - gap) / 2; zmin = -zmax; - ymax = ((NV*(SlabHeight+gap))-gap)/2; + ymax = ((NV * (SlabHeight + gap)) - gap) / 2; ymin = -ymax; /* Test-propagate to crystal plane */ - zz=z+vz*dt; - yy=y+vy*dt; - if (zz>zmin && zzymin && yy zmin && zz < zmax && yy > ymin && yy < ymax) { /* Intersect the crystal? */ + double tilth, tiltv; /* used to calculate tilt angle of slab */ + double ratio, Q_order, k, kux, kuy, kuz; + double kix, kiy, kiz; + int do_transmit = 0; int row, col; - col = ceil ( (zz-zmin)/(SlabWidth +gap)); /* which slab hit ? */ - row = ceil ( (yy-ymin)/(SlabHeight+gap)); + col = ceil ((zz - zmin) / (SlabWidth + gap)); /* which slab hit ? */ + row = ceil ((yy - ymin) / (SlabHeight + gap)); + + particle_setvar_void (_particle, ncol_var, &col); + particle_setvar_void (_particle, nrow_var, &row); - particle_setvar_void(_particle, ncol_var, &col); - particle_setvar_void(_particle, nrow_var, &row); - if (RH != 0) { - tilth = tiltH ? tiltH[(int)col] : asin((col-(NH+1)/2.0)*(SlabWidth+gap)/RH); + tilth = tiltH ? tiltH[(int)col] : asin ((col - (NH + 1) / 2.0) * (SlabWidth + gap) / RH); } else { - tilth=0; + tilth = 0; } if (RV != 0) { - tiltv = tiltV ? tiltV[(int)row] : -asin((row-(NV+1)/2.0)*(SlabHeight+gap)/RV); + tiltv = tiltV ? tiltV[(int)row] : -asin ((row - (NV + 1) / 2.0) * (SlabHeight + gap) / RV); } else { - tiltv=0; + tiltv = 0; } /* rotate with tilth (around Y) and tiltv (around Z), center on plate */ - double center_z=zmin+(col-0.5)*(SlabWidth+gap) -gap/2; - double center_y=ymin+(row-0.5)*(SlabHeight+gap)-gap/2; + double center_z = zmin + (col - 0.5) * (SlabWidth + gap) - gap / 2; + double center_y = ymin + (row - 0.5) * (SlabHeight + gap) - gap / 2; Rotation T; - rot_set_rotation(T, 0, tilth, tiltv); + rot_set_rotation (T, 0, tilth, tiltv); /* now make the coordinate system change */ - mccoordschange_polarisation(T, &vx, &vy, &vz); - y= y-center_y; - z= z-center_z; - coords_get(rot_apply(T,coords_set(x,y,z)),&x,&y,&z); + mccoordschange_polarisation (T, &vx, &vy, &vz); + y = y - center_y; + z = z - center_z; + coords_get (rot_apply (T, coords_set (x, y, z)), &x, &y, &z); /* this is where polarisation should be handled, plus further down */ /* mccoordschange_polarisation(t, &sx, &sy, &sz); */ @@ -289,235 +308,233 @@ TRACE PROP_X0; /* Hit a slab or a gap ?*/ - int inside=inside_rectangle(z,y,SlabWidth,SlabHeight); - if (inside){ /* not in gap ? */ - kix = V2K*vx; /* Initial wave vector */ - kiy = V2K*vy; - kiz = V2K*vz; + int inside = inside_rectangle (z, y, SlabWidth, SlabHeight); + if (inside) { /* not in gap ? */ + kix = V2K * vx; /* Initial wave vector */ + kiy = V2K * vy; + kiz = V2K * vz; /* Get reflection order and corresponding nominal scattering vector q0 of correct length and direction. Only the order with the closest scattering vector is considered */ - ratio = -2*kix/mono_Q; - Q_order = floor(ratio + .5); - if(Q_order == 0.0) Q_order = ratio < 0 ? -1 : 1; + ratio = -2 * kix / mono_Q; + Q_order = floor (ratio + .5); + if (Q_order == 0.0) + Q_order = ratio < 0 ? -1 : 1; /* Order will be negative when the neutron enters from the back, in which case the direction of Q0 is flipped. */ - if(Q_order < 0) Q_order = -Q_order; + if (Q_order < 0) + Q_order = -Q_order; /* Make sure the order is small enough to allow Bragg scattering at the given neutron wavelength */ - k = sqrt(kix*kix + kiy*kiy + kiz*kiz); - kux = kix/k; /* Unit vector along ki */ - kuy = kiy/k; - kuz = kiz/k; - if(Q_order > 2*k/mono_Q) Q_order--; - if((!order && Q_order > 0) || (Q_order == fabs(order) && order)) { /* Bragg scattering possible? */ + k = sqrt (kix * kix + kiy * kiy + kiz * kiz); + kux = kix / k; /* Unit vector along ki */ + kuy = kiy / k; + kuz = kiz / k; + if (Q_order > 2 * k / mono_Q) + Q_order--; + if ((!order && Q_order > 0) || (Q_order == fabs (order) && order)) { /* Bragg scattering possible? */ double q0, q0x, theta, delta, p_reflect, my_r0; - q0 = Q_order*mono_Q; + q0 = Q_order * mono_Q; q0x = ratio < 0 ? -q0 : q0; - theta = asin(q0/(2*k)); /* Actual bragg angle */ + theta = asin (q0 / (2 * k)); /* Actual bragg angle */ /* Make MC choice: reflect or transmit? */ - delta = asin(fabs(kux)) - theta; - - if (rTableFlag) - { - my_r0 = r0*Table_Value(rTable, k, 1); /* 2nd column */ + delta = asin (fabs (kux)) - theta; + + if (rTableFlag) { + my_r0 = r0 * Table_Value (rTable, k, 1); /* 2nd column */ + } else + my_r0 = r0; + if (my_r0 > 1) { + if (my_r0 > 1.01 && verbose) + fprintf (stdout, "Warning: Monochromator_curved : lowered reflectivity from %f to 1 (k=%f)\n", my_r0, k); + my_r0 = 0.999; } - else my_r0 = r0; - if (my_r0 > 1) - { - if (my_r0 > 1.01 && verbose) - fprintf(stdout, "Warning: Monochromator_curved : lowered reflectivity from %f to 1 (k=%f)\n", my_r0, k); - my_r0=0.999; - } - if (my_r0 < 0) - { - if (verbose) - fprintf(stdout, "Warning: Monochromator_curved : raised reflectivity from %f to 0 (k=%f)\n", my_r0, k); - my_r0=0; + if (my_r0 < 0) { + if (verbose) + fprintf (stdout, "Warning: Monochromator_curved : raised reflectivity from %f to 0 (k=%f)\n", my_r0, k); + my_r0 = 0; } - p_reflect = fabs(my_r0)*exp(-kiz*kiz/(kiy*kiy + kiz*kiz)*(delta*delta)/ - (2*mos_rms_y*mos_rms_y))* - exp(-kiy*kiy/(kiy*kiy + kiz*kiz)*(delta*delta)/ - (2*mos_rms_z*mos_rms_z)); + p_reflect = fabs (my_r0) * exp (-kiz * kiz / (kiy * kiy + kiz * kiz) * (delta * delta) / (2 * mos_rms_y * mos_rms_y)) + * exp (-kiy * kiy / (kiy * kiy + kiz * kiz) * (delta * delta) / (2 * mos_rms_z * mos_rms_z)); - double rr=rand01(); - if(rr <= p_reflect) { /* Reflect */ - double bx,by,bz,ax,ay,az,phi; - double cos_2theta,k_sin_2theta,cos_phi,sin_phi,q_x,q_y,q_z; - double total,c1x,c1y,c1z,w,mos_sample; - int i=0; + double rr = rand01 (); + if (rr <= p_reflect) { /* Reflect */ + double bx, by, bz, ax, ay, az, phi; + double cos_2theta, k_sin_2theta, cos_phi, sin_phi, q_x, q_y, q_z; + double total, c1x, c1y, c1z, w, mos_sample; + int i = 0; - cos_2theta = cos(2*theta); - k_sin_2theta = k*sin(2*theta); + cos_2theta = cos (2 * theta); + k_sin_2theta = k * sin (2 * theta); /* Get unit normal to plane containing ki and most probable kf */ - vec_prod(bx, by, bz, kix, kiy, kiz, q0x, 0, 0); - NORM(bx,by,bz); + vec_prod (bx, by, bz, kix, kiy, kiz, q0x, 0, 0); + NORM (bx, by, bz); bx = bx * k_sin_2theta; by = by * k_sin_2theta; bz = bz * k_sin_2theta; /* Get unit vector normal to ki and b */ - vec_prod(ax, ay, az, bx, by, bz, kux, kuy, kuz); + vec_prod (ax, ay, az, bx, by, bz, kux, kuy, kuz); /* Compute the total scattering probability at this ki */ total = 0; /* Choose width of Gaussian distribution to sample the angle - * phi on the Debye-Scherrer cone for the scattered neutron. - * The radius of the Debye-Scherrer cone is smaller by a - * factor 1/cos(theta) than the radius of the (partial) sphere - * describing the possible orientations of Q due to mosaicity, so we - * start with a width 1/cos(theta) greater than the largest of - * the two mosaics. */ - mos_sample = mos_rms_max/cos(theta); - c1x = kix*(cos_2theta-1); - c1y = kiy*(cos_2theta-1); - c1z = kiz*(cos_2theta-1); + * phi on the Debye-Scherrer cone for the scattered neutron. + * The radius of the Debye-Scherrer cone is smaller by a + * factor 1/cos(theta) than the radius of the (partial) sphere + * describing the possible orientations of Q due to mosaicity, so we + * start with a width 1/cos(theta) greater than the largest of + * the two mosaics. */ + mos_sample = mos_rms_max / cos (theta); + c1x = kix * (cos_2theta - 1); + c1y = kiy * (cos_2theta - 1); + c1z = kiz * (cos_2theta - 1); /* Loop, repeatedly reducing the sample width until it is small - * enough to avoid sampling scattering directions with - * ridiculously low scattering probability. - * Use a cut-off at 5 times the gauss width for considering - * scattering probability as well as for integration limits - * when integrating the sampled distribution below. */ - for(i=0; i<100; i++) { - w = 5*mos_sample; - cos_phi = cos(w); - sin_phi = sin(w); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = (c1y + cos_phi*ay + sin_phi*by)/mos_rms_z; - q_z = (c1z + cos_phi*az + sin_phi*bz)/mos_rms_y; + * enough to avoid sampling scattering directions with + * ridiculously low scattering probability. + * Use a cut-off at 5 times the gauss width for considering + * scattering probability as well as for integration limits + * when integrating the sampled distribution below. */ + for (i = 0; i < 100; i++) { + w = 5 * mos_sample; + cos_phi = cos (w); + sin_phi = sin (w); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = (c1y + cos_phi * ay + sin_phi * by) / mos_rms_z; + q_z = (c1z + cos_phi * az + sin_phi * bz) / mos_rms_y; /* Stop when we get near a factor of 25=5^2. */ - if(q_z*q_z + q_y*q_y < (25/(2.0/3.0))*(q_x*q_x)) + if (q_z * q_z + q_y * q_y < (25 / (2.0 / 3.0)) * (q_x * q_x)) break; - mos_sample *= (2.0/3.0); + mos_sample *= (2.0 / 3.0); } /* Now integrate the chosen sampling distribution, using a - * cut-off at five times sigma. */ - for(i = 0; i < (sizeof(Gauss_X)/sizeof(double)); i++) - { - phi = w*Gauss_X[i]; - cos_phi = cos(phi); - sin_phi = sin(phi); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = c1y + cos_phi*ay + sin_phi*by; - q_z = c1z + cos_phi*az + sin_phi*bz; - p_reflect = GAUSS_monocurved((q_z/q_x),0,mos_rms_y)* - GAUSS_monocurved((q_y/q_x),0,mos_rms_z); - total += Gauss_W[i]*p_reflect; + * cut-off at five times sigma. */ + for (i = 0; i < (sizeof (Gauss_X) / sizeof (double)); i++) { + phi = w * Gauss_X[i]; + cos_phi = cos (phi); + sin_phi = sin (phi); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = c1y + cos_phi * ay + sin_phi * by; + q_z = c1z + cos_phi * az + sin_phi * bz; + p_reflect = GAUSS_monocurved ((q_z / q_x), 0, mos_rms_y) * GAUSS_monocurved ((q_y / q_x), 0, mos_rms_z); + total += Gauss_W[i] * p_reflect; } total *= w; /* Choose point on Debye-Scherrer cone. Sample from a Gaussian of * width 1/cos(theta) greater than the mosaic and correct for any * error by adjusting the neutron weight later. */ - phi = mos_sample*randnorm(); + phi = mos_sample * randnorm (); /* Compute final wave vector kf and scattering vector q = ki - kf */ - cos_phi = cos(phi); - sin_phi = sin(phi); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = c1y + cos_phi*ay + sin_phi*by; - q_z = c1z + cos_phi*az + sin_phi*bz; - p_reflect = GAUSS_monocurved((q_z/q_x),0,mos_rms_y)* - GAUSS_monocurved((q_y/q_x),0,mos_rms_z); - - vx = K2V*(kix+q_x); - vy = K2V*(kiy+q_y); - vz = K2V*(kiz+q_z); - p_reflect /= total*GAUSS_monocurved(phi,0,mos_sample); - if (p_reflect <= 0) ABSORB; - if (p_reflect > 1) p_reflect = 1; + cos_phi = cos (phi); + sin_phi = sin (phi); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = c1y + cos_phi * ay + sin_phi * by; + q_z = c1z + cos_phi * az + sin_phi * bz; + p_reflect = GAUSS_monocurved ((q_z / q_x), 0, mos_rms_y) * GAUSS_monocurved ((q_y / q_x), 0, mos_rms_z); + + vx = K2V * (kix + q_x); + vy = K2V * (kiy + q_y); + vz = K2V * (kiz + q_z); + p_reflect /= total * GAUSS_monocurved (phi, 0, mos_sample); + if (p_reflect <= 0) + ABSORB; + if (p_reflect > 1) + p_reflect = 1; p = p * p_reflect; } /* End MC choice to reflect or transmit neutron (if tmp 1) - { - if (my_t0 > 1.01 && verbose) - fprintf(stdout, "Warning: Monochromator_curved : lowered transmission from %f to 1 (k=%f)\n", my_t0, k); - my_t0=0.999; + if (my_t0 > 1) { + if (my_t0 > 1.01 && verbose) + fprintf (stdout, "Warning: Monochromator_curved : lowered transmission from %f to 1 (k=%f)\n", my_t0, k); + my_t0 = 0.999; } - if (my_t0 > 0) p = p * my_t0; - else ABSORB; + if (my_t0 > 0) + p = p * my_t0; + else + ABSORB; } } /* end if not in gap */ /* rotate back in component frame */ Rotation TT; - rot_transpose(T, TT); + rot_transpose (T, TT); /* now make the coordinate system change */ - mccoordschange_polarisation(TT, &vx, &vy, &vz); - coords_get(rot_apply(TT,coords_set(x,y,z)),&x,&y,&z); - y= y+center_y; - z= z+center_z; - /* Visualise scattering point in proper, component frame - - but only if the neutron is reflected, that is none of: - * transmitted - * falling outside the slab material */ - if(!do_transmit) SCATTER; + mccoordschange_polarisation (TT, &vx, &vy, &vz); + coords_get (rot_apply (TT, coords_set (x, y, z)), &x, &y, &z); + y = y + center_y; + z = z + center_z; + /* Visualise scattering point in proper, component frame + - but only if the neutron is reflected, that is none of: + * transmitted + * falling outside the slab material */ + if (!do_transmit) + SCATTER; /* mccoordschange_polarisation(tt, &sx, &sy, &sz); */ } /* End intersect the crystal (if z) */ else { /* restore neutron state when no interaction */ - RESTORE_NEUTRON(INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p); + RESTORE_NEUTRON (INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p); } } /* End neutron moving towards crystal (if vx)*/ %} FINALLY %{ - if(rTableFlag){ - Table_Free(&rTable); + if (rTableFlag) { + Table_Free (&rTable); } - if(tTableFlag){ - Table_Free(&tTable); + if (tTableFlag) { + Table_Free (&tTable); } - if (tiltH) free(tiltH); - if (tiltV) free(tiltV); + if (tiltH) + free (tiltH); + if (tiltV) + free (tiltV); %} MCDISPLAY %{ int ih; - for(ih = 0; ih < NH; ih++) - { + for (ih = 0; ih < NH; ih++) { int iv; - for(iv = 0; iv < NV; iv++) - { - double zmin,zmax,ymin,ymax; + for (iv = 0; iv < NV; iv++) { + double zmin, zmax, ymin, ymax; double xt, yt; - zmin = (SlabWidth+gap)*(ih-NH/2.0)+gap/2; - zmax = zmin+SlabWidth; - ymin = (SlabHeight+gap)*(iv-NV/2.0)+gap/2; - ymax = ymin+SlabHeight; - - if (RH) xt = -(zmax*zmax - zmin*zmin)/RH/2; - else xt = 0; - - if (RV) yt = -(ymax*ymax - ymin*ymin)/RV/2; - else yt = 0; - multiline(5, xt+yt, (double)ymin, (double)zmin, - xt-yt, (double)ymax, (double)zmin, - -xt-yt, (double)ymax, (double)zmax, - -xt+yt, (double)ymin, (double)zmax, - xt+yt, (double)ymin, (double)zmin); - } - } + zmin = (SlabWidth + gap) * (ih - NH / 2.0) + gap / 2; + zmax = zmin + SlabWidth; + ymin = (SlabHeight + gap) * (iv - NV / 2.0) + gap / 2; + ymax = ymin + SlabHeight; + + if (RH) + xt = -(zmax * zmax - zmin * zmin) / RH / 2; + else + xt = 0; + + if (RV) + yt = -(ymax * ymax - ymin * ymin) / RV / 2; + else + yt = 0; + multiline (5, xt + yt, (double)ymin, (double)zmin, xt - yt, (double)ymax, (double)zmin, -xt - yt, (double)ymax, (double)zmax, -xt + yt, (double)ymin, + (double)zmax, xt + yt, (double)ymin, (double)zmin); + } + } %} END diff --git a/mcstas-comps/optics/Monochromator_flat.comp b/mcstas-comps/optics/Monochromator_flat.comp index cee3fd6598..9bcf77bb5e 100644 --- a/mcstas-comps/optics/Monochromator_flat.comp +++ b/mcstas-comps/optics/Monochromator_flat.comp @@ -68,27 +68,23 @@ mosaich=30.0, mosaicv=30.0, r0=0.7, Q=1.8734, DM=0) /* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ SHARE %{ -#ifndef GAUSS -/* Define these arrays only once for all instances. */ -/* Values for Gauss quadrature. Taken from Brice Carnahan, H. A. Luther and -James O Wilkes, "Applied numerical methods", Wiley, 1969, page 103. -This reference is available from the Copenhagen UB2 library */ -double Gauss_X[] = {-0.987992518020485, -0.937273392400706, -0.848206583410427, --0.724417731360170, -0.570972172608539, -0.394151347077563, --0.201194093997435, 0, 0.201194093997435, -0.394151347077563, 0.570972172608539, 0.724417731360170, -0.848206583410427, 0.937273392400706, 0.987992518020485}; -double Gauss_W[] = {0.030753241996117, 0.070366047488108, 0.107159220467172, -0.139570677926154, 0.166269205816994, 0.186161000115562, -0.198431485327111, 0.202578241925561, 0.198431485327111, -0.186161000115562, 0.166269205816994, 0.139570677926154, -0.107159220467172, 0.070366047488108, 0.030753241996117}; -#pragma acc declare create ( Gauss_X ) -#pragma acc declare create ( Gauss_W ) + #ifndef GAUSS + /* Define these arrays only once for all instances. */ + /* Values for Gauss quadrature. Taken from Brice Carnahan, H. A. Luther and + James O Wilkes, "Applied numerical methods", Wiley, 1969, page 103. + This reference is available from the Copenhagen UB2 library */ + double Gauss_X[] + = { -0.987992518020485, -0.937273392400706, -0.848206583410427, -0.724417731360170, -0.570972172608539, -0.394151347077563, -0.201194093997435, 0, + 0.201194093997435, 0.394151347077563, 0.570972172608539, 0.724417731360170, 0.848206583410427, 0.937273392400706, 0.987992518020485 }; + double Gauss_W[] + = { 0.030753241996117, 0.070366047488108, 0.107159220467172, 0.139570677926154, 0.166269205816994, 0.186161000115562, 0.198431485327111, 0.202578241925561, + 0.198431485327111, 0.186161000115562, 0.166269205816994, 0.139570677926154, 0.107159220467172, 0.070366047488108, 0.030753241996117 }; + #pragma acc declare create ( Gauss_X ) + #pragma acc declare create ( Gauss_W ) -#define GAUSS(x,mean,rms) \ - (exp(-((x)-(mean))*((x)-(mean))/(2*(rms)*(rms)))/(sqrt(2*PI)*(rms))) -#endif + #define GAUSS(x,mean,rms) \ + (exp(-((x)-(mean))*((x)-(mean))/(2*(rms)*(rms)))/(sqrt(2*PI)*(rms))) + #endif %} DECLARE @@ -101,80 +97,82 @@ DECLARE INITIALIZE %{ - mos_rms_y = MIN2RAD*mosaicv/sqrt(8*log(2)); - mos_rms_z = MIN2RAD*mosaich/sqrt(8*log(2)); + mos_rms_y = MIN2RAD * mosaicv / sqrt (8 * log (2)); + mos_rms_z = MIN2RAD * mosaich / sqrt (8 * log (2)); mos_rms_max = mos_rms_y > mos_rms_z ? mos_rms_y : mos_rms_z; mono_Q = Q; - if (DM != 0) mono_Q = 2*PI/DM; + if (DM != 0) + mono_Q = 2 * PI / DM; - if (zwidth>0) { zmax = zwidth/2; zmin=-zmax; } - if (yheight>0) { ymax = yheight/2; ymin=-ymax; } + if (zwidth > 0) { + zmax = zwidth / 2; + zmin = -zmax; + } + if (yheight > 0) { + ymax = yheight / 2; + ymin = -ymax; + } - if (zmin==zmax || ymin==ymax) - exit(fprintf(stderr, "Monochromator_flat: %s : Surface is null (zmin,zmax,ymin,ymax)\n", NAME_CURRENT_COMP)); + if (zmin == zmax || ymin == ymax) + exit (fprintf (stderr, "Monochromator_flat: %s : Surface is null (zmin,zmax,ymin,ymax)\n", NAME_CURRENT_COMP)); %} TRACE %{ - double y1,z1,t1,dt,kix,kiy,kiz,ratio,order,q0x,k,q0,theta; - double bx,by,bz,kux,kuy,kuz,ax,ay,az,phi; - double cos_2theta,k_sin_2theta,cos_phi,sin_phi,q_x,q_y,q_z; - double delta,p_reflect,total,c1x,c1y,c1z,width,mos_sample; + double y1, z1, t1, dt, kix, kiy, kiz, ratio, order, q0x, k, q0, theta; + double bx, by, bz, kux, kuy, kuz, ax, ay, az, phi; + double cos_2theta, k_sin_2theta, cos_phi, sin_phi, q_x, q_y, q_z; + double delta, p_reflect, total, c1x, c1y, c1z, width, mos_sample; int i; - if(vx != 0.0 && (dt = -x/vx) >= 0.0) - { /* Moving towards crystal? */ - y1 = y + vy*dt; /* Propagate to crystal plane */ - z1 = z + vz*dt; + if (vx != 0.0 && (dt = -x / vx) >= 0.0) { /* Moving towards crystal? */ + y1 = y + vy * dt; /* Propagate to crystal plane */ + z1 = z + vz * dt; t1 = t + dt; - if (z1>zmin && z1ymin && y1 zmin && z1 < zmax && y1 > ymin && y1 < ymax) { /* Intersect the crystal? */ + kix = V2K * vx; /* Initial wave vector */ + kiy = V2K * vy; + kiz = V2K * vz; /* Get reflection order and corresponding nominal scattering vector q0 of correct length and direction. Only the order with the closest scattering vector is considered */ - ratio = -2*kix/mono_Q; - order = floor(ratio + .5); - if(order == 0.0) + ratio = -2 * kix / mono_Q; + order = floor (ratio + .5); + if (order == 0.0) order = ratio < 0 ? -1 : 1; /* Order will be negative when the neutron enters from the back, in which case the direction of Q0 is flipped. */ - if(order < 0) + if (order < 0) order = -order; /* Make sure the order is small enough to allow Bragg scattering at the given neutron wavelength */ - k = sqrt(kix*kix + kiy*kiy + kiz*kiz); - kux = kix/k; /* Unit vector along ki */ - kuy = kiy/k; - kuz = kiz/k; - if(order > 2*k/mono_Q) + k = sqrt (kix * kix + kiy * kiy + kiz * kiz); + kux = kix / k; /* Unit vector along ki */ + kuy = kiy / k; + kuz = kiz / k; + if (order > 2 * k / mono_Q) order--; - if(order > 0) /* Bragg scattering possible? */ + if (order > 0) /* Bragg scattering possible? */ { - q0 = order*mono_Q; + q0 = order * mono_Q; q0x = ratio < 0 ? -q0 : q0; - theta = asin(q0/(2*k)); /* Actual bragg angle */ + theta = asin (q0 / (2 * k)); /* Actual bragg angle */ /* Make MC choice: reflect or transmit? */ - delta = asin(fabs(kux)) - theta; - p_reflect = r0*exp(-kiy*kiy/(kiy*kiy + kiz*kiz)*(delta*delta)/ - (2*mos_rms_y*mos_rms_y))* - exp(-kiz*kiz/(kiy*kiy + kiz*kiz)*(delta*delta)/ - (2*mos_rms_z*mos_rms_z)); - if(rand01() < p_reflect) - { /* Reflect */ - cos_2theta = cos(2*theta); - k_sin_2theta = k*sin(2*theta); + delta = asin (fabs (kux)) - theta; + p_reflect = r0 * exp (-kiy * kiy / (kiy * kiy + kiz * kiz) * (delta * delta) / (2 * mos_rms_y * mos_rms_y)) + * exp (-kiz * kiz / (kiy * kiy + kiz * kiz) * (delta * delta) / (2 * mos_rms_z * mos_rms_z)); + if (rand01 () < p_reflect) { /* Reflect */ + cos_2theta = cos (2 * theta); + k_sin_2theta = k * sin (2 * theta); /* Get unit normal to plane containing ki and most probable kf */ - vec_prod(bx, by, bz, kix, kiy, kiz, q0x, 0, 0); - NORM(bx,by,bz); + vec_prod (bx, by, bz, kix, kiy, kiz, q0x, 0, 0); + NORM (bx, by, bz); bx *= k_sin_2theta; by *= k_sin_2theta; bz *= k_sin_2theta; /* Get unit vector normal to ki and b */ - vec_prod(ax, ay, az, bx, by, bz, kux, kuy, kuz); + vec_prod (ax, ay, az, bx, by, bz, kux, kuy, kuz); /* Compute the total scattering probability at this ki */ total = 0; /* Choose width of Gaussian distribution to sample the angle @@ -184,65 +182,64 @@ TRACE * describing the possible orientations of Q due to mosaicity, so we * start with a width 1/cos(theta) greater than the largest of * the two mosaics. */ - mos_sample = mos_rms_max/cos(theta); - c1x = kix*(cos_2theta-1); - c1y = kiy*(cos_2theta-1); - c1z = kiz*(cos_2theta-1); + mos_sample = mos_rms_max / cos (theta); + c1x = kix * (cos_2theta - 1); + c1y = kiy * (cos_2theta - 1); + c1z = kiz * (cos_2theta - 1); /* Loop, repeatedly reducing the sample width until it is small * enough to avoid sampling scattering directions with * ridiculously low scattering probability. * Use a cut-off at 5 times the gauss width for considering * scattering probability as well as for integration limits * when integrating the sampled distribution below. */ - for(i=0; i<100; i++) { - width = 5*mos_sample; - cos_phi = cos(width); - sin_phi = sin(width); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = (c1y + cos_phi*ay + sin_phi*by)/mos_rms_y; - q_z = (c1z + cos_phi*az + sin_phi*bz)/mos_rms_z; + for (i = 0; i < 100; i++) { + width = 5 * mos_sample; + cos_phi = cos (width); + sin_phi = sin (width); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = (c1y + cos_phi * ay + sin_phi * by) / mos_rms_y; + q_z = (c1z + cos_phi * az + sin_phi * bz) / mos_rms_z; /* Stop when we get near a factor of 25=5^2. */ - if(q_z*q_z + q_y*q_y < (25/(2.0/3.0))*(q_x*q_x)) + if (q_z * q_z + q_y * q_y < (25 / (2.0 / 3.0)) * (q_x * q_x)) break; - mos_sample *= (2.0/3.0); + mos_sample *= (2.0 / 3.0); } /* Now integrate the chosen sampling distribution, using a * cut-off at five times sigma. */ - for(i = 0; i < (sizeof(Gauss_X)/sizeof(double)); i++) - { - phi = width*Gauss_X[i]; - cos_phi = cos(phi); - sin_phi = sin(phi); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = c1y + cos_phi*ay + sin_phi*by; - q_z = c1z + cos_phi*az + sin_phi*bz; - p_reflect = GAUSS((q_y/q_x),0,mos_rms_y)* - GAUSS((q_z/q_x),0,mos_rms_z); - total += Gauss_W[i]*p_reflect; + for (i = 0; i < (sizeof (Gauss_X) / sizeof (double)); i++) { + phi = width * Gauss_X[i]; + cos_phi = cos (phi); + sin_phi = sin (phi); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = c1y + cos_phi * ay + sin_phi * by; + q_z = c1z + cos_phi * az + sin_phi * bz; + p_reflect = GAUSS ((q_y / q_x), 0, mos_rms_y) * GAUSS ((q_z / q_x), 0, mos_rms_z); + total += Gauss_W[i] * p_reflect; } total *= width; /* Choose point on Debye-Scherrer cone. Sample from a Gaussian of * width 1/cos(theta) greater than the mosaic and correct for any * error by adjusting the neutron weight later. */ - phi = mos_sample*randnorm(); + phi = mos_sample * randnorm (); /* Compute final wave vector kf and scattering vector q = ki - kf */ - cos_phi = cos(phi); - sin_phi = sin(phi); - q_x = c1x + cos_phi*ax + sin_phi*bx; - q_y = c1y + cos_phi*ay + sin_phi*by; - q_z = c1z + cos_phi*az + sin_phi*bz; - p_reflect = GAUSS((q_y/q_x),0,mos_rms_y)* - GAUSS((q_z/q_x),0,mos_rms_z); + cos_phi = cos (phi); + sin_phi = sin (phi); + q_x = c1x + cos_phi * ax + sin_phi * bx; + q_y = c1y + cos_phi * ay + sin_phi * by; + q_z = c1z + cos_phi * az + sin_phi * bz; + p_reflect = GAUSS ((q_y / q_x), 0, mos_rms_y) * GAUSS ((q_z / q_x), 0, mos_rms_z); x = 0; y = y1; z = z1; t = t1; - vx = K2V*(kix+q_x); - vy = K2V*(kiy+q_y); - vz = K2V*(kiz+q_z); - p_reflect /= total*GAUSS(phi,0,mos_sample); - if (p_reflect <= 0) ABSORB; - if (p_reflect > 1) p_reflect = 1; + vx = K2V * (kix + q_x); + vy = K2V * (kiy + q_y); + vz = K2V * (kiz + q_z); + p_reflect /= total * GAUSS (phi, 0, mos_sample); + if (p_reflect <= 0) + ABSORB; + if (p_reflect > 1) + p_reflect = 1; p *= p_reflect; SCATTER; } /* End MC choice to reflect or transmit neutron */ @@ -253,12 +250,9 @@ TRACE MCDISPLAY %{ - - multiline(5, 0.0, (double)ymin, (double)zmin, - 0.0, (double)ymax, (double)zmin, - 0.0, (double)ymax, (double)zmax, - 0.0, (double)ymin, (double)zmax, - 0.0, (double)ymin, (double)zmin); + + multiline (5, 0.0, (double)ymin, (double)zmin, 0.0, (double)ymax, (double)zmin, 0.0, (double)ymax, (double)zmax, 0.0, (double)ymin, (double)zmax, 0.0, + (double)ymin, (double)zmin); %} END diff --git a/mcstas-comps/optics/Monochromator_pol.comp b/mcstas-comps/optics/Monochromator_pol.comp index 651a6e652a..04a2e508c7 100644 --- a/mcstas-comps/optics/Monochromator_pol.comp +++ b/mcstas-comps/optics/Monochromator_pol.comp @@ -97,33 +97,33 @@ SHARE DECLARE %{ -double mos_rms; /* root-mean-square of mosaic in radians */ -double d_rms; /* root-mean-square of d-spread in AA */ -double mono_Q; + double mos_rms; /* root-mean-square of mosaic in radians */ + double d_rms; /* root-mean-square of d-spread in AA */ + double mono_Q; -double FN; /* Unit cell nuclear structure factor */ -double FM; /* Unit cell magnetic structure factor */ + double FN; /* Unit cell nuclear structure factor */ + double FM; /* Unit cell magnetic structure factor */ %} INITIALIZE %{ -mos_rms = MIN2RAD*mosaic/sqrt(8*log(2)); + mos_rms = MIN2RAD * mosaic / sqrt (8 * log (2)); mono_Q = Q; if (DM != 0) - mono_Q = 2*PI/DM; + mono_Q = 2 * PI / DM; - DM = 2*PI/mono_Q; - d_rms = dspread*DM/sqrt(8*log(2)); + DM = 2 * PI / mono_Q; + d_rms = dspread * DM / sqrt (8 * log (2)); // calculate the unit cell nuclear and magnetic structure factors - if(debug > 0) - printf("Rup: %f, Rdown: %f\n", Rup, Rdown); + if (debug > 0) + printf ("Rup: %f, Rdown: %f\n", Rup, Rdown); - GetMonoPolFNFM(Rup, Rdown, &FN, &FM); + GetMonoPolFNFM (Rup, Rdown, &FN, &FM); - if(debug > 0) - printf("FN: %f, FM: %f\n", FN, FM); + if (debug > 0) + printf ("FN: %f, FM: %f\n", FN, FM); %} TRACE @@ -137,73 +137,70 @@ TRACE /* Propagate to crystal */ PROP_X0; - if (inside_rectangle(z, y, zwidth, yheight)) {/* Intersect the crystal? */ + if (inside_rectangle (z, y, zwidth, yheight)) { /* Intersect the crystal? */ // calculate sin(Bragg angle) - vel = sqrt(vx*vx + vy*vy + vz*vz); - sinTheta = abs(vx)/vel; + vel = sqrt (vx * vx + vy * vy + vz * vz); + sinTheta = abs (vx) / vel; // calculate lambdaBragg - lambdaBragg = 2.0*DM*sinTheta; + lambdaBragg = 2.0 * DM * sinTheta; // calculate lambda of neutron - lambda = 2*PI/(V2K*vel); - + lambda = 2 * PI / (V2K * vel); // calculate deltalambda squared and sigmaLambda squared - dlambda2 = (lambda-lambdaBragg)*(lambda-lambdaBragg); + dlambda2 = (lambda - lambdaBragg) * (lambda - lambdaBragg); // The sigmaLambda is propagated by differentiating the Bragg // condition: lambda = 2*d*sinTheta - sigmaLambda2 = 2.0*2.0 * sinTheta*sinTheta * d_rms*d_rms+ - 2.0*2.0 * DM*DM * (1.0-sinTheta*sinTheta) * mos_rms*mos_rms; + sigmaLambda2 = 2.0 * 2.0 * sinTheta * sinTheta * d_rms * d_rms + 2.0 * 2.0 * DM * DM * (1.0 - sinTheta * sinTheta) * mos_rms * mos_rms; // calculate peak reflection probability - GetMonoPolRefProb(FN, FM, sy, &R0); + GetMonoPolRefProb (FN, FM, sy, &R0); /* Output of PW discussions with Hal Lee 2024/03/08 We have now done our QM "measurement", thus forcing the spin to assume up/down: */ - sx=0; sz=0; + sx = 0; + sz = 0; // calculate reflection probability - p_reflect = R0*exp(-dlambda2/(2.0*sigmaLambda2)); + p_reflect = R0 * exp (-dlambda2 / (2.0 * sigmaLambda2)); - if(debug > 0) { - printf("\n lambda: %f, Lambda_Bragg: %f\n", lambda, lambdaBragg); - printf("sigmaLambda: %f, R0: %f, p_reflect: %f\n", - sqrt(sigmaLambda2), R0, p_reflect); - printf("S_in: (%f, %f, %f)\n", sx, sy, sz); + if (debug > 0) { + printf ("\n lambda: %f, Lambda_Bragg: %f\n", lambda, lambdaBragg); + printf ("sigmaLambda: %f, R0: %f, p_reflect: %f\n", sqrt (sigmaLambda2), R0, p_reflect); + printf ("S_in: (%f, %f, %f)\n", sx, sy, sz); } - if((pThreshold>0 && p_reflect>pThreshold) || rand01() 0 && p_reflect > pThreshold) || rand01 () < p_reflect) { /* Reflect */ // scale weight if neutron was accepted because of threshold - if(pThreshold>0 && p_reflect>pThreshold) - p*=p_reflect; + if (pThreshold > 0 && p_reflect > pThreshold) + p *= p_reflect; vx = -vx; // Outgoing polarisation - SetMonoPolRefOut(FN, FM, R0, &sx, &sy, &sz); + SetMonoPolRefOut (FN, FM, R0, &sx, &sy, &sz); - if(debug > 0) - printf("S_out: (%f, %f, %f)\n", sx, sy, sz); + if (debug > 0) + printf ("S_out: (%f, %f, %f)\n", sx, sy, sz); - if(sx*sx+sy*sy+sz*sz>1) - fprintf(stderr,"Pol_mirror: %s: Warning: polarisation |s| = %g > 1\n", - NAME_CURRENT_COMP, sx*sx+sy*sy+sz*sz); // check that polarisation is meaningfull + if (sx * sx + sy * sy + sz * sz > 1) + fprintf (stderr, "Pol_mirror: %s: Warning: polarisation |s| = %g > 1\n", NAME_CURRENT_COMP, + sx * sx + sy * sy + sz * sz); // check that polarisation is meaningfull SCATTER; } /* End MC choice to reflect or transmit neutron */ } /* End intersect the crystal */ - %} MCDISPLAY %{ - - rectangle("yz", 0, 0, 0, zwidth, yheight); + + rectangle ("yz", 0, 0, 0, zwidth, yheight); %} END diff --git a/mcstas-comps/optics/PolAnalyser_ideal.comp b/mcstas-comps/optics/PolAnalyser_ideal.comp index 503f6e6cb1..ef71904ab9 100644 --- a/mcstas-comps/optics/PolAnalyser_ideal.comp +++ b/mcstas-comps/optics/PolAnalyser_ideal.comp @@ -44,60 +44,60 @@ DECLARE INITIALIZE %{ -if (mx==0 && my==0 && mz==0) { - printf("PolAnalyser_ideal: %s: NULL vector defined!\n" - "ERROR (mx, my, mz)=(0,0,0). Exiting", - NAME_CURRENT_COMP); - exit(1); + if (mx == 0 && my == 0 && mz == 0) { + printf ("PolAnalyser_ideal: %s: NULL vector defined!\n" + "ERROR (mx, my, mz)=(0,0,0). Exiting", + NAME_CURRENT_COMP); + exit (1); } - if ((mx*mx + my*my + mz*mz) > 1) { - printf("PolAnalyser_ideal: %s: Polarisation analysis vector (mx, my, mz) is unphysical!\n" - "ERROR mx*mx + my*my + mz*mz > 1. Exiting....", - NAME_CURRENT_COMP); - exit(1); + if ((mx * mx + my * my + mz * mz) > 1) { + printf ("PolAnalyser_ideal: %s: Polarisation analysis vector (mx, my, mz) is unphysical!\n" + "ERROR mx*mx + my*my + mz*mz > 1. Exiting....", + NAME_CURRENT_COMP); + exit (1); } - NORM(mx,my,mz); + NORM (mx, my, mz); %} TRACE %{ double prob_up; - prob_up=(1+scalar_prod(sx,sy,sz,mx,my,mz))/2.0; + prob_up = (1 + scalar_prod (sx, sy, sz, mx, my, mz)) / 2.0; - if (prob_up>0) { - /*adjust weight accordingly (i.e. monte carlo choice with prob. 1)*/ - p*=prob_up; - sx=mx;sy=my;sz=mz; - SCATTER; + if (prob_up > 0) { + /*adjust weight accordingly (i.e. monte carlo choice with prob. 1)*/ + p *= prob_up; + sx = mx; + sy = my; + sz = mz; + SCATTER; } else { - ABSORB; + ABSORB; } - %} MCDISPLAY %{ /* A bit ugly; hard-coded dimensions. */ - - line(0,0,0,0.2,0,0); - line(0,0,0,0,0.2,0); - line(0,0,0,0,0,0.2); - line(0,0,0,0.2*mx,0.2*my,0.2*mz); + line (0, 0, 0, 0.2, 0, 0); + line (0, 0, 0, 0, 0.2, 0); + line (0, 0, 0, 0, 0, 0.2); + + line (0, 0, 0, 0.2 * mx, 0.2 * my, 0.2 * mz); /*draw the arrowhead*/ - double cos2=cos(2*DEG2RAD); - double sin2=sin(2*DEG2RAD); - multiline(4,0.18*(mx*cos2+my*sin2),0.18*(-mx*sin2+my*cos2),0.18*mz, - 0.18*(mx*cos2+mz*sin2),0.18*my,0.18*(-mx*sin2+mz*cos2), - 0.18*mx,0.18*(my*cos2+mz*sin2),0.18*(-my*sin2+mz*cos2), - 0.18*(mx*cos2+my*sin2),0.18*(-mx*sin2+my*cos2),0.18*mz); + double cos2 = cos (2 * DEG2RAD); + double sin2 = sin (2 * DEG2RAD); + multiline (4, 0.18 * (mx * cos2 + my * sin2), 0.18 * (-mx * sin2 + my * cos2), 0.18 * mz, 0.18 * (mx * cos2 + mz * sin2), 0.18 * my, + 0.18 * (-mx * sin2 + mz * cos2), 0.18 * mx, 0.18 * (my * cos2 + mz * sin2), 0.18 * (-my * sin2 + mz * cos2), 0.18 * (mx * cos2 + my * sin2), + 0.18 * (-mx * sin2 + my * cos2), 0.18 * mz); - line(0.2*mx,0.2*my,0.2*mz,0.18*(mx*cos2+my*sin2),0.18*(-mx*sin2+my*cos2),0.18*mx); - line(0.2*mx,0.2*my,0.2*mz,0.18*(mx*cos2+mz*sin2),0.18*my,0.18*(-mx*sin2+mz*cos2)); - line(0.2*mx,0.2*my,0.2*mz,0.18*mx,0.18*(my*cos2+mz*sin2),0.18*(-my*sin2+mz*cos2)); + line (0.2 * mx, 0.2 * my, 0.2 * mz, 0.18 * (mx * cos2 + my * sin2), 0.18 * (-mx * sin2 + my * cos2), 0.18 * mx); + line (0.2 * mx, 0.2 * my, 0.2 * mz, 0.18 * (mx * cos2 + mz * sin2), 0.18 * my, 0.18 * (-mx * sin2 + mz * cos2)); + line (0.2 * mx, 0.2 * my, 0.2 * mz, 0.18 * mx, 0.18 * (my * cos2 + mz * sin2), 0.18 * (-my * sin2 + mz * cos2)); %} END diff --git a/mcstas-comps/optics/Pol_Bfield.comp b/mcstas-comps/optics/Pol_Bfield.comp index 70c87973a5..371c9abee9 100644 --- a/mcstas-comps/optics/Pol_Bfield.comp +++ b/mcstas-comps/optics/Pol_Bfield.comp @@ -88,8 +88,8 @@ SHARE %{ %include "pol-lib" - double fmax(double, double); - double fmin(double, double); + double fmax (double, double); + double fmin (double, double); %} @@ -102,135 +102,141 @@ DECLARE INITIALIZE %{ - enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY}; - enum field_functions ff=field_type; + 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 (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 (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 == 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); + 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}; + 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; + /*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; } - mcmagnet_push(_particle, field_type,&(ROT_A_CURRENT_COMP),&(POS_A_CURRENT_COMP),0,Bprms); -#ifdef MCDEBUG - mcmagnet_print_stack(); -#endif + 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); + /*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; - } + 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 diff --git a/mcstas-comps/optics/Pol_Bfield_stop.comp b/mcstas-comps/optics/Pol_Bfield_stop.comp index e0a408c90b..51991e2f8e 100644 --- a/mcstas-comps/optics/Pol_Bfield_stop.comp +++ b/mcstas-comps/optics/Pol_Bfield_stop.comp @@ -71,51 +71,55 @@ DECLARE %} INITIALIZE %{ - enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY}; - /*if a start component is given, and no geometry is set, inherent geometry from start comp.*/ - if(geometry && strlen(geometry)){ - shape=ANY; - }else 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; - } + enum shapes { NONE = 0, BOX, WINDOW, CYLINDER, SPHERE, ANY }; + /*if a start component is given, and no geometry is set, inherent geometry from start comp.*/ + if (geometry && strlen (geometry)) { + shape = ANY; + } else 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; + } %} TRACE %{ - double t0,t1; - int nofield=0; - enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY}; - /*enter through whatever object we are*/ - switch (shape){ - case BOX: - box_intersect(&t0,&t1,x,y,z,vx,vy,vz,xwidth,yheight,zdepth); - if (t0>FLT_EPSILON) PROP_DT(t0);/*this is to get a hollow inside the field.*/ - else PROP_DT(t1); - break; - case CYLINDER: - cylinder_intersect(&t0,&t1,x,y,z,vx,vy,vz,radius,yheight);/*this is to get a hollow inside the field.*/ - if (t0>FLT_EPSILON) PROP_DT(t0); - else 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; + double t0, t1; + int nofield = 0; + enum shapes { NONE = 0, BOX, WINDOW, CYLINDER, SPHERE, ANY }; + /*enter through whatever object we are*/ + switch (shape) { + case BOX: + box_intersect (&t0, &t1, x, y, z, vx, vy, vz, xwidth, yheight, zdepth); + if (t0 > FLT_EPSILON) + PROP_DT (t0); /*this is to get a hollow inside the field.*/ + else + PROP_DT (t1); + break; + case CYLINDER: + cylinder_intersect (&t0, &t1, x, y, z, vx, vy, vz, radius, yheight); /*this is to get a hollow inside the field.*/ + if (t0 > FLT_EPSILON) + PROP_DT (t0); + else + 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; } - mcmagnet_pop(_particle); + break; + default: + PROP_Z0; + } + mcmagnet_pop (_particle); %} END diff --git a/mcstas-comps/optics/Pol_FieldBox.comp b/mcstas-comps/optics/Pol_FieldBox.comp index 8d2403c046..f818684c9c 100644 --- a/mcstas-comps/optics/Pol_FieldBox.comp +++ b/mcstas-comps/optics/Pol_FieldBox.comp @@ -51,52 +51,58 @@ DECLARE INITIALIZE %{ /*constant magnetic field in the box*/ - Bprms[0]=Bx;Bprms[1]=By;Bprms[2]=Bz; + Bprms[0] = Bx; + Bprms[1] = By; + Bprms[2] = Bz; %} TRACE %{ - int hit; - double t0,t1; - if (hit=box_intersect(&t0,&t1,x,y,z,vx,vy,vz,xwidth,yheight,zdepth)){ - if(t0>0) PROP_DT(t0); - double phi_prec; - if(t1-t0>0){ - PROP_DT(t1-t0); - /*do the precession "manually"*/ - phi_prec= fmod(sqrt(Bx*Bx+ By*By+ Bz*Bz) * (t1-t0)*mc_pol_omegaL, 2*PI); - double sx_i,sy_i,sz_i; - sx_i=sx;sy_i=sy;sz_i=sz; - rotate(sx, sy, sz, sx_i,sy_i,sz_i, phi_prec, Bx, By, Bz); - } + int hit; + double t0, t1; + if (hit = box_intersect (&t0, &t1, x, y, z, vx, vy, vz, xwidth, yheight, zdepth)) { + if (t0 > 0) + PROP_DT (t0); + double phi_prec; + if (t1 - t0 > 0) { + PROP_DT (t1 - t0); + /*do the precession "manually"*/ + phi_prec = fmod (sqrt (Bx * Bx + By * By + Bz * Bz) * (t1 - t0) * mc_pol_omegaL, 2 * PI); + double sx_i, sy_i, sz_i; + sx_i = sx; + sy_i = sy; + sz_i = sz; + rotate (sx, sy, sz, sx_i, sy_i, sz_i, phi_prec, Bx, By, Bz); } - + } %} MCDISPLAY %{ const int nDash = 10; - double xw_2,yh_2,zd_2; - xw_2=xwidth/2.0;yh_2=yheight/2.0;zd_2=zdepth/2.0; + double xw_2, yh_2, zd_2; + xw_2 = xwidth / 2.0; + yh_2 = yheight / 2.0; + zd_2 = zdepth / 2.0; /*entrance*/ - dashed_line(-xw_2, -yh_2, +zd_2, xw_2, -yh_2, -zd_2, nDash); - dashed_line(-xw_2, -yh_2, +zd_2, -xw_2, yh_2, +zd_2, nDash); - dashed_line( xw_2, yh_2, -zd_2, -xw_2, yh_2, +zd_2, nDash); - dashed_line( xw_2, yh_2, -zd_2, xw_2, -yh_2, -zd_2, nDash); + dashed_line (-xw_2, -yh_2, +zd_2, xw_2, -yh_2, -zd_2, nDash); + dashed_line (-xw_2, -yh_2, +zd_2, -xw_2, yh_2, +zd_2, nDash); + dashed_line (xw_2, yh_2, -zd_2, -xw_2, yh_2, +zd_2, nDash); + dashed_line (xw_2, yh_2, -zd_2, xw_2, -yh_2, -zd_2, nDash); /*exit*/ - dashed_line(-xw_2, -yh_2, zdepth+zd_2, xw_2, -yh_2, zdepth-zd_2, nDash); - dashed_line(-xw_2, -yh_2, zdepth+zd_2, -xw_2, yh_2, zdepth+zd_2, nDash); - dashed_line( xw_2, yh_2, zdepth-zd_2, -xw_2, yh_2, zdepth+zd_2, nDash); - dashed_line( xw_2, yh_2, zdepth-zd_2, xw_2, -yh_2, zdepth-zd_2, nDash); + dashed_line (-xw_2, -yh_2, zdepth + zd_2, xw_2, -yh_2, zdepth - zd_2, nDash); + dashed_line (-xw_2, -yh_2, zdepth + zd_2, -xw_2, yh_2, zdepth + zd_2, nDash); + dashed_line (xw_2, yh_2, zdepth - zd_2, -xw_2, yh_2, zdepth + zd_2, nDash); + dashed_line (xw_2, yh_2, zdepth - zd_2, xw_2, -yh_2, zdepth - zd_2, nDash); /*4 lines to make a box*/ - dashed_line(-xw_2, -yh_2, +zd_2, -xw_2, -yh_2, zdepth+zd_2, nDash); - dashed_line(-xw_2, yh_2, +zd_2, -xw_2, yh_2, zdepth+zd_2, nDash); - dashed_line( xw_2, -yh_2, -zd_2, xw_2, -yh_2, zdepth-zd_2, nDash); - dashed_line( xw_2, yh_2, -zd_2, xw_2, yh_2, zdepth-zd_2, nDash); + dashed_line (-xw_2, -yh_2, +zd_2, -xw_2, -yh_2, zdepth + zd_2, nDash); + dashed_line (-xw_2, yh_2, +zd_2, -xw_2, yh_2, zdepth + zd_2, nDash); + dashed_line (xw_2, -yh_2, -zd_2, xw_2, -yh_2, zdepth - zd_2, nDash); + dashed_line (xw_2, yh_2, -zd_2, xw_2, yh_2, zdepth - zd_2, nDash); %} END diff --git a/mcstas-comps/optics/Pol_SF_ideal.comp b/mcstas-comps/optics/Pol_SF_ideal.comp index fd216a5378..b37af25b98 100644 --- a/mcstas-comps/optics/Pol_SF_ideal.comp +++ b/mcstas-comps/optics/Pol_SF_ideal.comp @@ -45,48 +45,45 @@ SETTING PARAMETERS (nx=0, ny=1, nz=0, xwidth=0.1, yheight=0.1, zdepth=0.1) /* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ TRACE %{ - int hit; - double t0,t1; - hit=box_intersect(&t0,&t1, x,y,z,vx,vy,vz, xwidth,yheight,zdepth); - if(hit){ - PROP_DT(t0); - if(fabs(z- -zdepth*0.5)>DBL_EPSILON){ - /*neutron must have hit the side walls*/ - ABSORB; - } - /*move to center of box and flip*/ - PROP_Z0; - SCATTER; - double s=scalar_prod(sx,sy,sz,nx,ny,nz); - if (s!=0){ - sx-=2*s*nx; - sy-=2*s*ny; - sz-=2*s*nz; - } - PROP_DT((t1-t0)/2);/*propagate the remaining distance to the box exit*/ - if(fabs(z-zdepth*0.5)>DBL_EPSILON){ - ABSORB; - } + int hit; + double t0, t1; + hit = box_intersect (&t0, &t1, x, y, z, vx, vy, vz, xwidth, yheight, zdepth); + if (hit) { + PROP_DT (t0); + if (fabs (z - -zdepth * 0.5) > DBL_EPSILON) { + /*neutron must have hit the side walls*/ + ABSORB; } - - + /*move to center of box and flip*/ + PROP_Z0; + SCATTER; + double s = scalar_prod (sx, sy, sz, nx, ny, nz); + if (s != 0) { + sx -= 2 * s * nx; + sy -= 2 * s * ny; + sz -= 2 * s * nz; + } + PROP_DT ((t1 - t0) / 2); /*propagate the remaining distance to the box exit*/ + if (fabs (z - zdepth * 0.5) > DBL_EPSILON) { + ABSORB; + } + } %} MCDISPLAY %{ - double dx=xwidth/16; - double dy=yheight/8; - - box(0,0,0,xwidth,yheight,zdepth,0, 0, 1, 0); - - line(dx,-dy,0,dx,-dy+yheight/2.0,0); - line(-dx,dy,0,-dx,dy-yheight/2.0,0); - line(dx,-dy+yheight/2.0,0, dx+xwidth/16,-dy+yheight-yheight/16,0); - line(dx,-dy+yheight/2.0,0, dx-xwidth/16,-dy+yheight-yheight/16,0); - - line(-dx,dy-yheight/2.0,0, -dx+xwidth/16,dy-yheight+yheight/16,0); - line(-dx,dy-yheight/2.0,0, -dx-xwidth/16,dy-yheight+yheight/16,0); + double dx = xwidth / 16; + double dy = yheight / 8; + + box (0, 0, 0, xwidth, yheight, zdepth, 0, 0, 1, 0); + + line (dx, -dy, 0, dx, -dy + yheight / 2.0, 0); + line (-dx, dy, 0, -dx, dy - yheight / 2.0, 0); + line (dx, -dy + yheight / 2.0, 0, dx + xwidth / 16, -dy + yheight - yheight / 16, 0); + line (dx, -dy + yheight / 2.0, 0, dx - xwidth / 16, -dy + yheight - yheight / 16, 0); + line (-dx, dy - yheight / 2.0, 0, -dx + xwidth / 16, dy - yheight + yheight / 16, 0); + line (-dx, dy - yheight / 2.0, 0, -dx - xwidth / 16, dy - yheight + yheight / 16, 0); %} END diff --git a/mcstas-comps/optics/Pol_bender.comp b/mcstas-comps/optics/Pol_bender.comp index dd59c9d430..b0cefbbfb4 100644 --- a/mcstas-comps/optics/Pol_bender.comp +++ b/mcstas-comps/optics/Pol_bender.comp @@ -143,149 +143,146 @@ INITIALIZE %{ double angle; - if(strlen(rTopUpData) && strcmp(rTopUpData,"NULL")){ - useTables=1; + if (strlen (rTopUpData) && strcmp (rTopUpData, "NULL")) { + useTables = 1; /*if rUpTopData is set assume we'll be usning tabled data for all reflectivities*/ - if (Table_Read(&rTopUpTable, rTopUpData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rTopUpData); - exit(1); + if (Table_Read (&rTopUpTable, rTopUpData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rTopUpData); + exit (1); } - if (Table_Read(&rTopDownTable, rTopDownData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rTopDownData); - exit(1); + if (Table_Read (&rTopDownTable, rTopDownData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rTopDownData); + exit (1); } - if (Table_Read(&rBotUpTable, rBotUpData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rBotUpData); - exit(1); + if (Table_Read (&rBotUpTable, rBotUpData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rBotUpData); + exit (1); } - if (Table_Read(&rBotDownTable, rBotDownData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rBotDownData); - exit(1); + if (Table_Read (&rBotDownTable, rBotDownData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rBotDownData); + exit (1); } - if (Table_Read(&rLeftUpTable, rLeftUpData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rLeftUpData); - exit(1); + if (Table_Read (&rLeftUpTable, rLeftUpData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rLeftUpData); + exit (1); } - if (Table_Read(&rLeftDownTable, rLeftDownData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rLeftDownData); - exit(1); + if (Table_Read (&rLeftDownTable, rLeftDownData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rLeftDownData); + exit (1); } - if (Table_Read(&rRightUpTable, rRightUpData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rRightUpData); - exit(1); + if (Table_Read (&rRightUpTable, rRightUpData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rRightUpData); + exit (1); } - if (Table_Read(&rRightDownTable, rRightDownData, 1) <= 0) { - fprintf(stderr,"Pol_bender: %s: can not read file %s\n",NAME_CURRENT_COMP, rRightDownData); - exit(1); + if (Table_Read (&rRightDownTable, rRightDownData, 1) <= 0) { + fprintf (stderr, "Pol_bender: %s: can not read file %s\n", NAME_CURRENT_COMP, rRightDownData); + exit (1); } } - if ((xwidth<=0) || (yheight <= 0) || (length<=0) || (radius==0)) { - fprintf(stderr, "Pol_bender: %s: NULL or negative length scale!\n" - "ERROR (xwidth,yheight,length, radius). Exiting\n", - NAME_CURRENT_COMP); - exit(1); + if ((xwidth <= 0) || (yheight <= 0) || (length <= 0) || (radius == 0)) { + fprintf (stderr, + "Pol_bender: %s: NULL or negative length scale!\n" + "ERROR (xwidth,yheight,length, radius). Exiting\n", + NAME_CURRENT_COMP); + exit (1); } - if (drawOption<1 || drawOption>3) { - fprintf(stderr, "Pol_bender: %s: drawOption %ld not supported. Exiting.\n", - NAME_CURRENT_COMP, drawOption); - exit(1); + if (drawOption < 1 || drawOption > 3) { + fprintf (stderr, "Pol_bender: %s: drawOption %ld not supported. Exiting.\n", NAME_CURRENT_COMP, drawOption); + exit (1); } if (mcgravitation) { - localG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,-GRAVITY,0)); - fprintf(stdout,"Pol_bender %s: Gravity is on!\n", - NAME_CURRENT_COMP); - if (localG.x!=0 || localG.z!=0) - fprintf(stderr,"WARNING: Pol_Bender: %s: " - "This component only gives correct resulta with gravitation,\n" - "when gravity is strictly along the y-axis!\n", - NAME_CURRENT_COMP); + localG = rot_apply (ROT_A_CURRENT_COMP, coords_set (0, -GRAVITY, 0)); + fprintf (stdout, "Pol_bender %s: Gravity is on!\n", NAME_CURRENT_COMP); + if (localG.x != 0 || localG.z != 0) + fprintf (stderr, + "WARNING: Pol_Bender: %s: " + "This component only gives correct resulta with gravitation,\n" + "when gravity is strictly along the y-axis!\n", + NAME_CURRENT_COMP); } else - localG = coords_set(0, 0, 0); + localG = coords_set (0, 0, 0); // To be able to handle the situation properly where a component of // the gravity is along the z-axis we also define entrance (in) and // exit (out) planes - angle = length/radius; - normIn = coords_set(0, 0, 1); + angle = length / radius; + normIn = coords_set (0, 0, 1); if (endFlat) - normOut = coords_set(0, 0, 1); + normOut = coords_set (0, 0, 1); else - normOut = coords_set(sin(angle), 0, cos(angle)); - pointIn = coords_set(0, 0, 0); - pointOut = coords_set(radius-radius*cos(angle), 0, radius*sin(angle)); + normOut = coords_set (sin (angle), 0, cos (angle)); + pointIn = coords_set (0, 0, 0); + pointOut = coords_set (radius - radius * cos (angle), 0, radius* sin (angle)); // Top and bot plane (+y dir) can be spanned by (1, 0, 0) & (0, 0, 1) // and the top point (0, yheight/2, 0) and bot point (0, -yheight/2, 0) // A normal vector is (0, 1, 0) - normTopBot = coords_set(0, 1, 0); - pointTop = coords_set(0, yheight/2, 0); - pointBot = coords_set(0, -yheight/2, 0); - + normTopBot = coords_set (0, 1, 0); + pointTop = coords_set (0, yheight / 2, 0); + pointBot = coords_set (0, -yheight / 2, 0); %} TRACE %{ - const double whalf = 0.5*xwidth; /* half width of guide */ - const double hhalf = 0.5*yheight; /* half height of guide */ - const double z_off = radius*sin(length/radius); /* z-comp of guide length */ - const double dThreshold = 1e-10; /* distance threshold */ - const double tThreshold = dThreshold/sqrt(vx*vx + vy*vy + vz*vz); - double angle_z_vout; /* angle between z-axis and v_out */ + const double whalf = 0.5 * xwidth; /* half width of guide */ + const double hhalf = 0.5 * yheight; /* half height of guide */ + const double z_off = radius * sin (length / radius); /* z-comp of guide length */ + const double dThreshold = 1e-10; /* distance threshold */ + const double tThreshold = dThreshold / sqrt (vx * vx + vy * vy + vz * vz); + double angle_z_vout; /* angle between z-axis and v_out */ // Variables used in the case of multiple slits - const double slitWidth = xwidth/nslit; // slitwidth - const double spacerhalf = 0.5*d; /* half width of spacers */ - int slitHit; // decide which slit is hit - double posInSlit; // position in slit + const double slitWidth = xwidth / nslit; // slitwidth + const double spacerhalf = 0.5 * d; /* half width of spacers */ + int slitHit; // decide which slit is hit + double posInSlit; // position in slit double t11, t12, t21, t22, theta, alpha, endtime, phi; int i_bounce; - int nerr=0; + int nerr = 0; // Pol variables double FN, FM, Rup, Rdown, weight; double Rleft; /* radius of curvature of left mirror */ double Rright; /* radius of curvature of right mirror */ - double absR = fabs(radius); + double absR = fabs (radius); double sign = 1; - if(radius<0) + if (radius < 0) sign = -1; /* Propagate neutron to guide entrance. */ PROP_Z0; - if (!inside_rectangle(x, y, xwidth, yheight)) + if (!inside_rectangle (x, y, xwidth, yheight)) ABSORB; - if(nslit>1) { + if (nslit > 1) { // check if neutron is absorbed on a spacer - posInSlit = fmod(x+whalf, slitWidth); - if(posInSlit <= spacerhalf || - posInSlit >= slitWidth-spacerhalf) + posInSlit = fmod (x + whalf, slitWidth); + if (posInSlit <= spacerhalf || posInSlit >= slitWidth - spacerhalf) ABSORB; // check which slat is hit - slitHit = (int)((x+whalf)/slitWidth); + slitHit = (int)((x + whalf) / slitWidth); // Modify R1 and R2 according to which slat was hit - Rleft = absR + sign*whalf - sign*(slitHit+1)*slitWidth + sign*spacerhalf; - Rright = absR + sign*whalf - sign*slitHit*slitWidth - sign*spacerhalf; + Rleft = absR + sign * whalf - sign * (slitHit + 1) * slitWidth + sign * spacerhalf; + Rright = absR + sign * whalf - sign * slitHit * slitWidth - sign * spacerhalf; - if(debug>0) - printf("\nslitHit: %d/%f, Rleft: %f, Rright: %f\n", - slitHit, (x+whalf)/slitWidth, Rleft, Rright); + if (debug > 0) + printf ("\nslitHit: %d/%f, Rleft: %f, Rright: %f\n", slitHit, (x + whalf) / slitWidth, Rleft, Rright); } else { // only 1 slit - Rleft = absR - sign*whalf; - Rright = absR + sign*whalf; + Rleft = absR - sign * whalf; + Rright = absR + sign * whalf; } - for(;;) { + for (;;) { double tLeft, tRight, tTop, tBot, tIn, tOut, tMirror; double tUp, tSide, time, endtime; @@ -296,267 +293,259 @@ TRACE isPolarising = 0; - xVec = coords_set(x, y, z); - vVec = coords_set(vx, vy, vz); + xVec = coords_set (x, y, z); + vVec = coords_set (vx, vy, vz); - solve_2nd_order(&tTop, NULL, 0.5*coords_sp(normTopBot,localG), - coords_sp(normTopBot, vVec), - coords_sp(normTopBot, coords_sub(xVec, pointTop))); + solve_2nd_order (&tTop, NULL, 0.5 * coords_sp (normTopBot, localG), coords_sp (normTopBot, vVec), coords_sp (normTopBot, coords_sub (xVec, pointTop))); - solve_2nd_order(&tBot, NULL, 0.5*coords_sp(normTopBot,localG), - coords_sp(normTopBot, vVec), - coords_sp(normTopBot, coords_sub(xVec, pointBot))); + solve_2nd_order (&tBot, NULL, 0.5 * coords_sp (normTopBot, localG), coords_sp (normTopBot, vVec), coords_sp (normTopBot, coords_sub (xVec, pointBot))); - solve_2nd_order(&tIn, NULL, 0.5*coords_sp(normIn,localG), - coords_sp(normIn, vVec), - coords_sp(normIn, coords_sub(xVec, pointIn))); + solve_2nd_order (&tIn, NULL, 0.5 * coords_sp (normIn, localG), coords_sp (normIn, vVec), coords_sp (normIn, coords_sub (xVec, pointIn))); - solve_2nd_order(&tOut, NULL, 0.5*coords_sp(normOut,localG), - coords_sp(normOut, vVec), - coords_sp(normOut, coords_sub(xVec, pointOut))); + solve_2nd_order (&tOut, NULL, 0.5 * coords_sp (normOut, localG), coords_sp (normOut, vVec), coords_sp (normOut, coords_sub (xVec, pointOut))); /* Find itersection points with inside and outside guide walls */ - if (!cylinder_intersect(&t11, &t12 ,x - radius, y, z, vx, vy, vz, Rleft, 2*yheight)){ + if (!cylinder_intersect (&t11, &t12, x - radius, y, z, vx, vy, vz, Rleft, 2 * yheight)) { /*neutron did not hit the cylinder*/ - t11=t12=0; + t11 = t12 = 0; } - if (!cylinder_intersect(&t21, &t22 ,x - radius, y, z, vx, vy, vz, Rright, 2*yheight)){ + if (!cylinder_intersect (&t21, &t22, x - radius, y, z, vx, vy, vz, Rright, 2 * yheight)) { /*neutron did not hit the cylinder*/ - t21=t22=0; + t21 = t22 = 0; } /* Choose appropriate reflection time */ - tLeft = (t11 < tThreshold) ? t12 : t11; + tLeft = (t11 < tThreshold) ? t12 : t11; tRight = (t21 < tThreshold) ? t22 : t21; /* Choose appropriate reflection time */ - if (tTop>tThreshold && (tTop tThreshold && (tTop < tBot || tBot <= tThreshold)) + tUp = tTop; else - tUp=tBot; + tUp = tBot; - if (tLeft>tThreshold && (tLeft tThreshold && (tLeft < tRight || tRight <= tThreshold)) + tSide = tLeft; else - tSide=tRight; + tSide = tRight; - if (tUp>tThreshold && (tUp tThreshold && (tUp < tSide || tSide <= tThreshold)) + time = tUp; else - time=tSide; + time = tSide; - if (time<=tThreshold) { + if (time <= tThreshold) { nerr++; if (nerr < 10) { - fprintf(stdout, "tTop: %e, tBot:%e, tRight: %e, tLeft: %e\n" - "tUp: %e, tSide: %e, time: %e\n", - tTop, tBot, tRight, tLeft, tUp, tSide, time); + fprintf (stdout, + "tTop: %e, tBot:%e, tRight: %e, tLeft: %e\n" + "tUp: %e, tSide: %e, time: %e\n", + tTop, tBot, tRight, tLeft, tUp, tSide, time); } else { - fprintf(stdout, "Found 10 propagation error for this neutron, terminating!\n"); + fprintf (stdout, "Found 10 propagation error for this neutron, terminating!\n"); break; } } /* Has neutron left the guide? */ - if (tOut>tThreshold && (tOut tThreshold && (tOut < tIn || tIn <= tThreshold)) + endtime = tOut; else - endtime=tIn; + endtime = tIn; if (time > endtime) break; - PROP_DT(time); + PROP_DT (time); SCATTER; /* Find reflection surface */ - if(time==tSide) { /* Left or right side */ + if (time == tSide) { /* Left or right side */ - if(time==tLeft) - R = sign*Rleft; + if (time == tLeft) + R = sign * Rleft; else - R = sign*Rright; + R = sign * Rright; - phi = atan(vx/vz); /* angle of neutron trajectory */ - alpha = asin(z/R); /* angle of guide wall */ - theta = fabs(phi - alpha); /* angle of reflection */ - angle_z_vout = 2.0*alpha - phi; + phi = atan (vx / vz); /* angle of neutron trajectory */ + alpha = asin (z / R); /* angle of guide wall */ + theta = fabs (phi - alpha); /* angle of reflection */ + angle_z_vout = 2.0 * alpha - phi; - vel_xz = sqrt(vx*vx + vz*vz); /* in plane velocity */ - vz = vel_xz*cos(angle_z_vout); - vx = vel_xz*sin(angle_z_vout); + vel_xz = sqrt (vx * vx + vz * vz); /* in plane velocity */ + vz = vel_xz * cos (angle_z_vout); + vx = vel_xz * sin (angle_z_vout); } else { /* Top or Bottom wall */ - theta = fabs(atan(vy/vz)); - vy = -vy; + theta = fabs (atan (vy / vz)); + vy = -vy; } /* Now compute reflectivity. */ - Q = 2.0*sin(theta)*sqrt(vx*vx + vy*vy + vz*vz)*V2K; + Q = 2.0 * sin (theta) * sqrt (vx * vx + vy * vy + vz * vz) * V2K; // calculate reflection probability - if(time==tTop) { - if(useTables){ - Rup=Table_Value(rTopUpTable,Q,1); - Rdown=Table_Value(rTopDownTable,Q,1); - }else{ - StdReflecFunc(Q, rTopUpPar, &Rup); - StdReflecFunc(Q, rTopDownPar, &Rdown); + if (time == tTop) { + if (useTables) { + Rup = Table_Value (rTopUpTable, Q, 1); + Rdown = Table_Value (rTopDownTable, Q, 1); + } else { + StdReflecFunc (Q, rTopUpPar, &Rup); + StdReflecFunc (Q, rTopDownPar, &Rdown); } - if(debug>0) - fprintf(stdout, "\tTop hit:\n"); - } else if(time==tBot) { - if(useTables){ - Rup=Table_Value(rBotUpTable,Q,1); - Rdown=Table_Value(rBotDownTable,Q,1); - }else{ - StdReflecFunc(Q, rBotUpPar, &Rup); - StdReflecFunc(Q, rBotDownPar, &Rdown); + if (debug > 0) + fprintf (stdout, "\tTop hit:\n"); + } else if (time == tBot) { + if (useTables) { + Rup = Table_Value (rBotUpTable, Q, 1); + Rdown = Table_Value (rBotDownTable, Q, 1); + } else { + StdReflecFunc (Q, rBotUpPar, &Rup); + StdReflecFunc (Q, rBotDownPar, &Rdown); } - if(debug>0) - fprintf(stdout, "\tBot hit:\n"); - } else if(time==tRight) { - if(useTables){ - Rup=Table_Value(rRightUpTable,Q,1); - Rdown=Table_Value(rRightDownTable,Q,1); - }else{ - StdReflecFunc(Q, rRightUpPar, &Rup); - StdReflecFunc(Q, rRightDownPar, &Rdown); + if (debug > 0) + fprintf (stdout, "\tBot hit:\n"); + } else if (time == tRight) { + if (useTables) { + Rup = Table_Value (rRightUpTable, Q, 1); + Rdown = Table_Value (rRightDownTable, Q, 1); + } else { + StdReflecFunc (Q, rRightUpPar, &Rup); + StdReflecFunc (Q, rRightDownPar, &Rdown); } - if(debug>0) - fprintf(stdout, "\tRight hit:\n"); - } else if(time==tLeft) { - if(useTables){ - Rup=Table_Value(rLeftUpTable,Q,1); - Rdown=Table_Value(rLeftDownTable,Q,1); - }else{ - StdReflecFunc(Q, rLeftUpPar, &Rup); - StdReflecFunc(Q, rLeftDownPar, &Rdown); + if (debug > 0) + fprintf (stdout, "\tRight hit:\n"); + } else if (time == tLeft) { + if (useTables) { + Rup = Table_Value (rLeftUpTable, Q, 1); + Rdown = Table_Value (rLeftDownTable, Q, 1); + } else { + StdReflecFunc (Q, rLeftUpPar, &Rup); + StdReflecFunc (Q, rLeftDownPar, &Rdown); } - if(debug>0) - fprintf(stdout, "\tLeft hit:\n"); + if (debug > 0) + fprintf (stdout, "\tLeft hit:\n"); } - if(Rup != Rdown) { + if (Rup != Rdown) { isPolarising = 1; - GetMonoPolFNFM(Rup, Rdown, &FN, &FM); - GetMonoPolRefProb(FN, FM, sy, &weight); + GetMonoPolFNFM (Rup, Rdown, &FN, &FM); + GetMonoPolRefProb (FN, FM, sy, &weight); /* Output of PW discussions with Hal Lee 2024/03/08 - We have now done our QM "measurement", thus - forcing the spin to assume up/down: */ - sx=0; sz=0; + We have now done our QM "measurement", thus + forcing the spin to assume up/down: */ + sx = 0; + sz = 0; } else weight = Rup; - if(debug>0) - printf("\tlambda: %.2f AA, Q: %.4f, Rup: %.4f, Rdown: %.4f," - " weight: %.4f\n", - 2*PI/(sqrt(vx*vx + vy*vy + vz*vz)*V2K), Q, - Rup, Rdown, weight); + if (debug > 0) + printf ("\tlambda: %.2f AA, Q: %.4f, Rup: %.4f, Rdown: %.4f," + " weight: %.4f\n", + 2 * PI / (sqrt (vx * vx + vy * vy + vz * vz) * V2K), Q, Rup, Rdown, weight); // check that refWeight is meaningfull - if (weight <= 0) ABSORB; - if (weight > 1) weight =1 ; - - if(isPolarising) { - SetMonoPolRefOut(FN, FM, weight, &sx, &sy, &sz); - if(sx*sx+sy*sy+sz*sz>1.000001) - fprintf(stderr,"Pol_bender: %s: Warning: polarisation |s| = %g > 1\n", - NAME_CURRENT_COMP, sx*sx+sy*sy+sz*sz); // check that polarisation is meaningfull + if (weight <= 0) + ABSORB; + if (weight > 1) + weight = 1; + + if (isPolarising) { + SetMonoPolRefOut (FN, FM, weight, &sx, &sy, &sz); + if (sx * sx + sy * sy + sz * sz > 1.000001) + fprintf (stderr, "Pol_bender: %s: Warning: polarisation |s| = %g > 1\n", NAME_CURRENT_COMP, + sx * sx + sy * sy + sz * sz); // check that polarisation is meaningfull } p *= weight; - if(p==0) { + if (p == 0) { ABSORB; break; } } - %} MCDISPLAY %{ double x1, x2, z1, z2; - x1=x2=z1=z2=0; + x1 = x2 = z1 = z2 = 0; const int n = 90; - double *xplot=malloc(n*sizeof(double)); - double *zplot=malloc(n*sizeof(double)); + double* xplot = malloc (n * sizeof (double)); + double* zplot = malloc (n * sizeof (double)); int ns = 0; int j = 1; - const double lengthOfGuide = sin(length/radius)*radius; - const double slitWidth = xwidth/nslit; + const double lengthOfGuide = sin (length / radius) * radius; + const double slitWidth = xwidth / nslit; double R = 0; /* radius of arc */ int nSlitsMax = nslit; - int nMax = n; + int nMax = n; - if (lengthOfGuide<=0) - exit(fprintf(stdout,"Pol_bender: %s: Negative guide length ! lengthOfGuide=%g\n", - NAME_CURRENT_COMP, lengthOfGuide)); + if (lengthOfGuide <= 0) + exit (fprintf (stdout, "Pol_bender: %s: Negative guide length ! lengthOfGuide=%g\n", NAME_CURRENT_COMP, lengthOfGuide)); - if (drawOption==2) { + if (drawOption == 2) { - if(nSlitsMax>20) + if (nSlitsMax > 20) nSlitsMax = 20; nMax = 40; - } else if (drawOption==3) { + } else if (drawOption == 3) { - if(nSlitsMax>5) + if (nSlitsMax > 5) nSlitsMax = 5; nMax = 10; } - - // draw opening - rectangle("xy", 0, 0, 0, xwidth, yheight); + rectangle ("xy", 0, 0, 0, xwidth, yheight); - for(ns=0; ns < nSlitsMax+1; ns++) { + for (ns = 0; ns < nSlitsMax + 1; ns++) { // to make sure the sides are drawn properly - if(ns==nSlitsMax && nSlitsMax0) - xplot[j] = radius - sqrt(R*R - zplot[j]*zplot[j]); + if (radius > 0) + xplot[j] = radius - sqrt (R * R - zplot[j] * zplot[j]); else - xplot[j] = radius + sqrt(R*R - zplot[j]*zplot[j]); + xplot[j] = radius + sqrt (R * R - zplot[j] * zplot[j]); } // To be able to draw end we store some of the point values - if(ns==0) { // first wall + if (ns == 0) { // first wall - x1 = xplot[nMax-1]; - z1 = zplot[nMax-1]; - } else if(ns==nslit) { //last wall + x1 = xplot[nMax - 1]; + z1 = zplot[nMax - 1]; + } else if (ns == nslit) { // last wall - x2 = xplot[nMax-1]; - z2 = zplot[nMax-1]; + x2 = xplot[nMax - 1]; + z2 = zplot[nMax - 1]; } - for(j=0; j0) - return (wallpos-pos)/vel; + if (vel > 0) + return (wallpos - pos) / vel; else - return (-wallpos-pos)/vel; + return (-wallpos - pos) / vel; } %} @@ -72,29 +73,29 @@ INITIALIZE double velocity = 0, time = 0; - if ((xwidth<=0) || (yheight<=0) || (zdepth<=0)) { - fprintf(stderr, "Pol_filter: %s: Null or negative volume!\n" - "ERROR (xwidth, yheight, zdepth). Exiting\n", - NAME_CURRENT_COMP); - exit(1); + if ((xwidth <= 0) || (yheight <= 0) || (zdepth <= 0)) { + fprintf (stderr, + "Pol_filter: %s: Null or negative volume!\n" + "ERROR (xwidth, yheight, zdepth). Exiting\n", + NAME_CURRENT_COMP); + exit (1); } // neutron Larmor frequency: omegaL=29.16 MHz/Tesla * B(Neutron Data Booklet) // omegaL/B = -2*mu_n/hbar = -2.0*1.913*5.051e-27/1.055e-34 omegaL = -2 * PI * 29.16e6 * B * 1e-4; // B is in Gauss - if(fliplambda>0){ - velocity = K2V*2*PI/fliplambda; - time = zdepth/velocity; + if (fliplambda > 0) { + velocity = K2V * 2 * PI / fliplambda; + time = zdepth / velocity; // omegaL*time = flipangle - omegaL = flipangle*DEG2RAD/time; + omegaL = flipangle * DEG2RAD / time; // omegaL = 2*PI*29.16 MHz/T*B B = omegaL / -2 / 29.16e6 / PI / 1e-4; // Gauss - printf("Pol_constBfield: %s: Magnetic field set to B=%f Gauss\n", - NAME_CURRENT_COMP, B); + printf ("Pol_constBfield: %s: Magnetic field set to B=%f Gauss\n", NAME_CURRENT_COMP, B); } %} @@ -103,30 +104,30 @@ TRACE double deltaT, deltaTx, deltaTy, sx_in, sz_in; PROP_Z0; - if (!inside_rectangle(x, y, xwidth, yheight)) + if (!inside_rectangle (x, y, xwidth, yheight)) ABSORB; // Time spent in B-field - deltaT = zdepth/vz; + deltaT = zdepth / vz; // check that track goes throgh without hitting the walls - if (!inside_rectangle(x+vx*deltaT, y+vy*deltaT, xwidth, yheight)) { + if (!inside_rectangle (x + vx * deltaT, y + vy * deltaT, xwidth, yheight)) { // Propagate to the wall and absorb - deltaTx = IntersectWall(x, vx, xwidth/2); - deltaTy = IntersectWall(y, vy, yheight/2); + deltaTx = IntersectWall (x, vx, xwidth / 2); + deltaTy = IntersectWall (y, vy, yheight / 2); - if (deltaTx>=0 && deltaTx= 0 && deltaTx < deltaTy) deltaT = deltaTx; else deltaT = deltaTy; - PROP_DT(deltaT); + PROP_DT (deltaT); ABSORB; } - PROP_DT(deltaT); + PROP_DT (deltaT); // The solution to neutron precession in a constant field along the // z-axis is: @@ -139,13 +140,13 @@ TRACE sx_in = sx; sz_in = sz; - sz = cos(omegaL*deltaT)*sz_in - sin(omegaL*deltaT)*sx_in; - sx = sin(omegaL*deltaT)*sz_in + cos(omegaL*deltaT)*sx_in; + sz = cos (omegaL * deltaT) * sz_in - sin (omegaL * deltaT) * sx_in; + sx = sin (omegaL * deltaT) * sz_in + cos (omegaL * deltaT) * sx_in; %} MCDISPLAY %{ - box(0, 0, zdepth/2, xwidth, yheight, zdepth,0, 0, 1, 0); + box (0, 0, zdepth / 2, xwidth, yheight, zdepth, 0, 0, 1, 0); %} END diff --git a/mcstas-comps/optics/Pol_guide_mirror.comp b/mcstas-comps/optics/Pol_guide_mirror.comp index af2dcba072..386c512b4f 100644 --- a/mcstas-comps/optics/Pol_guide_mirror.comp +++ b/mcstas-comps/optics/Pol_guide_mirror.comp @@ -106,51 +106,48 @@ DECLARE INITIALIZE %{ - if (strlen(rData) && strcmp(rData,"NULL")){ - if (Table_Read(&rTable, rData, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rPar); - exit(1); + if (strlen (rData) && strcmp (rData, "NULL")) { + if (Table_Read (&rTable, rData, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rPar); + exit (1); } - rTableFlag=1; - }else{ - rTableFlag=0; + rTableFlag = 1; + } else { + rTableFlag = 0; } - if (strlen(rUpData) && strcmp(rUpData,"NULL")){ - if (Table_Read(&rUpTable, rUpData, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rUpPar); - exit(1); + if (strlen (rUpData) && strcmp (rUpData, "NULL")) { + if (Table_Read (&rUpTable, rUpData, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rUpPar); + exit (1); } - rUpTableFlag=1; - }else { - rUpTableFlag=0; + rUpTableFlag = 1; + } else { + rUpTableFlag = 0; } - if (strlen(rDownData) && strcmp(rDownData,"NULL")){ - if (Table_Read(&rDownTable, rDownData, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rDownPar); - exit(1); + if (strlen (rDownData) && strcmp (rDownData, "NULL")) { + if (Table_Read (&rDownTable, rDownData, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rDownPar); + exit (1); } - rDownTableFlag=1; - }else{ - rDownTableFlag=0; + rDownTableFlag = 1; + } else { + rDownTableFlag = 0; } - if ((xwidth<=0) || (yheight<= 0) || (length<=0)) { - fprintf(stderr, "Pol_guide_mirror: %s: NULL or negative length scale!\n" - "ERROR (xwidth,yheight,length). Exiting\n", - NAME_CURRENT_COMP); - exit(1); + if ((xwidth <= 0) || (yheight <= 0) || (length <= 0)) { + fprintf (stderr, + "Pol_guide_mirror: %s: NULL or negative length scale!\n" + "ERROR (xwidth,yheight,length). Exiting\n", + NAME_CURRENT_COMP); + exit (1); } if (mcgravitation) { - localG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,-GRAVITY,0)); - fprintf(stdout,"Pol_guide_mirror: %s: Gravity is on!\n", - NAME_CURRENT_COMP); + localG = rot_apply (ROT_A_CURRENT_COMP, coords_set (0, -GRAVITY, 0)); + fprintf (stdout, "Pol_guide_mirror: %s: Gravity is on!\n", NAME_CURRENT_COMP); } else - localG = coords_set(0, 0, 0); + localG = coords_set (0, 0, 0); // To be able to handle the situation properly where a component of // the gravity is along the z-axis we also define entrance (in) and @@ -159,41 +156,41 @@ INITIALIZE // (0, 0, 1) // and the two points pointIn=(0, 0, 0) and pointOut=(0, 0, length) - normalInOut = coords_set(0, 0, 1); - pointIn = coords_set(0, 0, 0); - pointOut = coords_set(0, 0, length); + normalInOut = coords_set (0, 0, 1); + pointIn = coords_set (0, 0, 0); + pointOut = coords_set (0, 0, length); // Top plane (+y dir) can be spanned by (1, 0, 0) & (0, 0, 1) // and the point (0, yheight/2, 0) // A normal vector is (0, 1, 0) - normalTop = coords_set(0, 1, 0); - pointTop = coords_set(0, yheight/2, 0); + normalTop = coords_set (0, 1, 0); + pointTop = coords_set (0, yheight / 2, 0); // Bottom plane (-y dir) can be spanned by (1, 0, 0) & (0, 0, 1) // and the point (0, -yheight/2, 0) // A normal vector is (0, 1, 0) - normalBot = coords_set(0, 1, 0); - pointBot = coords_set(0, -yheight/2, 0); + normalBot = coords_set (0, 1, 0); + pointBot = coords_set (0, -yheight / 2, 0); // Left plane (+x dir) can be spanned by (0, 1, 0) & (0, 0, 1) // and the point (xwidth/2, 0, 0) // A normal vector is (1, 0, 0) - normalLeft = coords_set(1, 0, 0); - pointLeft = coords_set(xwidth/2, 0, 0); + normalLeft = coords_set (1, 0, 0); + pointLeft = coords_set (xwidth / 2, 0, 0); // Right plane (-x dir) can be spanned by (0, 1, 0) & (0, 0, 1) // and the point (-xwidth/2, 0, 0) // A normal vector is (1, 0, 0) - normalRight = coords_set(1, 0, 0); - pointRight = coords_set(-xwidth/2, 0, 0); + normalRight = coords_set (1, 0, 0); + pointRight = coords_set (-xwidth / 2, 0, 0); %} TRACE %{ /* time threshold */ - const double tThreshold = 1e-10/sqrt(vx*vx + vy*vy + vz*vz); - const double xwhalf = xwidth/2; - const double norm = 1.0/sqrt(xwidth*xwidth + length*length); + const double tThreshold = 1e-10 / sqrt (vx * vx + vy * vy + vz * vz); + const double xwhalf = xwidth / 2; + const double norm = 1.0 / sqrt (xwidth * xwidth + length * length); double R; Coords normalMirror, pointMirror; @@ -205,15 +202,15 @@ TRACE /* Propagate neutron to guide entrance. */ PROP_Z0; - if (!inside_rectangle(x, y, xwidth, yheight)) + if (!inside_rectangle (x, y, xwidth, yheight)) ABSORB; SCATTER; - normalMirror = coords_set(norm*length, 0, -norm*xwidth); - pointMirror = coords_set(-xwhalf, 0, 0); + normalMirror = coords_set (norm * length, 0, -norm* xwidth); + pointMirror = coords_set (-xwhalf, 0, 0); - for(;;) { + for (;;) { double tLeft, tRight, tTop, tBot, tIn, tOut, tMirror; double tUp, tSide, time, endtime; double Q; //, dummy1, dummy2, dummy3; @@ -221,190 +218,184 @@ TRACE int mirrorReflect; mirrorReflect = 0; - xVec = coords_set(x, y, z); - vVec = coords_set(vx, vy, vz); + xVec = coords_set (x, y, z); + vVec = coords_set (vx, vy, vz); - solve_2nd_order(&tTop, NULL, 0.5*coords_sp(normalTop,localG), - coords_sp(normalTop, vVec), - coords_sp(normalTop, coords_sub(xVec, pointTop))); + solve_2nd_order (&tTop, NULL, 0.5 * coords_sp (normalTop, localG), coords_sp (normalTop, vVec), coords_sp (normalTop, coords_sub (xVec, pointTop))); - solve_2nd_order(&tBot, NULL, 0.5*coords_sp(normalBot,localG), - coords_sp(normalBot, vVec), - coords_sp(normalBot, coords_sub(xVec, pointBot))); + solve_2nd_order (&tBot, NULL, 0.5 * coords_sp (normalBot, localG), coords_sp (normalBot, vVec), coords_sp (normalBot, coords_sub (xVec, pointBot))); - solve_2nd_order(&tRight, NULL, 0.5*coords_sp(normalRight,localG), - coords_sp(normalRight, vVec), - coords_sp(normalRight, coords_sub(xVec, pointRight))); + solve_2nd_order (&tRight, NULL, 0.5 * coords_sp (normalRight, localG), coords_sp (normalRight, vVec), coords_sp (normalRight, coords_sub (xVec, pointRight))); - solve_2nd_order(&tLeft, NULL, 0.5*coords_sp(normalLeft,localG), - coords_sp(normalLeft, vVec), - coords_sp(normalLeft, coords_sub(xVec, pointLeft))); + solve_2nd_order (&tLeft, NULL, 0.5 * coords_sp (normalLeft, localG), coords_sp (normalLeft, vVec), coords_sp (normalLeft, coords_sub (xVec, pointLeft))); - solve_2nd_order(&tIn, NULL, 0.5*coords_sp(normalInOut,localG), - coords_sp(normalInOut, vVec), - coords_sp(normalInOut, coords_sub(xVec, pointIn))); + solve_2nd_order (&tIn, NULL, 0.5 * coords_sp (normalInOut, localG), coords_sp (normalInOut, vVec), coords_sp (normalInOut, coords_sub (xVec, pointIn))); - solve_2nd_order(&tOut, NULL, 0.5*coords_sp(normalInOut,localG), - coords_sp(normalInOut, vVec), - coords_sp(normalInOut, coords_sub(xVec, pointOut))); + solve_2nd_order (&tOut, NULL, 0.5 * coords_sp (normalInOut, localG), coords_sp (normalInOut, vVec), coords_sp (normalInOut, coords_sub (xVec, pointOut))); - solve_2nd_order(&tMirror, NULL, 0.5*coords_sp(normalMirror,localG), - coords_sp(normalMirror, vVec), - coords_sp(normalMirror, coords_sub(xVec, pointMirror))); - - double nx,ny,nz,px,py,pz; - coords_get(normalMirror,&nx,&ny,&nz); - coords_get(pointMirror,&px,&py,&pz); - plane_intersect(&tMirror, x,y,z,vx,vy,vz, nx, ny, nz, px, py, pz); + solve_2nd_order (&tMirror, NULL, 0.5 * coords_sp (normalMirror, localG), coords_sp (normalMirror, vVec), + coords_sp (normalMirror, coords_sub (xVec, pointMirror))); + double nx, ny, nz, px, py, pz; + coords_get (normalMirror, &nx, &ny, &nz); + coords_get (pointMirror, &px, &py, &pz); + plane_intersect (&tMirror, x, y, z, vx, vy, vz, nx, ny, nz, px, py, pz); /* Choose appropriate reflection time */ - if (tTop>tThreshold && (tTop tThreshold && (tTop < tBot || tBot <= tThreshold)) + tUp = tTop; else - tUp=tBot; + tUp = tBot; - if (tLeft>tThreshold && (tLeft tThreshold && (tLeft < tRight || tRight <= tThreshold)) + tSide = tLeft; else - tSide=tRight; + tSide = tRight; - if (tUp>tThreshold && (tUp tThreshold && (tUp < tSide || tSide <= tThreshold)) + time = tUp; else - time=tSide; + time = tSide; - if (tMirror>tThreshold && tMirror tThreshold && tMirror < time) { - time=tMirror; + time = tMirror; mirrorReflect = 1; // flag to show which reflection function to use } - if (time<=tThreshold) - fprintf(stdout, "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + if (time <= tThreshold) + fprintf (stdout, + "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); /* Has neutron left the guide? */ - if (tOut>tThreshold && (tOut tThreshold && (tOut < tIn || tIn <= tThreshold)) + endtime = tOut; else - endtime=tIn; + endtime = tIn; if (time > endtime) break; - if(time <= tThreshold) { + if (time <= tThreshold) { - printf("Time below threshold!\n"); - fprintf(stdout, "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + printf ("Time below threshold!\n"); + fprintf (stdout, + "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); break; } - if(debug>0 && time==tLeft) { + if (debug > 0 && time == tLeft) { - fprintf(stdout, "\nPol_guide_mirror: %s: Left side hit: x, v, normal, point, gravity\n", NAME_CURRENT_COMP); - coords_print(xVec); - coords_print(vVec); - coords_print(normalLeft); - coords_print(pointLeft); - coords_print(localG); + fprintf (stdout, "\nPol_guide_mirror: %s: Left side hit: x, v, normal, point, gravity\n", NAME_CURRENT_COMP); + coords_print (xVec); + coords_print (vVec); + coords_print (normalLeft); + coords_print (pointLeft); + coords_print (localG); - fprintf(stdout, "\nA: %f, B: %f, C: %f, tLeft: %f\n", - 0.5*coords_sp(normalLeft,localG),coords_sp(normalLeft, vVec), - coords_sp(normalLeft, coords_sub(xVec, pointLeft)), tLeft); + fprintf (stdout, "\nA: %f, B: %f, C: %f, tLeft: %f\n", 0.5 * coords_sp (normalLeft, localG), coords_sp (normalLeft, vVec), + coords_sp (normalLeft, coords_sub (xVec, pointLeft)), tLeft); } - if(debug>0) - fprintf(stdout, "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + if (debug > 0) + fprintf (stdout, + "Pol_guide_mirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); - if(debug>0) - fprintf(stdout, "Pol_guide_mirror: %s: Start v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); + if (debug > 0) + fprintf (stdout, "Pol_guide_mirror: %s: Start v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); - PROP_DT(time); + PROP_DT (time); if (mcgravitation) - vVec = coords_set(vx, vy, vz); + vVec = coords_set (vx, vy, vz); - if(time==tTop) + if (time == tTop) normalPointer = &normalTop; - else if(time==tBot) + else if (time == tBot) normalPointer = &normalBot; - else if(time==tRight) + else if (time == tRight) normalPointer = &normalRight; - else if(time==tLeft) + else if (time == tLeft) normalPointer = &normalLeft; - else if(time==tMirror) + else if (time == tMirror) normalPointer = &normalMirror; else - fprintf(stderr, "Pol_guide_mirror: %s: This should never happen!!!!\n", NAME_CURRENT_COMP); + fprintf (stderr, "Pol_guide_mirror: %s: This should never happen!!!!\n", NAME_CURRENT_COMP); - Q = 2*coords_sp(vVec, *normalPointer)*V2K; + Q = 2 * coords_sp (vVec, *normalPointer) * V2K; - if(!mirrorReflect) { + if (!mirrorReflect) { /* we have hit one of the sides. Always reflect. */ - vVec = coords_add(vVec, coords_scale(*normalPointer, -Q*K2V)); - if(rTableFlag){ - refWeight=Table_Value(rTable, fabs(Q), 1); - }else{ - StdReflecFunc(fabs(Q), rPar, &refWeight); + vVec = coords_add (vVec, coords_scale (*normalPointer, -Q * K2V)); + if (rTableFlag) { + refWeight = Table_Value (rTable, fabs (Q), 1); + } else { + StdReflecFunc (fabs (Q), rPar, &refWeight); } p *= refWeight; SCATTER; } else { /* we have hit the mirror */ - if(rUpTableFlag){ - Rup=Table_Value(rUpTable,fabs(Q),1); - }else{ - StdReflecFunc(fabs(Q), rUpPar, &Rup); + if (rUpTableFlag) { + Rup = Table_Value (rUpTable, fabs (Q), 1); + } else { + StdReflecFunc (fabs (Q), rUpPar, &Rup); } - if(rDownTableFlag){ - Rdown=Table_Value(rDownTable,fabs(Q),1); - }else{ - StdReflecFunc(fabs(Q), rDownPar, &Rdown); + if (rDownTableFlag) { + Rdown = Table_Value (rDownTable, fabs (Q), 1); + } else { + StdReflecFunc (fabs (Q), rDownPar, &Rdown); } - if (Rup < 0) ABSORB; - if (Rup > 1) Rup =1 ; - if (Rdown < 0) ABSORB; - if (Rdown > 1) Rdown =1 ; - GetMonoPolFNFM(Rup, Rdown, &FN, &FM); - GetMonoPolRefProb(FN, FM, sy, &refWeight); + if (Rup < 0) + ABSORB; + if (Rup > 1) + Rup = 1; + if (Rdown < 0) + ABSORB; + if (Rdown > 1) + Rdown = 1; + GetMonoPolFNFM (Rup, Rdown, &FN, &FM); + GetMonoPolRefProb (FN, FM, sy, &refWeight); /* Output of PW discussions with Hal Lee 2024/03/08 - We have now done our QM "measurement", thus - forcing the spin to assume up/down: */ - sx=0; sz=0; + We have now done our QM "measurement", thus + forcing the spin to assume up/down: */ + sx = 0; + sz = 0; // check that refWeight is meaningful - if (refWeight < 0) ABSORB; - if (refWeight > 1) refWeight =1 ; - - if (rand01() 1) + refWeight = 1; + + if (rand01 () < refWeight) { + vVec = coords_add (vVec, coords_scale (*normalPointer, -Q * K2V)); + SetMonoPolRefOut (FN, FM, refWeight, &sx, &sy, &sz); + SCATTER; } else { - SetMonoPolTransOut(FN, FM, refWeight, &sx, &sy, &sz); + SetMonoPolTransOut (FN, FM, refWeight, &sx, &sy, &sz); } - if (sx*sx+sy*sy+sz*sz>1.000001) { // check that polarisation is meaningfull - fprintf(stderr, "Pol_guide_mirror: %s: polarisation |s|=%g > 1 s=[%g,%g,%g]\n", - NAME_CURRENT_COMP, sx*sx+sy*sy+sz*sz, sx, sy, sz); + if (sx * sx + sy * sy + sz * sz > 1.000001) { // check that polarisation is meaningfull + fprintf (stderr, "Pol_guide_mirror: %s: polarisation |s|=%g > 1 s=[%g,%g,%g]\n", NAME_CURRENT_COMP, sx * sx + sy * sy + sz * sz, sx, sy, sz); } } - if(p==0) { + if (p == 0) { ABSORB; break; } // set new velocity vector - coords_get(vVec, &vx, &vy, &vz); + coords_get (vVec, &vx, &vy, &vz); - if(debug>0){ - fprintf(stdout, "Pol_guide_mirror: %s: End v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); + if (debug > 0) { + fprintf (stdout, "Pol_guide_mirror: %s: End v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); } } %} @@ -413,10 +404,10 @@ MCDISPLAY %{ int i, j; // draw box - box(0, 0, length/2.0, xwidth, yheight, length,0, 0, 1, 0); + box (0, 0, length / 2.0, xwidth, yheight, length, 0, 0, 1, 0); - for(j = -1; j<=1; j+=2){ - line(-xwidth/2.0, j*yheight/2, 0, xwidth/2.0, j*yheight/2, length); + for (j = -1; j <= 1; j += 2) { + line (-xwidth / 2.0, j * yheight / 2, 0, xwidth / 2.0, j * yheight / 2, length); } %} diff --git a/mcstas-comps/optics/Pol_guide_vmirror.comp b/mcstas-comps/optics/Pol_guide_vmirror.comp index 3b6b0935c8..2c1b8b68fd 100644 --- a/mcstas-comps/optics/Pol_guide_vmirror.comp +++ b/mcstas-comps/optics/Pol_guide_vmirror.comp @@ -118,134 +118,126 @@ SHARE DECLARE %{ -Coords localG; -Coords normalTop; -Coords normalBot; -Coords normalLeft; -Coords normalRight; -Coords normalInOut; -Coords pointTop; -Coords pointBot; -Coords pointLeft; -Coords pointRight; -Coords pointIn; -Coords pointOut; - -Coords* mirrorNormals; -Coords* mirrorPoints; - -double xwhalf; -double xwfull; -double norm; - -int n_index; -int i_index; -double rParToFunc[6]; -double rUpParToFunc[6]; -double rDownParToFunc[6]; - -t_Table rParPtr; -t_Table rUpParPtr; -t_Table rDownParPtr; + Coords localG; + Coords normalTop; + Coords normalBot; + Coords normalLeft; + Coords normalRight; + Coords normalInOut; + Coords pointTop; + Coords pointBot; + Coords pointLeft; + Coords pointRight; + Coords pointIn; + Coords pointOut; + + Coords* mirrorNormals; + Coords* mirrorPoints; + + double xwhalf; + double xwfull; + double norm; + + int n_index; + int i_index; + double rParToFunc[6]; + double rUpParToFunc[6]; + double rDownParToFunc[6]; + + t_Table rParPtr; + t_Table rUpParPtr; + t_Table rDownParPtr; %} INITIALIZE %{ -if (inputType == 0) { -//copy the SM reflectivity input parameter array r..Par to array r..ParToFunc -//the input array can be 5 parameters, i.e. without beta, then beta=0 -//or it can be 6 parameters, including the value for beta. -//r..ParToFunc is sent to the reflectivity functions - - for (i_index=0; i_index < 6; i_index++) - { - rParToFunc[i_index] = 0; - rUpParToFunc[i_index] = 0; - rDownParToFunc[i_index] = 0; - } - - n_index = sizeof(rPar)/sizeof(rPar[0]); - for (i_index=0; i_index < n_index; i_index++) - { - rParToFunc[i_index] = rPar[i_index]; - } - - n_index = sizeof(rUpPar)/sizeof(rUpPar[0]); - for (i_index=0; i_index < n_index; i_index++) - { - rUpParToFunc[i_index] = rUpPar[i_index]; - } - - n_index = sizeof(rDownPar)/sizeof(rDownPar[0]); - for (i_index=0; i_index < n_index; i_index++) - { - rDownParToFunc[i_index] = rDownPar[i_index]; - } - } else if (inputType == 1) { - if (Table_Read(&rParPtr, rParFile, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rPar); - exit(1); - } - if (Table_Read(&rUpParPtr, rUpParFile, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rUpPar); - exit(1); - } - if (Table_Read(&rDownParPtr, rDownParFile, 1) <= 0) { - fprintf(stderr,"Pol_guide_vmirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rDownPar); - exit(1); - } - fprintf(stderr, "Pol_guide_vmirror: %s: Reading files is not possible!\n", - NAME_CURRENT_COMP); - exit(1); - } else if (inputType == 2) { - //Assemble the parameter array r..ParToFunc from the individual parameters - //r..ParToFunc is sent to the reflectivity functions - - for (i_index=0; i_index < 6; i_index++) { - rParToFunc[i_index] = 0; - rUpParToFunc[i_index] = 0; - rDownParToFunc[i_index] = 0; + if (inputType == 0) { + // copy the SM reflectivity input parameter array r..Par to array r..ParToFunc + // the input array can be 5 parameters, i.e. without beta, then beta=0 + // or it can be 6 parameters, including the value for beta. + // r..ParToFunc is sent to the reflectivity functions + + for (i_index = 0; i_index < 6; i_index++) { + rParToFunc[i_index] = 0; + rUpParToFunc[i_index] = 0; + rDownParToFunc[i_index] = 0; + } + + n_index = sizeof (rPar) / sizeof (rPar[0]); + for (i_index = 0; i_index < n_index; i_index++) { + rParToFunc[i_index] = rPar[i_index]; + } + + n_index = sizeof (rUpPar) / sizeof (rUpPar[0]); + for (i_index = 0; i_index < n_index; i_index++) { + rUpParToFunc[i_index] = rUpPar[i_index]; + } + + n_index = sizeof (rDownPar) / sizeof (rDownPar[0]); + for (i_index = 0; i_index < n_index; i_index++) { + rDownParToFunc[i_index] = rDownPar[i_index]; + } + } else if (inputType == 1) { + if (Table_Read (&rParPtr, rParFile, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rPar); + exit (1); + } + if (Table_Read (&rUpParPtr, rUpParFile, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rUpPar); + exit (1); + } + if (Table_Read (&rDownParPtr, rDownParFile, 1) <= 0) { + fprintf (stderr, "Pol_guide_vmirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rDownPar); + exit (1); + } + fprintf (stderr, "Pol_guide_vmirror: %s: Reading files is not possible!\n", NAME_CURRENT_COMP); + exit (1); + } else if (inputType == 2) { + // Assemble the parameter array r..ParToFunc from the individual parameters + // r..ParToFunc is sent to the reflectivity functions + + for (i_index = 0; i_index < 6; i_index++) { + rParToFunc[i_index] = 0; + rUpParToFunc[i_index] = 0; + rDownParToFunc[i_index] = 0; + } + + rParToFunc[0] = rR0; + rParToFunc[1] = rQc; + rParToFunc[2] = ralpha; + rParToFunc[3] = rmSM; + rParToFunc[4] = rW; + rParToFunc[5] = rbeta; + + rUpParToFunc[0] = rUpR0; + rUpParToFunc[1] = rUpQc; + rUpParToFunc[2] = rUpalpha; + rUpParToFunc[3] = rUpmSM; + rUpParToFunc[4] = rUpW; + rUpParToFunc[5] = rUpbeta; + + rDownParToFunc[0] = rDownR0; + rDownParToFunc[1] = rDownQc; + rDownParToFunc[2] = rDownalpha; + rDownParToFunc[3] = rDownmSM; + rDownParToFunc[4] = rDownW; + rDownParToFunc[5] = rDownbeta; } - - rParToFunc[0] = rR0; - rParToFunc[1] = rQc; - rParToFunc[2] = ralpha; - rParToFunc[3] = rmSM; - rParToFunc[4] = rW; - rParToFunc[5] = rbeta; - - rUpParToFunc[0] = rUpR0; - rUpParToFunc[1] = rUpQc; - rUpParToFunc[2] = rUpalpha; - rUpParToFunc[3] = rUpmSM; - rUpParToFunc[4] = rUpW; - rUpParToFunc[5] = rUpbeta; - - rDownParToFunc[0] = rDownR0; - rDownParToFunc[1] = rDownQc; - rDownParToFunc[2] = rDownalpha; - rDownParToFunc[3] = rDownmSM; - rDownParToFunc[4] = rDownW; - rDownParToFunc[5] = rDownbeta; - } - - if ((xwidth<=0) || (yheight<= 0) || (length<=0)) { - fprintf(stderr, "Pol_guide_vmirror: %s: NULL or negative length scale!\n" - "ERROR (xwidth,yheight,length). Exiting\n", - NAME_CURRENT_COMP); - exit(1); + + if ((xwidth <= 0) || (yheight <= 0) || (length <= 0)) { + fprintf (stderr, + "Pol_guide_vmirror: %s: NULL or negative length scale!\n" + "ERROR (xwidth,yheight,length). Exiting\n", + NAME_CURRENT_COMP); + exit (1); } if (mcgravitation) { - localG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,-GRAVITY,0)); - fprintf(stdout,"Pol_guide_vmirror: %s: Gravity is on!\n", - NAME_CURRENT_COMP); + localG = rot_apply (ROT_A_CURRENT_COMP, coords_set (0, -GRAVITY, 0)); + fprintf (stdout, "Pol_guide_vmirror: %s: Gravity is on!\n", NAME_CURRENT_COMP); } else - localG = coords_set(0, 0, 0); + localG = coords_set (0, 0, 0); // To be able to handle the situation properly where a component of // the gravity is along the z-axis we also define entrance (in) and @@ -254,45 +246,43 @@ if (inputType == 0) { // (0, 0, 1) // and the two points pointIn=(0, 0, 0) and pointOut=(0, 0, length) - normalInOut = coords_set(0, 0, 1); - pointIn = coords_set(0, 0, 0); - pointOut = coords_set(0, 0, length); + normalInOut = coords_set (0, 0, 1); + pointIn = coords_set (0, 0, 0); + pointOut = coords_set (0, 0, length); // Top plane (+y dir) can be spanned by (1, 0, 0) & (0, 0, 1) // and the point (0, yheight/2, 0) // A normal vector is (0, 1, 0) - normalTop = coords_set(0, 1, 0); - pointTop = coords_set(0, yheight/2, 0); + normalTop = coords_set (0, 1, 0); + pointTop = coords_set (0, yheight / 2, 0); // Bottom plane (-y dir) can be spanned by (1, 0, 0) & (0, 0, 1) // and the point (0, -yheight/2, 0) // A normal vector is (0, 1, 0) - normalBot = coords_set(0, 1, 0); - pointBot = coords_set(0, -yheight/2, 0); + normalBot = coords_set (0, 1, 0); + pointBot = coords_set (0, -yheight / 2, 0); // Left plane (+x dir) can be spanned by (0, 1, 0) & (0, 0, 1) // and the point (xwidth/2, 0, 0) // A normal vector is (1, 0, 0) - normalLeft = coords_set(1, 0, 0); - pointLeft = coords_set(xwidth/2, 0, 0); + normalLeft = coords_set (1, 0, 0); + pointLeft = coords_set (xwidth / 2, 0, 0); // Right plane (-x dir) can be spanned by (0, 1, 0) & (0, 0, 1) // and the point (-xwidth/2, 0, 0) // A normal vector is (1, 0, 0) - normalRight = coords_set(1, 0, 0); - pointRight = coords_set(-xwidth/2, 0, 0); + normalRight = coords_set (1, 0, 0); + pointRight = coords_set (-xwidth / 2, 0, 0); - - mirrorNormals = malloc(2*nvs*sizeof(Coords)); - mirrorPoints = malloc(2*nvs*sizeof(Coords)); + mirrorNormals = malloc (2 * nvs * sizeof (Coords)); + mirrorPoints = malloc (2 * nvs * sizeof (Coords)); /* Split in odd and even nvs cases */ - xwhalf = xwidth/(2*nvs); - xwfull = xwidth/nvs; - norm = 1.0/sqrt(xwhalf*xwhalf + length*length); + xwhalf = xwidth / (2 * nvs); + xwfull = xwidth / nvs; + norm = 1.0 / sqrt (xwhalf * xwhalf + length * length); - - /* For "all-mirror" solution: */ + /* For "all-mirror" solution: */ /* double dx; */ /* if (nvs % 2) { */ /* /\* Odd number of cavities *\/ */ @@ -308,10 +298,8 @@ if (inputType == 0) { /* mirrorPoints[2*counter-2] = coords_set(-(dx+counter*xwfull), 0, 0); */ /* mirrorPoints[2*counter-1] = coords_set((dx+counter*xwfull), 0, 0); */ /* normalMirror1 = coords_set(norm*length, 0, -norm*xwhalf); */ - + /* } */ - - %} TRACE @@ -319,7 +307,7 @@ TRACE double R; int sgn, ivs; /* time threshold */ - double tThreshold = 1e-10/sqrt(vx*vx + vy*vy + vz*vz); + double tThreshold = 1e-10 / sqrt (vx * vx + vy * vy + vz * vz); Coords normalMirror1, pointMirror1; Coords normalMirror2, pointMirror2; Coords* normalPointer = 0; @@ -327,272 +315,268 @@ TRACE // Pol variables double FN, FM, Rup, Rdown, refWeight; - if(!allow_inside_start || z<0){ + if (!allow_inside_start || z < 0) { /* Propagate neutron to guide entrance. */ PROP_Z0; } - if (!inside_rectangle(x, y, xwidth, yheight)) + if (!inside_rectangle (x, y, xwidth, yheight)) ABSORB; - if (debug) printf("-........-\n"); - - for(;;) { + if (debug) + printf ("-........-\n"); + + for (;;) { double tLeft, tRight, tTop, tBot, tIn, tOut, tMirror1, tMirror2; double tUp, tSide, time, endtime; double Q; //, dummy1, dummy2, dummy3; Coords vVec, xVec; int mirrorReflect; - + /* Hal parametrization */ - int N,m,Total; - double downmirror,upmirror; + int N, m, Total; + double downmirror, upmirror; - Total = nvs; - N = floor(fabs(x)/xwhalf); + N = floor (fabs (x) / xwhalf); /* if N == total, exge case ... */ - - m = 1 - (Total - floor(Total/2.0)*2); - if (debug) printf("Total=%i m=%i",Total,m); - if (debug) printf("neutron is in N=%i and m=%i\n",N,m); - - sgn = x/(fabs(x)); + m = 1 - (Total - floor (Total / 2.0) * 2); + if (debug) + printf ("Total=%i m=%i", Total, m); + if (debug) + printf ("neutron is in N=%i and m=%i\n", N, m); - if (sgn>0) { - downmirror = (floor((N+m)/2.0)*xwfull - m * xwhalf)*sgn; - upmirror = ((floor((N+m)/2.0)+1)*xwfull - m * xwhalf)*sgn; + sgn = x / (fabs (x)); + + if (sgn > 0) { + downmirror = (floor ((N + m) / 2.0) * xwfull - m * xwhalf) * sgn; + upmirror = ((floor ((N + m) / 2.0) + 1) * xwfull - m * xwhalf) * sgn; } else { - upmirror = (floor((N+m)/2.0)*xwfull - m * xwhalf)*sgn; - downmirror = ((floor((N+m)/2.0)+1)*xwfull - m * xwhalf)*sgn; + upmirror = (floor ((N + m) / 2.0) * xwfull - m * xwhalf) * sgn; + downmirror = ((floor ((N + m) / 2.0) + 1) * xwfull - m * xwhalf) * sgn; } - if (debug) printf("Found downmirror=%g , x=%g and upmirror=%g\n",downmirror,x,upmirror); - - normalMirror1 = coords_set(norm*length, 0, norm*xwhalf); - pointMirror1 = coords_set(upmirror, 0, 0); - normalMirror2 = coords_set(norm*length, 0, -norm*xwhalf); - pointMirror2 = coords_set(downmirror, 0, 0); - - if (debug) printf("Normal down=%g ,and up=%g with sign=%i\n",norm*xwhalf,-norm*xwhalf,sgn); - - - + if (debug) + printf ("Found downmirror=%g , x=%g and upmirror=%g\n", downmirror, x, upmirror); + + normalMirror1 = coords_set (norm * length, 0, norm * xwhalf); + pointMirror1 = coords_set (upmirror, 0, 0); + normalMirror2 = coords_set (norm * length, 0, -norm * xwhalf); + pointMirror2 = coords_set (downmirror, 0, 0); + + if (debug) + printf ("Normal down=%g ,and up=%g with sign=%i\n", norm * xwhalf, -norm * xwhalf, sgn); + /* ivs = floor(fabs(x)/(2*xwhalf)); - + normalMirror1 = coords_set(norm*length, 0, -norm*xwhalf); pointMirror1 = coords_set(sgn*ivs*xwhalf, 0, 0); normalMirror2 = coords_set(norm*length, 0, norm*xwhalf); pointMirror2 = coords_set(sgn*ivs*xwhalf, 0, 0);*/ - + mirrorReflect = 0; - xVec = coords_set(x, y, z); - vVec = coords_set(vx, vy, vz); + xVec = coords_set (x, y, z); + vVec = coords_set (vx, vy, vz); - solve_2nd_order(&tTop, NULL, 0.5*coords_sp(normalTop,localG), - coords_sp(normalTop, vVec), - coords_sp(normalTop, coords_sub(xVec, pointTop))); + solve_2nd_order (&tTop, NULL, 0.5 * coords_sp (normalTop, localG), coords_sp (normalTop, vVec), coords_sp (normalTop, coords_sub (xVec, pointTop))); - solve_2nd_order(&tBot, NULL, 0.5*coords_sp(normalBot,localG), - coords_sp(normalBot, vVec), - coords_sp(normalBot, coords_sub(xVec, pointBot))); + solve_2nd_order (&tBot, NULL, 0.5 * coords_sp (normalBot, localG), coords_sp (normalBot, vVec), coords_sp (normalBot, coords_sub (xVec, pointBot))); - solve_2nd_order(&tRight, NULL, 0.5*coords_sp(normalRight,localG), - coords_sp(normalRight, vVec), - coords_sp(normalRight, coords_sub(xVec, pointRight))); + solve_2nd_order (&tRight, NULL, 0.5 * coords_sp (normalRight, localG), coords_sp (normalRight, vVec), coords_sp (normalRight, coords_sub (xVec, pointRight))); - solve_2nd_order(&tLeft, NULL, 0.5*coords_sp(normalLeft,localG), - coords_sp(normalLeft, vVec), - coords_sp(normalLeft, coords_sub(xVec, pointLeft))); + solve_2nd_order (&tLeft, NULL, 0.5 * coords_sp (normalLeft, localG), coords_sp (normalLeft, vVec), coords_sp (normalLeft, coords_sub (xVec, pointLeft))); - solve_2nd_order(&tIn, NULL, 0.5*coords_sp(normalInOut,localG), - coords_sp(normalInOut, vVec), - coords_sp(normalInOut, coords_sub(xVec, pointIn))); + solve_2nd_order (&tIn, NULL, 0.5 * coords_sp (normalInOut, localG), coords_sp (normalInOut, vVec), coords_sp (normalInOut, coords_sub (xVec, pointIn))); - solve_2nd_order(&tOut, NULL, 0.5*coords_sp(normalInOut,localG), - coords_sp(normalInOut, vVec), - coords_sp(normalInOut, coords_sub(xVec, pointOut))); + solve_2nd_order (&tOut, NULL, 0.5 * coords_sp (normalInOut, localG), coords_sp (normalInOut, vVec), coords_sp (normalInOut, coords_sub (xVec, pointOut))); - solve_2nd_order(&tMirror1, NULL, 0.5*coords_sp(normalMirror1,localG), - coords_sp(normalMirror1, vVec), - coords_sp(normalMirror1, coords_sub(xVec, pointMirror1))); + solve_2nd_order (&tMirror1, NULL, 0.5 * coords_sp (normalMirror1, localG), coords_sp (normalMirror1, vVec), + coords_sp (normalMirror1, coords_sub (xVec, pointMirror1))); - solve_2nd_order(&tMirror2, NULL, 0.5*coords_sp(normalMirror2,localG), - coords_sp(normalMirror2, vVec), - coords_sp(normalMirror2, coords_sub(xVec, pointMirror2))); + solve_2nd_order (&tMirror2, NULL, 0.5 * coords_sp (normalMirror2, localG), coords_sp (normalMirror2, vVec), + coords_sp (normalMirror2, coords_sub (xVec, pointMirror2))); /* Choose appropriate reflection time */ - if (tTop>tThreshold && (tTop tThreshold && (tTop < tBot || tBot <= tThreshold)) + tUp = tTop; else - tUp=tBot; + tUp = tBot; - if (tLeft>tThreshold && (tLeft tThreshold && (tLeft < tRight || tRight <= tThreshold)) + tSide = tLeft; else - tSide=tRight; + tSide = tRight; - if (tUp>tThreshold && (tUp tThreshold && (tUp < tSide || tSide <= tThreshold)) + time = tUp; else - time=tSide; + time = tSide; - if (tMirror1>tThreshold && tMirror1 tThreshold && tMirror1 < time) { + time = tMirror1; mirrorReflect = 1; // flag to show which reflection function to use } - if (tMirror2>tThreshold && tMirror2 tThreshold && tMirror2 < time) { + time = tMirror2; mirrorReflect = 2; // flag to show which reflection function to use } - if (time<=tThreshold) - fprintf(stdout, "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + if (time <= tThreshold) + fprintf (stdout, + "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); /* Has neutron left the guide? */ - if (tOut>tThreshold && (tOut tThreshold && (tOut < tIn || tIn <= tThreshold)) + endtime = tOut; else - endtime=tIn; + endtime = tIn; if (time > endtime) break; - if(time <= tThreshold) { + if (time <= tThreshold) { - printf("Time below threshold!\n"); - fprintf(stdout, "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + printf ("Time below threshold!\n"); + fprintf (stdout, + "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); break; } - if(debug>0 && time==tLeft) { + if (debug > 0 && time == tLeft) { - fprintf(stdout, "\nPol_guide_vmirror: %s: Left side hit: x, v, normal, point, gravity\n", NAME_CURRENT_COMP); - coords_print(xVec); - coords_print(vVec); - coords_print(normalLeft); - coords_print(pointLeft); - coords_print(localG); + fprintf (stdout, "\nPol_guide_vmirror: %s: Left side hit: x, v, normal, point, gravity\n", NAME_CURRENT_COMP); + coords_print (xVec); + coords_print (vVec); + coords_print (normalLeft); + coords_print (pointLeft); + coords_print (localG); - fprintf(stdout, "\nA: %f, B: %f, C: %f, tLeft: %f\n", - 0.5*coords_sp(normalLeft,localG),coords_sp(normalLeft, vVec), - coords_sp(normalLeft, coords_sub(xVec, pointLeft)), tLeft); + fprintf (stdout, "\nA: %f, B: %f, C: %f, tLeft: %f\n", 0.5 * coords_sp (normalLeft, localG), coords_sp (normalLeft, vVec), + coords_sp (normalLeft, coords_sub (xVec, pointLeft)), tLeft); } - if(debug>0) - fprintf(stdout, "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" - "tUp: %f, tSide: %f, time: %f\n", NAME_CURRENT_COMP, - tTop, tBot, tRight, tLeft, tUp, tSide, time); + if (debug > 0) + fprintf (stdout, + "Pol_guide_vmirror: %s: tTop: %f, tBot:%f, tRight: %f, tLeft: %f\n" + "tUp: %f, tSide: %f, time: %f\n", + NAME_CURRENT_COMP, tTop, tBot, tRight, tLeft, tUp, tSide, time); - if(debug>0) - fprintf(stdout, "Pol_guide_vmirror: %s: Start v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); + if (debug > 0) + fprintf (stdout, "Pol_guide_vmirror: %s: Start v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); - PROP_DT(time); + PROP_DT (time); if (mcgravitation) - vVec = coords_set(vx, vy, vz); + vVec = coords_set (vx, vy, vz); SCATTER; - if(time==tTop) + if (time == tTop) normalPointer = &normalTop; - else if(time==tBot) + else if (time == tBot) normalPointer = &normalBot; - else if(time==tRight) + else if (time == tRight) normalPointer = &normalRight; - else if(time==tLeft) + else if (time == tLeft) normalPointer = &normalLeft; - else if(time==tMirror1) + else if (time == tMirror1) normalPointer = &normalMirror1; - else if(time==tMirror2) + else if (time == tMirror2) normalPointer = &normalMirror2; else - fprintf(stderr, "Pol_guide_vmirror: %s: This should never happen!!!!\n", NAME_CURRENT_COMP); + fprintf (stderr, "Pol_guide_vmirror: %s: This should never happen!!!!\n", NAME_CURRENT_COMP); - Q = 2*coords_sp(vVec, *normalPointer)*V2K; + Q = 2 * coords_sp (vVec, *normalPointer) * V2K; - if(!mirrorReflect) { + if (!mirrorReflect) { // we have hit one of the sides. Always reflect. - vVec = coords_add(vVec, coords_scale(*normalPointer, -Q*K2V)); - StdReflecFunc(fabs(Q), rParToFunc, &refWeight); + vVec = coords_add (vVec, coords_scale (*normalPointer, -Q * K2V)); + StdReflecFunc (fabs (Q), rParToFunc, &refWeight); p *= refWeight; } else { // we have hit one of the mirrors - StdDoubleReflecFunc(fabs(Q), rUpParToFunc, &Rup); - StdDoubleReflecFunc(fabs(Q), rDownParToFunc, &Rdown); - if (Rup < 0) ABSORB; - if (Rup > 1) Rup =1 ; - if (Rdown < 0) ABSORB; - if (Rdown > 1) Rdown =1 ; - - GetMonoPolFNFM(Rup, Rdown, &FN, &FM); - GetMonoPolRefProb(FN, FM, sy, &refWeight); + StdDoubleReflecFunc (fabs (Q), rUpParToFunc, &Rup); + StdDoubleReflecFunc (fabs (Q), rDownParToFunc, &Rdown); + if (Rup < 0) + ABSORB; + if (Rup > 1) + Rup = 1; + if (Rdown < 0) + ABSORB; + if (Rdown > 1) + Rdown = 1; + + GetMonoPolFNFM (Rup, Rdown, &FN, &FM); + GetMonoPolRefProb (FN, FM, sy, &refWeight); /* Output of PW discussions with Hal Lee 2024/03/08 - We have now done our QM "measurement", thus - forcing the spin to assume up/down: */ - sx=0; sz=0; + We have now done our QM "measurement", thus + forcing the spin to assume up/down: */ + sx = 0; + sz = 0; // check that refWeight is meaningfull - if (refWeight < 0) ABSORB; - if (refWeight > 1) refWeight =1 ; + if (refWeight < 0) + ABSORB; + if (refWeight > 1) + refWeight = 1; - if (rand01()1.000001) { // check that polarisation is meaningful - fprintf(stderr, "Pol_guide_vmirror: %s: polarisation |s|=%g > 1 s=[%g,%g,%g]\n", - NAME_CURRENT_COMP, sx*sx+sy*sy+sz*sz, sx, sy, sz); + if (sx * sx + sy * sy + sz * sz > 1.000001) { // check that polarisation is meaningful + fprintf (stderr, "Pol_guide_vmirror: %s: polarisation |s|=%g > 1 s=[%g,%g,%g]\n", NAME_CURRENT_COMP, sx * sx + sy * sy + sz * sz, sx, sy, sz); } } - if(p==0) { + if (p == 0) { ABSORB; break; } // set new velocity vector - coords_get(vVec, &vx, &vy, &vz); + coords_get (vVec, &vx, &vy, &vz); - if(debug>0) - fprintf(stdout, "Pol_guide_vmirror: %s: End v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); + if (debug > 0) + fprintf (stdout, "Pol_guide_vmirror: %s: End v: (%f, %f, %f)\n", NAME_CURRENT_COMP, vx, vy, vz); } - %} FINALLY %{ - free(mirrorNormals); - free(mirrorPoints); + free (mirrorNormals); + free (mirrorPoints); %} MCDISPLAY %{ int i, j; - - double dx = xwidth/(2*nvs); + + double dx = xwidth / (2 * nvs); // draw box - box(0, 0, length/2.0, xwidth, yheight, length,0, 0, 1, 0); - - for(i = -nvs; i<=nvs; i+=2) - for(j = -1; j<=1; j+=2) { - double dx2 = (i+j)*dx; - if (dx2 < -xwidth/2.0) dx2 = -xwidth/2.0; - if (dx2 > xwidth/2.0) dx2 = xwidth/2.0; - line(dx2, j*yheight/2, 0, i*dx, j*yheight/2, length); + box (0, 0, length / 2.0, xwidth, yheight, length, 0, 0, 1, 0); + + for (i = -nvs; i <= nvs; i += 2) + for (j = -1; j <= 1; j += 2) { + double dx2 = (i + j) * dx; + if (dx2 < -xwidth / 2.0) + dx2 = -xwidth / 2.0; + if (dx2 > xwidth / 2.0) + dx2 = xwidth / 2.0; + line (dx2, j * yheight / 2, 0, i * dx, j * yheight / 2, length); } %} diff --git a/mcstas-comps/optics/Pol_mirror.comp b/mcstas-comps/optics/Pol_mirror.comp index ba615bb8b4..98a06604a7 100644 --- a/mcstas-comps/optics/Pol_mirror.comp +++ b/mcstas-comps/optics/Pol_mirror.comp @@ -108,34 +108,32 @@ DECLARE INITIALIZE %{ - if (strlen(rUpData) && strcmp(rUpData,"NULL")){ - if (Table_Read(&rUpTable, rUpData, 1) <= 0) { - fprintf(stderr,"Pol_mirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rUpData); - exit(1); + if (strlen (rUpData) && strcmp (rUpData, "NULL")) { + if (Table_Read (&rUpTable, rUpData, 1) <= 0) { + fprintf (stderr, "Pol_mirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rUpData); + exit (1); } - rUpTableFlag=1; - }else{ - rUpTableFlag=0; + rUpTableFlag = 1; + } else { + rUpTableFlag = 0; } - if (strlen(rUpData) && strcmp(rUpData,"NULL")){ - if (Table_Read(&rDownTable, rDownData, 1) <= 0) { - fprintf(stderr,"Pol_mirror: %s: can not read file %s\n", - NAME_CURRENT_COMP, rDownData); - exit(1); + if (strlen (rUpData) && strcmp (rUpData, "NULL")) { + if (Table_Read (&rDownTable, rDownData, 1) <= 0) { + fprintf (stderr, "Pol_mirror: %s: can not read file %s\n", NAME_CURRENT_COMP, rDownData); + exit (1); } - rDownTableFlag=1; - }else{ - rDownTableFlag=0; + rDownTableFlag = 1; + } else { + rDownTableFlag = 0; } - if ((zwidth<=0) || (yheight <= 0)) { - fprintf(stderr, "Pol_mirror: %s: NULL or negative length scale!\n" - "ERROR (zwidth=%g,yheight=%g). Exiting\n", - NAME_CURRENT_COMP, zwidth, yheight); - exit(1); + if ((zwidth <= 0) || (yheight <= 0)) { + fprintf (stderr, + "Pol_mirror: %s: NULL or negative length scale!\n" + "ERROR (zwidth=%g,yheight=%g). Exiting\n", + NAME_CURRENT_COMP, zwidth, yheight); + exit (1); } - %} TRACE @@ -147,94 +145,96 @@ TRACE // propagate to mirror plane PROP_X0; - if (inside_rectangle(z, y, zwidth, yheight)) {/* Intersect the crystal? */ + if (inside_rectangle (z, y, zwidth, yheight)) { /* Intersect the crystal? */ // calculate scattering vector magnitude - Q = fabs(2*vx*V2K); + Q = fabs (2 * vx * V2K); // calculate reflection probability // downgraded from defpars version - //rUpFunc(Q, rUpParPtr, &Rup); - if(rUpTableFlag){ - Rup=Table_Value(rUpTable,Q,1); - }else{ - StdReflecFunc(Q, rUpPar, &Rup); + // rUpFunc(Q, rUpParPtr, &Rup); + if (rUpTableFlag) { + Rup = Table_Value (rUpTable, Q, 1); + } else { + StdReflecFunc (Q, rUpPar, &Rup); } // downgraded from defpars version - //rDownFunc(Q, rDownParPtr, &Rdown); - if(rDownTableFlag){ - Rdown=Table_Value(rDownTable,Q,1); - }else{ - StdReflecFunc(Q, rDownPar, &Rdown); + // rDownFunc(Q, rDownParPtr, &Rdown); + if (rDownTableFlag) { + Rdown = Table_Value (rDownTable, Q, 1); + } else { + StdReflecFunc (Q, rDownPar, &Rdown); } - if(Rup != Rdown) { + if (Rup != Rdown) { isPolarising = 1; - GetMonoPolFNFM(Rup, Rdown, &FN, &FM); - GetMonoPolRefProb(FN, FM, sy, &refWeight); + GetMonoPolFNFM (Rup, Rdown, &FN, &FM); + GetMonoPolRefProb (FN, FM, sy, &refWeight); /* Output of PW discussions with Hal Lee 2024/03/08 We have now done our QM "measurement", thus forcing the spin to assume up/down: */ - sx=0; sz=0; + sx = 0; + sz = 0; } else refWeight = Rup; // check that refWeight is meaningfull - if (refWeight < 0) ABSORB; - if (refWeight > 1) refWeight =1 ; + if (refWeight < 0) + ABSORB; + if (refWeight > 1) + refWeight = 1; // find out if neutrons is reflected or transmitted if (p_reflect < 0 || p_reflect > 1) { // reflect OR transmit using mirror reflectivity - if (rand01()1.000001) - fprintf(stderr,"Pol_mirror: %s: Warning: polarisation |s| = %g > 1\n", - NAME_CURRENT_COMP, sx*sx+sy*sy+sz*sz); // check that polarisation is meaningfull + if (isPolarising) + if (sx * sx + sy * sy + sz * sz > 1.000001) + fprintf (stderr, "Pol_mirror: %s: Warning: polarisation |s| = %g > 1\n", NAME_CURRENT_COMP, + sx * sx + sy * sy + sz * sz); // check that polarisation is meaningfull SCATTER; } /* End intersect the mirror */ - else - { + else { /* neutron will miss the mirror, so don't propagate i.e restore it */ - RESTORE_NEUTRON(INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p); + RESTORE_NEUTRON (INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p); } %} MCDISPLAY %{ - rectangle("yz", 0, 0, 0, zwidth, yheight); + rectangle ("yz", 0, 0, 0, zwidth, yheight); %} END diff --git a/mcstas-comps/optics/Pol_tabled_field.comp b/mcstas-comps/optics/Pol_tabled_field.comp index 40709cffa2..df0e6267c2 100644 --- a/mcstas-comps/optics/Pol_tabled_field.comp +++ b/mcstas-comps/optics/Pol_tabled_field.comp @@ -56,65 +56,70 @@ SHARE #define tabled_pol_angular_accuracy (1.0*DEG2RAD) #define tabled_pol_initial_timestep 1e-5; - -#pragma acc routine seq - int table_magnetic_field(double x, double y, double z, double t, double *bx, double *by, double *bz, - struct interpolator_struct *interpolator) - { - if (!interpolator) return 1; - if( (interpolator_interpolate3_3(interpolator, x,y,z, bx,by,bz)) != NULL ){ + #pragma acc routine seq + int + table_magnetic_field (double x, double y, double z, double t, double* bx, double* by, double* bz, struct interpolator_struct* interpolator) { + if (!interpolator) + return 1; + if ((interpolator_interpolate3_3 (interpolator, x, y, z, bx, by, bz)) != NULL) { return 0; - }else{ + } else { return 1; } } - double fmax(double, double); - double fmin(double, double); + double fmax (double, double); + double fmin (double, double); /*most of this function is borrowed from SimpleNumMagnetPrecession in pol-lib.c*/ -#pragma acc routine seq - int prop_precess(_class_particle *_particle, struct interpolator_struct *interpolator, double dt){ + #pragma acc routine seq + int + prop_precess (_class_particle* _particle, struct interpolator_struct* interpolator, double dt) { double Bx, By, Bz, tabled_pol_phiz; double BxStart, ByStart, BzStart, Bstart; double BxTemp, ByTemp, BzTemp, Btemp; double Bstep, tabled_pol_timeStep, tabled_pol_sp; - const double tabled_pol_spThreshold = cos(tabled_pol_angular_accuracy); - _class_particle *pp = _particle; - table_magnetic_field(pp->x, pp->y, pp->z, pp->t,&BxTemp, &ByTemp, &BzTemp,interpolator); + const double tabled_pol_spThreshold = cos (tabled_pol_angular_accuracy); + _class_particle* pp = _particle; + table_magnetic_field (pp->x, pp->y, pp->z, pp->t, &BxTemp, &ByTemp, &BzTemp, interpolator); do { - Bx = 0; By = 0; Bz = 0; tabled_pol_phiz = 0; - BxStart = BxTemp; ByStart = ByTemp; BzStart = BzTemp; - Bstart = sqrt(BxStart*BxStart + ByStart*ByStart + BzStart*BzStart); + Bx = 0; + By = 0; + Bz = 0; + tabled_pol_phiz = 0; + BxStart = BxTemp; + ByStart = ByTemp; + BzStart = BzTemp; + Bstart = sqrt (BxStart * BxStart + ByStart * ByStart + BzStart * BzStart); tabled_pol_timeStep = tabled_pol_initial_timestep; /*check if we need to take multiple steps of maximum size tabled_pol_timeStep*/ - if(dtx+ pp->vx*tabled_pol_timeStep; - yp = pp->y+ pp->vy*tabled_pol_timeStep; - zp = pp->z+ pp->vz*tabled_pol_timeStep; + xp = pp->x + pp->vx * tabled_pol_timeStep; + yp = pp->y + pp->vy * tabled_pol_timeStep; + zp = pp->z + pp->vz * tabled_pol_timeStep; - table_magnetic_field(xp, yp, zp,pp->t+tabled_pol_timeStep, &BxTemp, &ByTemp, &BzTemp,interpolator); + table_magnetic_field (xp, yp, zp, pp->t + tabled_pol_timeStep, &BxTemp, &ByTemp, &BzTemp, interpolator); /* not so elegant, but this is how we make sure that the steps decrease when the WHILE condition is not met*/ tabled_pol_timeStep *= 0.5; - Btemp = sqrt(BxTemp*BxTemp + ByTemp*ByTemp + BzTemp*BzTemp); + Btemp = sqrt (BxTemp * BxTemp + ByTemp * ByTemp + BzTemp * BzTemp); - tabled_pol_sp = scalar_prod(BxStart, ByStart, BzStart, BxTemp, ByTemp, BzTemp); - tabled_pol_sp /= Bstart*Btemp; + tabled_pol_sp = scalar_prod (BxStart, ByStart, BzStart, BxTemp, ByTemp, BzTemp); + tabled_pol_sp /= Bstart * Btemp; - } while (tabled_pol_spFLT_EPSILON); + } while (tabled_pol_sp < tabled_pol_spThreshold && tabled_pol_timeStep > FLT_EPSILON); - tabled_pol_timeStep*=2; + tabled_pol_timeStep *= 2; // update coordinate values pp->x = xp; @@ -127,123 +132,122 @@ SHARE Bx = 0.5 * (BxStart + BxTemp); By = 0.5 * (ByStart + ByTemp); Bz = 0.5 * (BzStart + BzTemp); - tabled_pol_phiz = fmod(sqrt(Bx*Bx+ By*By+ Bz*Bz) * tabled_pol_timeStep*tabled_pol_omegaL, 2*PI); + tabled_pol_phiz = fmod (sqrt (Bx * Bx + By * By + Bz * Bz) * tabled_pol_timeStep * tabled_pol_omegaL, 2 * PI); /* Do the neutron spin precession for the small timestep*/ - if(!(Bx==0 && By==0 && Bz==0)) { + if (!(Bx == 0 && By == 0 && Bz == 0)) { double sx_in = pp->sx; double sy_in = pp->sy; double sz_in = pp->sz; - rotate(pp->sx, pp->sy, pp->sz, sx_in,sy_in,sz_in, tabled_pol_phiz, Bx, By, Bz); + rotate (pp->sx, pp->sy, pp->sz, sx_in, sy_in, sz_in, tabled_pol_phiz, Bx, By, Bz); } - } while (dt>0); - + } while (dt > 0); } - %} DECLARE %{ int shape; - struct interpolator_struct *interpolator; + struct interpolator_struct* interpolator; %} INITIALIZE %{ - enum shapes {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY}; + enum shapes { NONE = 0, BOX, WINDOW, CYLINDER, SPHERE, ANY }; /* these default field functions are part of pol-lib */ /*initialize the interpolation vertex structure*/ - #ifdef OPENACC // If "aotomatic mode is given on GPU, switch // to 'default' - if (!strcmp(interpol_method,"NULL")) { - sprintf(interpol_method,"default"); + if (!strcmp (interpol_method, "NULL")) { + sprintf (interpol_method, "default"); } #endif // Handle default mode in both CPU and GPU case - if (!strcmp(interpol_method,"default")) { + if (!strcmp (interpol_method, "default")) { #ifdef OPENACC // Default is to assume regular interpolation on GPU - sprintf(interpol_method,"regular"); + sprintf (interpol_method, "regular"); #else // On CPU we use "NULL" allowing to jump automatically // between regular and kdtree interpolation - sprintf(interpol_method,"NULL"); + sprintf (interpol_method, "NULL"); #endif } - interpolator = interpolator_load(filename, 3, 3, interpol_method); - interpolator_info(interpolator); + interpolator = interpolator_load (filename, 3, 3, interpol_method); + interpolator_info (interpolator); /*initialize shape to either be window/box/cylinder*/ /*some logic here to enter through a box or cylinder*/ #ifdef USE_OFF - if(geometry && strlen(geometry)){ - shape=ANY; - }else - #endif - if(xwidth && yheight && zdepth){ - shape=BOX; - }else if(radius && yheight){ - shape=CYLINDER; - }else if (radius) { - shape=SPHERE; - } - + if (geometry && strlen (geometry)) { + shape = ANY; + } else + #endif + if (xwidth && yheight && zdepth) { + shape = BOX; + } else if (radius && yheight) { + shape = CYLINDER; + } else if (radius) { + shape = SPHERE; + } %} TRACE %{ - double t0,t1; - int hit; - enum {NONE=0, BOX, WINDOW, CYLINDER, SPHERE, ANY} shapes; - - /*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 nuetron is already there.*/ - if(t0>FLT_EPSILON) { - PROP_DT(t0); - t1-=t0; - } - 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 nuetron is already there.*/ - if(t0>FLT_EPSILON) { - PROP_DT(t0); - t1-=t0; - } - break; - case SPHERE: - hit=sphere_intersect(&t0,&t1,x,y,z,vx,vy,vz,radius); - if(!hit) ABSORB; - if(t0>FLT_EPSILON) { - PROP_DT(t0); - t1-=t0; - } - break; + double t0, t1; + int hit; + enum { NONE = 0, BOX, WINDOW, CYLINDER, SPHERE, ANY } shapes; + + /*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 nuetron is already there.*/ + if (t0 > FLT_EPSILON) { + PROP_DT (t0); + t1 -= t0; + } + 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 nuetron is already there.*/ + if (t0 > FLT_EPSILON) { + PROP_DT (t0); + t1 -= t0; } - /*Do propagation including spin precession*/ - prop_precess(_particle,interpolator,t1); + break; + case SPHERE: + hit = sphere_intersect (&t0, &t1, x, y, z, vx, vy, vz, radius); + if (!hit) + ABSORB; + if (t0 > FLT_EPSILON) { + PROP_DT (t0); + t1 -= t0; + } + break; + } + /*Do propagation including spin precession*/ + prop_precess (_particle, interpolator, t1); %} MCDISPLAY %{ - - rectangle("xy",0,0,0,xwidth,yheight); + + rectangle ("xy", 0, 0, 0, xwidth, yheight); %} END diff --git a/mcstas-comps/optics/Refractor.comp b/mcstas-comps/optics/Refractor.comp index 6657cd4824..1a529fd3ea 100644 --- a/mcstas-comps/optics/Refractor.comp +++ b/mcstas-comps/optics/Refractor.comp @@ -153,166 +153,165 @@ SHARE %{ -%include "read_table-lib" -%include "interoff-lib" -%include "ref-lib" - + %include "read_table-lib" + %include "interoff-lib" + %include "ref-lib" /* wrappers to intersection routines which also return the normal vector */ - int box_intersect_n(double *t0, double *t1, - double x, double y, double z, - double vx, double vy, double vz, - double dx, double dy, double dz, - double *nx, double *ny, double *nz) { - - double dt=0; - int intersect = box_intersect(t0, t1, x,y,z, vx,vy,vz, dx,dy,dz); + int + box_intersect_n (double* t0, double* t1, double x, double y, double z, double vx, double vy, double vz, double dx, double dy, double dz, double* nx, double* ny, + double* nz) { + + double dt = 0; + int intersect = box_intersect (t0, t1, x, y, z, vx, vy, vz, dx, dy, dz); /* determine normal vector depending on hit face */ if (intersect) { dt = *t0 <= 0 || *t0 > *t1 ? *t1 : *t0; - if (dt < 0) intersect = 0; + if (dt < 0) + intersect = 0; } if (intersect && dx && dy && dz) { - x += vx*dt; y += vy*dt; z += vz*dt; + x += vx * dt; + y += vy * dt; + z += vz * dt; /* determine hit face: difference to plane is closest to 0 */ - *nx = trunc(2.002*x/dx); - *ny = trunc(2.002*y/dy); - *nz = trunc(2.002*z/dz); + *nx = trunc (2.002 * x / dx); + *ny = trunc (2.002 * y / dy); + *nz = trunc (2.002 * z / dz); } - return(intersect); + return (intersect); } // box_intersect_n /* sphere: when radius < 0 we always use the further intersection point to determine the normal vector */ - int sphere_intersect_n(double *t0, double *t1, - double x, double y, double z, - double vx, double vy, double vz, - double r, - double *nx, double *ny, double *nz) { - - double dt=0; - int intersect = sphere_intersect(t0, t1, x,y,z, vx,vy,vz, r); + int + sphere_intersect_n (double* t0, double* t1, double x, double y, double z, double vx, double vy, double vz, double r, double* nx, double* ny, double* nz) { + + double dt = 0; + int intersect = sphere_intersect (t0, t1, x, y, z, vx, vy, vz, r); if (intersect) { - if (r >0) /* First intersection in positive time */ + if (r > 0) /* First intersection in positive time */ dt = *t0 <= 0 || *t0 > *t1 ? *t1 : *t0; - else /* always second intersection */ + else /* always second intersection */ dt = *t1; - if (dt < 0) intersect = 0; + if (dt < 0) + intersect = 0; } if (intersect && r) { /* must propagate locally to determine normal vector. */ - x += vx*dt; y += vy*dt; z += vz*dt; - *nx = x; - *ny = y; - *nz = z; + x += vx * dt; + y += vy * dt; + z += vz * dt; + *nx = x; + *ny = y; + *nz = z; } - return(intersect); + return (intersect); } // sphere_intersect_n - int cylinder_intersect_n(double *t0, double *t1, - double x, double y, double z, - double vx, double vy, double vz, - double r, double h, - double *nx, double *ny, double *nz) { + int + cylinder_intersect_n (double* t0, double* t1, double x, double y, double z, double vx, double vy, double vz, double r, double h, double* nx, double* ny, + double* nz) { - double dt=0; - int intersect = cylinder_intersect(t0, t1, - x,y,z, vx,vy,vz, r,h); + double dt = 0; + int intersect = cylinder_intersect (t0, t1, x, y, z, vx, vy, vz, r, h); if (intersect) { - if (r >0) /* First intersection in positive time */ + if (r > 0) /* First intersection in positive time */ dt = *t0 <= 0 || *t0 > *t1 ? *t1 : *t0; - else /* always second intersection */ + else /* always second intersection */ dt = *t1; - if (dt < 0) intersect = 0; + if (dt < 0) + intersect = 0; } if (intersect && r) { /* must propagate locally to determine normal vector */ - x += vx*dt; z += vz*dt; - *nx = x; - *ny = 0; /* cylinder is vertical */ - *nz = z; + x += vx * dt; + z += vz * dt; + *nx = x; + *ny = 0; /* cylinder is vertical */ + *nz = z; } - return(intersect); + return (intersect); } // cylinder_intersect_n -// two sphere separated with a given thickness -int lens_sphere_intersect_n(double *t0, double *t1, -double x, double y, double z, -double vx, double vy, double vz, -double r, double dz, -double *nx, double *ny, double *nz) { + // two sphere separated with a given thickness + int + lens_sphere_intersect_n (double* t0, double* t1, double x, double y, double z, double vx, double vy, double vz, double r, double dz, double* nx, double* ny, + double* nz) { /* two spherical lenses, concave, with given radius, thickness=zdepth at meniscus, plus cross section=xwidth*yheight */ - int intersect1 = 0, intersect2 = 0; - double nx1=0,nx2=0,ny1=0,ny2=0,nz1=0,nz2=0; - double t2=0,t3=0; + int intersect1 = 0, intersect2 = 0; + double nx1 = 0, nx2 = 0, ny1 = 0, ny2 = 0, nz1 = 0, nz2 = 0; + double t2 = 0, t3 = 0; - *t0=*t1=0; + *t0 = *t1 = 0; - intersect1 = sphere_intersect_n(t0, t1, x,y,z+r+dz/2, - vx,vy,vz, -r, &nx1,&ny1,&nz1); /* -r: use the further intersection with sphere */ + intersect1 = sphere_intersect_n (t0, t1, x, y, z + r + dz / 2, vx, vy, vz, -r, &nx1, &ny1, &nz1); /* -r: use the further intersection with sphere */ - intersect2 = sphere_intersect_n(&t2, &t3, x,y,z-r-dz/2, - vx,vy,vz, r, &nx2,&ny2,&nz2); + intersect2 = sphere_intersect_n (&t2, &t3, x, y, z - r - dz / 2, vx, vy, vz, r, &nx2, &ny2, &nz2); /* usual case with 4 intersections: return t1 and t2 */ if (intersect1 || intersect2) { - if (intersect1) *t0=*t1; - if (intersect2) *t1= t2; + if (intersect1) + *t0 = *t1; + if (intersect2) + *t1 = t2; } if (!intersect1 && !intersect2) - return(0); + return (0); if (!intersect1 || !intersect2) { if (!intersect1) { /* intersection with the 2st sphere: return t2 and some other external intersection (container box entrance) t0 */ - intersect1 = box_intersect_n(t0,&t3, x,y,z, vx,vy,vz, - 2*r, 2*r, 2*r+dz, &nx1,&ny1,&nz1); + intersect1 = box_intersect_n (t0, &t3, x, y, z, vx, vy, vz, 2 * r, 2 * r, 2 * r + dz, &nx1, &ny1, &nz1); } else { /* intersection with the 1st sphere: return t1 and some other external intersection (container box exit) t3 */ - intersect2 = box_intersect_n(&t2,t1, x,y,z, vx,vy,vz, - 2*r, 2*r, 2*r+dz, &nx2,&ny2,&nz2); + intersect2 = box_intersect_n (&t2, t1, x, y, z, vx, vy, vz, 2 * r, 2 * r, 2 * r + dz, &nx2, &ny2, &nz2); } } /* the normal vector corresponds to the first forward intersection */ if (intersect1 || intersect2) { if (*t0 < 0) { - *nx = nx2; *ny = ny2; *nz = nz2; + *nx = nx2; + *ny = ny2; + *nz = nz2; } else { - *nx = nx1; *ny = ny1; *nz = nz1; + *nx = nx1; + *ny = ny1; + *nz = nz1; } } /* no intersection: use intersection with container box */ - return(intersect1+intersect2); + return (intersect1 + intersect2); } // lens_sphere_intersect_n - + /* Surface_wavyness: function to rotate normal vector around axis for roughness * with specified tilt angle (rad) * RETURNS: rotated nx,ny,nz coordinates */ - #pragma acc routine - void Surface_wavyness(double *nx, double *ny, double *nz, double tilt, _class_particle *_particle) - { - double nt_x, nt_y, nt_z; /* transverse vector */ - double n1_x, n1_y, n1_z; /* normal vector (tmp) */ + #pragma acc routine + void + Surface_wavyness (double* nx, double* ny, double* nz, double tilt, _class_particle* _particle) { + double nt_x, nt_y, nt_z; /* transverse vector */ + double n1_x, n1_y, n1_z; /* normal vector (tmp) */ /* normal vector n_z = [ 0,1,0], n_t = n x n_z; */ - vec_prod(nt_x,nt_y,nt_z, *nx,*ny,*nz, 0,1,0); + vec_prod (nt_x, nt_y, nt_z, *nx, *ny, *nz, 0, 1, 0); /* rotate n with angle wav_z around n_t -> n1 */ - tilt /= (sqrt(8*log(2)))*randnorm(); - rotate(n1_x,n1_y,n1_z, *nx,*ny,*nz, tilt, nt_x,nt_y,nt_z); + tilt /= (sqrt (8 * log (2))) * randnorm (); + rotate (n1_x, n1_y, n1_z, *nx, *ny, *nz, tilt, nt_x, nt_y, nt_z); /* rotate n1 with angle phi around n -> nt */ - rotate(nt_x,nt_y,nt_z, n1_x,n1_y,n1_z, 2*PI*rand01(), *nx,*ny,*nz); + rotate (nt_x, nt_y, nt_z, n1_x, n1_y, n1_z, 2 * PI * rand01 (), *nx, *ny, *nz); - *nx=nt_x; - *ny=nt_y; - *nz=nt_z; + *nx = nt_x; + *ny = nt_y; + *nz = nt_z; } %} @@ -329,57 +328,57 @@ DECLARE INITIALIZE %{ - mean_n=0; events=0; - theta1=0; theta2=0; + mean_n = 0; + events = 0; + theta1 = 0; + theta2 = 0; /* set geometry from input geometry parameters */ - if (!geometry || !strlen(geometry) || !strcmp(geometry, "NULL") || !strcmp(geometry, "0")) { - if (radius && yheight && !xwidth) strcpy(geometry, "cylinder"); - else if (xwidth && yheight && zdepth && !radius) strcpy(geometry, "box"); - else if (radius && !yheight && !xwidth && !zdepth) strcpy(geometry, "sphere"); - } else if (radius && zdepth && !strcmp(geometry, "lens_sphere")) { + if (!geometry || !strlen (geometry) || !strcmp (geometry, "NULL") || !strcmp (geometry, "0")) { + if (radius && yheight && !xwidth) + strcpy (geometry, "cylinder"); + else if (xwidth && yheight && zdepth && !radius) + strcpy (geometry, "box"); + else if (radius && !yheight && !xwidth && !zdepth) + strcpy (geometry, "sphere"); + } else if (radius && zdepth && !strcmp (geometry, "lens_sphere")) { /* NOP: OK */ - } else if (strcmp(geometry, "NULL") && strcmp(geometry, "0") && xwidth && yheight && zdepth) { + } else if (strcmp (geometry, "NULL") && strcmp (geometry, "0") && xwidth && yheight && zdepth) { #ifndef USE_OFF - fprintf(stderr,"Error: You are attempting to use an OFF geometry without -DUSE_OFF. You will need to recompile with that define set!\n"); - exit(-1); + fprintf (stderr, "Error: You are attempting to use an OFF geometry without -DUSE_OFF. You will need to recompile with that define set!\n"); + exit (-1); #else /* off/ply case */ - if (!off_init(geometry, xwidth, yheight, zdepth, 0, &offdata)) - exit(printf("Refractor: %s: FATAL: invalid OFF/PLY geometry specification for file '%s'.\n", - NAME_CURRENT_COMP, geometry)); + if (!off_init (geometry, xwidth, yheight, zdepth, 0, &offdata)) + exit (printf ("Refractor: %s: FATAL: invalid OFF/PLY geometry specification for file '%s'.\n", NAME_CURRENT_COMP, geometry)); #endif - } - else exit(printf("Refractor: %s: FATAL: invalid geometry specification.\n" - " Check geometry,xwidth,yheight,zdepth,radius\n", - NAME_CURRENT_COMP)); + } else + exit (printf ("Refractor: %s: FATAL: invalid geometry specification.\n" + " Check geometry,xwidth,yheight,zdepth,radius\n", + NAME_CURRENT_COMP)); /* compute refraction parameters, if needed */ - if (density==0 || weight<=0) - exit(printf("Refractor: %s: FATAL: invalid material density or molar weight: density=%g weight=%g\n", - NAME_CURRENT_COMP, density, weight)); - rho= fabs(density)*6.02214179*1e23*1e-24/weight; /* per at/Angs^3 */ - if (sigma_coh==0) - exit(printf("Refractor: %s: FATAL: invalid material coherent cross section: sigma_coh=%g\n", - NAME_CURRENT_COMP, sigma_coh)); - bc=sqrt(fabs(sigma_coh)*100/4/PI)*1e-5; /* bound coherent scattering length */ - if (sigma_coh<0) bc *= -1; + if (density == 0 || weight <= 0) + exit (printf ("Refractor: %s: FATAL: invalid material density or molar weight: density=%g weight=%g\n", NAME_CURRENT_COMP, density, weight)); + rho = fabs (density) * 6.02214179 * 1e23 * 1e-24 / weight; /* per at/Angs^3 */ + if (sigma_coh == 0) + exit (printf ("Refractor: %s: FATAL: invalid material coherent cross section: sigma_coh=%g\n", NAME_CURRENT_COMP, sigma_coh)); + bc = sqrt (fabs (sigma_coh) * 100 / 4 / PI) * 1e-5; /* bound coherent scattering length */ + if (sigma_coh < 0) + bc *= -1; /* use bulk to compute reflectivity critical angle/wavevector */ - if (Qc <=0) - Qc = 4*sqrt(PI*rho*fabs(bc)); - MPI_MASTER( - printf("Refractor: %s: rho.bc=%g [10-6 Angs-2] Qc=%g [Angs-1]. geometry=%s\n", - NAME_CURRENT_COMP, rho*bc*1e6, Qc, geometry); - ); + if (Qc <= 0) + Qc = 4 * sqrt (PI * rho * fabs (bc)); + MPI_MASTER (printf ("Refractor: %s: rho.bc=%g [10-6 Angs-2] Qc=%g [Angs-1]. geometry=%s\n", NAME_CURRENT_COMP, rho * bc * 1e6, Qc, geometry);); %} TRACE %{ - int intersect = 0; - int iterations= 0; - char event[256]; + int intersect = 0; + int iterations = 0; + char event[256]; - theta1=theta2=0; + theta1 = theta2 = 0; #ifdef OPENACC #ifdef USE_OFF @@ -388,269 +387,287 @@ TRACE #else #define thread_offdata offdata #endif - + do { - double nx=0, ny=0, nz=0; - double t0=0, t1=0, dt=0; + double nx = 0, ny = 0, nz = 0; + double t0 = 0, t1 = 0, dt = 0; intersect = 0; iterations++; #ifndef OPENACC - strcpy(event, " "); + strcpy (event, " "); #endif /* determine intersection times and normal vector with geometry */ - if (!strcmp(geometry, "sphere")) { - intersect = sphere_intersect_n(&t0, &t1, x,y,z, vx,vy,vz, - radius, &nx,&ny,&nz); - } else if (!strcmp(geometry, "lens_sphere")) { - intersect = lens_sphere_intersect_n(&t0, &t1, x,y,z, vx,vy,vz, - radius, zdepth, &nx,&ny,&nz); - } else if (!strcmp(geometry, "cylinder")) { - intersect = cylinder_intersect_n(&t0, &t1, x,y,z, vx,vy,vz, - radius, yheight, &nx,&ny,&nz); - } else if (!strcmp(geometry, "box")) { - intersect = box_intersect_n(&t0, &t1, x,y,z, vx,vy,vz, - xwidth, yheight, zdepth, &nx,&ny,&nz); + if (!strcmp (geometry, "sphere")) { + intersect = sphere_intersect_n (&t0, &t1, x, y, z, vx, vy, vz, radius, &nx, &ny, &nz); + } else if (!strcmp (geometry, "lens_sphere")) { + intersect = lens_sphere_intersect_n (&t0, &t1, x, y, z, vx, vy, vz, radius, zdepth, &nx, &ny, &nz); + } else if (!strcmp (geometry, "cylinder")) { + intersect = cylinder_intersect_n (&t0, &t1, x, y, z, vx, vy, vz, radius, yheight, &nx, &ny, &nz); + } else if (!strcmp (geometry, "box")) { + intersect = box_intersect_n (&t0, &t1, x, y, z, vx, vy, vz, xwidth, yheight, zdepth, &nx, &ny, &nz); } #ifdef USE_OFF - else if (geometry && strcmp(geometry, "NULL") && strcmp(geometry, "0")) { + else if (geometry && strcmp (geometry, "NULL") && strcmp (geometry, "0")) { Coords n0, n1; - intersect = off_intersect(&t0, &t1, &n0, &n1, x, y, z, vx, vy, vz, 0, 0, 0, thread_offdata ); + intersect = off_intersect (&t0, &t1, &n0, &n1, x, y, z, vx, vy, vz, 0, 0, 0, thread_offdata); if (intersect) { - coords_get(t0 <= 0 || t0 > t1 ? n1 : n0, &nx, &ny, &nz); + coords_get (t0 <= 0 || t0 > t1 ? n1 : n0, &nx, &ny, &nz); } } #endif if (intersect) { - if (t1 < t0) { double tmp=t0; t0=t1; t1=tmp; } + if (t1 < t0) { + double tmp = t0; + t0 = t1; + t1 = tmp; + } dt = t0 <= 1e-10 ? t1 : t0; /* full propagation time inside geometry */ - if (dt < 0) dt=0; + if (dt < 0) + dt = 0; } - if (dt<=0) break; + if (dt <= 0) + break; #ifndef OPENACC - strcpy(event, "none"); + strcpy (event, "none"); #endif if (verbose) - printf("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(intersect) %s\n", - NAME_CURRENT_COMP, __LINE__, mcget_run_num(), iterations, geometry, intersect, t0,t1, dt, event); + printf ("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(intersect) %s\n", NAME_CURRENT_COMP, __LINE__, mcget_run_num (), + iterations, geometry, intersect, t0, t1, dt, event); /* scattering/absorption in bulk, refraction/reflection at interface */ if (intersect) { - char scatter_me=0, refract_me=0; - double my_t=0, d_path=0; - double v=0,lambda=0; - char inbulk = t0 < 0 && t1 > 0; + char scatter_me = 0, refract_me = 0; + double my_t = 0, d_path = 0; + double v = 0, lambda = 0; + char inbulk = t0 < 0 && t1 > 0; /* when density is given negative, we assume bulk refractive material is 'outside' or 'before' the shape */ - if (density < 0) inbulk = !inbulk; + if (density < 0) + inbulk = !inbulk; - v = sqrt(vx*vx+vy*vy+vz*vz); - if (!v) ABSORB; - lambda = 3956.0032/v; - d_path = v*dt; /* full length in material */ + v = sqrt (vx * vx + vy * vy + vz * vz); + if (!v) + ABSORB; + lambda = 3956.0032 / v; + d_path = v * dt; /* full length in material */ /* compute probability to scatter/absorb inside bulk */ if (inbulk) { /* scatter inside bulk */ - double ws = 0; - double p_trans= 0, p_scatt=0, mc_trans=0, mc_scatt=0; - int flag = 0; + double ws = 0; + double p_trans = 0, p_scatt = 0, mc_trans = 0, mc_scatt = 0; + int flag = 0; double my_a_v = (rho * 100 * sigma_abs); - double my_a = my_a_v*2200/v; - double my_s = rho * 100 *(sigma_inc+sigma_coh); + double my_a = my_a_v * 2200 / v; + double my_s = rho * 100 * (sigma_inc + sigma_coh); my_t = my_a + my_s; - ws = my_s/my_t; /* (inc+coh)/(inc+coh+abs) */ + ws = my_s / my_t; /* (inc+coh)/(inc+coh+abs) */ /* Proba of transmission along length d_path */ - p_trans = exp(-my_t*d_path); + p_trans = exp (-my_t * d_path); p_scatt = 1 - p_trans; flag = 0; /* flag used for propagation to exit point before ending */ /* are we next to the exit ? probably no scattering (avoid rounding errors) */ - if (my_s*d_path <= 4e-7) { - flag = 1; /* No interaction before the exit */ + if (my_s * d_path <= 4e-7) { + flag = 1; /* No interaction before the exit */ } /* force a given fraction of the beam to scatter */ - if (p_interact>0 && p_interact<=1) { + if (p_interact > 0 && p_interact <= 1) { /* we force a portion of the beam to interact */ /* This is used to improve statistics on single scattering (and multiple) */ - mc_trans = 1-p_interact; + mc_trans = 1 - p_interact; } else { mc_trans = p_trans; /* 1 - p_scatt */ } mc_scatt = 1 - mc_trans; /* portion of beam to scatter (or force to) */ - if (mc_scatt <= 0 || mc_scatt>1) flag=1; + if (mc_scatt <= 0 || mc_scatt > 1) + flag = 1; /* MC choice: Interaction or transmission ? */ - scatter_me = !flag && ws && p_scatt && mc_scatt > 0 && (mc_scatt >= 1 || rand01() < mc_scatt); + scatter_me = !flag && ws && p_scatt && mc_scatt > 0 && (mc_scatt >= 1 || rand01 () < mc_scatt); /* account for absorption and retain scattered fraction */ /* we have chosen portion mc_scatt of beam instead of p_scatt, so we compensate */ if (scatter_me) - p *= ws * fabs(p_scatt/mc_scatt); + p *= ws * fabs (p_scatt / mc_scatt); else if (p_trans && mc_trans) - p *= fabs(p_trans/mc_trans); /* attenuate beam by portion which is scattered (and left along) */ + p *= fabs (p_trans / mc_trans); /* attenuate beam by portion which is scattered (and left along) */ if (verbose) - printf("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(inbulk) %s scatter_me=%i\n", - NAME_CURRENT_COMP, __LINE__, mcget_run_num(), iterations, geometry, intersect, t0,t1, dt, event, scatter_me); + printf ("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(inbulk) %s scatter_me=%i\n", NAME_CURRENT_COMP, __LINE__, + mcget_run_num (), iterations, geometry, intersect, t0, t1, dt, event, scatter_me); } /* if inbulk */ /* handle absorption and scattering in material */ /* req: my_t, d_path, focus_ah, focus_aw */ if (p_scatter && scatter_me) { - double dl=0, solid_angle=0; - double vx2=0, vy2=0, vz2=0; + double dl = 0, solid_angle = 0; + double vx2 = 0, vy2 = 0, vz2 = 0; - if (my_t*d_path < 1e-6){ + if (my_t * d_path < 1e-6) { /* For very weak scattering, use simple uniform sampling of scattering point to avoid rounding errors. */ - dl = rand0max(d_path); /* length */ + dl = rand0max (d_path); /* length */ } else { - double a = rand0max((1 - exp(-my_t*d_path))); - dl = -log(1 - a) / my_t; /* length */ + double a = rand0max ((1 - exp (-my_t * d_path))); + dl = -log (1 - a) / my_t; /* length */ } - PROP_DT(dl/v); dt = 0; // we propagate in the bulk + PROP_DT (dl / v); + dt = 0; // we propagate in the bulk SCATTER; /* 1 */ /* scatter randomly in cone to take into account material sigma */ - randvec_target_circle(&vx2, &vy2, &vz2, - &solid_angle, vx,vy,vz, focus_scatter*DEG2RAD); - vx=vx2; vy=vy2; vz=vz2; + randvec_target_circle (&vx2, &vy2, &vz2, &solid_angle, vx, vy, vz, focus_scatter * DEG2RAD); + vx = vx2; + vy = vy2; + vz = vz2; if (solid_angle) { - p *= solid_angle/4/PI; - NORM(vx, vy, vz); - vx*=v; vy*=v; vz*=v; /* scattering is elastic */ + p *= solid_angle / 4 / PI; + NORM (vx, vy, vz); + vx *= v; + vy *= v; + vz *= v; /* scattering is elastic */ } /* force to recompute intersection with new neutron direction/position */ refract_me = 0; - #ifndef OPENACC - strcpy(event, "scatter"); - #endif + #ifndef OPENACC + strcpy (event, "scatter"); + #endif if (verbose) - printf("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(scatter) %s\n", - NAME_CURRENT_COMP, __LINE__, mcget_run_num(), iterations, geometry, intersect, t0,t1, dl/v, event); + printf ("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(scatter) %s\n", NAME_CURRENT_COMP, __LINE__, mcget_run_num (), + iterations, geometry, intersect, t0, t1, dl / v, event); } else { refract_me = 1; } /* if scatter */ - if ((p_refract||p_reflect) && refract_me) { // refract or reflect on the surface - double n=0; /* refractive index */ - double n1=0, n2=0; - - double q=0, R=0; - double par[] = {R0, Qc, 6.0, 1.0, 1.0/300.0}; + if ((p_refract || p_reflect) && refract_me) { // refract or reflect on the surface + double n = 0; /* refractive index */ + double n1 = 0, n2 = 0; + double q = 0, R = 0; + double par[] = { R0, Qc, 6.0, 1.0, 1.0 / 300.0 }; /* propagate to surface */ - PROP_DT(dt); dt=0; - SCATTER; SCATTER; /* 2 */ + PROP_DT (dt); + dt = 0; + SCATTER; + SCATTER; /* 2 */ /* compute refraction index */ - n = sqrt(1-(lambda*lambda*rho*bc/PI)); + n = sqrt (1 - (lambda * lambda * rho * bc / PI)); mean_n += n; events++; /* compute incoming angle */ - if (inbulk) { n1=n; n2=1; } /* from bulk to void */ - else { n1=1; n2=n; } /* from void to bulk */ + if (inbulk) { + n1 = n; + n2 = 1; + } /* from bulk to void */ + else { + n1 = 1; + n2 = n; + } /* from void to bulk */ /* compute reflectivity */ - q = fabs(2*vz*V2Q); + q = fabs (2 * vz * V2Q); /* Reflectivity (see component Guide). */ - StdReflecFunc(q, par, &R); + StdReflecFunc (q, par, &R); /* tilt normal vector for roughness, in cone theta_RMS */ - NORM(nx,ny,nz); + NORM (nx, ny, nz); /* cone angle from RMS roughness = atan(2*RMS/lambda) */ - if (RMS>0) Surface_wavyness(&nx, &ny, &nz, atan(2*RMS/lambda), _particle); + if (RMS > 0) + Surface_wavyness (&nx, &ny, &nz, atan (2 * RMS / lambda), _particle); /* Snell-Descartes formula for refraction n1 sin(theta1) = n2 sin(theta2) */ /* https://en.wikipedia.org/wiki/Snell's_law */ - Coords N = coords_set(nx,ny,nz); // normal vector to surface - Coords V = coords_set(vx,vy,vz); // incoming velocity - Coords I = coords_scale(V, 1/v); // normalised ray = v/|v| + Coords N = coords_set (nx, ny, nz); // normal vector to surface + Coords V = coords_set (vx, vy, vz); // incoming velocity + Coords I = coords_scale (V, 1 / v); // normalised ray = v/|v| // theta1: incident angle to the surface normal - double cos_theta1 = -coords_sp(N,I); // cos(theta1) = -N.I + double cos_theta1 = -coords_sp (N, I); // cos(theta1) = -N.I - if (fabs(cos_theta1) > 1) ABSORB; // should never occur... - theta1 = acos(cos_theta1)*RAD2DEG; + if (fabs (cos_theta1) > 1) + ABSORB; // should never occur... + theta1 = acos (cos_theta1) * RAD2DEG; // reflected ray: probability R // reflected beam: I + 2cos(theta1).N - Coords I_reflect = coords_add(I, coords_scale(N, 2*cos_theta1)); + Coords I_reflect = coords_add (I, coords_scale (N, 2 * cos_theta1)); // reflected velocity: I_reflect.v - Coords V_reflect = coords_scale(I_reflect, v); + Coords V_reflect = coords_scale (I_reflect, v); // compute refracted angle theta2... - double sqr_cos_theta2 = 1-(n1/n2)*(n1/n2)*(1-cos_theta1*cos_theta1); + double sqr_cos_theta2 = 1 - (n1 / n2) * (n1 / n2) * (1 - cos_theta1 * cos_theta1); // now choose which one to use, and compute outgoing velocity if (0 < sqr_cos_theta2 && sqr_cos_theta2 < 1) { // refraction is possible // theta2: refracted angle to the surface normal - double cos_theta2= sqrt(sqr_cos_theta2); + double cos_theta2 = sqrt (sqr_cos_theta2); // select reflection (or refraction) from Monte-Carlo choice with probability R // in this case we expect R to be small (q > Qc) - if (p_reflect && 0 < R && R < 1 && rand01() < R) { + if (p_reflect && 0 < R && R < 1 && rand01 () < R) { // choose reflection from MC theta2 = theta1; - coords_get(V_reflect, &vx, &vy, &vz); - #ifndef OPENACC - strcpy(event, "reflect"); - #endif + coords_get (V_reflect, &vx, &vy, &vz); + #ifndef OPENACC + strcpy (event, "reflect"); + #endif } else if (p_refract) { // compute refracted ray - theta2 = acos(cos_theta2)*RAD2DEG; + theta2 = acos (cos_theta2) * RAD2DEG; - Coords I_refract = coords_add(coords_scale(I, n1/n2), - coords_scale(N, n1/n2*cos_theta1 + (cos_theta1 < 0 ? cos_theta2 : -cos_theta2) )); - Coords V_refract = coords_scale(I_refract, v); + Coords I_refract = coords_add (coords_scale (I, n1 / n2), coords_scale (N, n1 / n2 * cos_theta1 + (cos_theta1 < 0 ? cos_theta2 : -cos_theta2))); + Coords V_refract = coords_scale (I_refract, v); - coords_get(V_refract, &vx, &vy, &vz); - #ifndef OPENACC - strcpy(event, "refract"); - #endif + coords_get (V_refract, &vx, &vy, &vz); + #ifndef OPENACC + strcpy (event, "refract"); + #endif SCATTER; /* 3 */ } } else if (p_reflect) { // only reflection: below total reflection theta2 = theta1; - if (0 < R && R < 1) p *= R; // should be R0 - coords_get(V_reflect, &vx, &vy, &vz); - #ifndef OPENACC - strcpy(event, "reflect"); - #endif + if (0 < R && R < 1) + p *= R; // should be R0 + coords_get (V_reflect, &vx, &vy, &vz); + #ifndef OPENACC + strcpy (event, "reflect"); + #endif } /* propagate by a small time so that we leave the surface */ - PROP_DT(1e-9); + PROP_DT (1e-9); if (verbose) - printf("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(reflect/refract) %s theta1=%g theta2=%g 1-n=%g |xy|=%g nz=%g\n", - NAME_CURRENT_COMP, __LINE__, mcget_run_num(), iterations, geometry, intersect, t0,t1, dt, event, - theta1, theta2, 1-n, sqrt(x*x+y*y), nz); + printf ("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=(reflect/refract) %s theta1=%g theta2=%g 1-n=%g |xy|=%g nz=%g\n", + NAME_CURRENT_COMP, __LINE__, mcget_run_num (), iterations, geometry, intersect, t0, t1, dt, event, theta1, theta2, 1 - n, sqrt (x * x + y * y), + nz); } /* if reflect/refract */ } /* if intersect */ - else break; + else + break; if (verbose) - printf("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=%s\n", - NAME_CURRENT_COMP, __LINE__, mcget_run_num(), iterations, geometry, intersect, t0,t1, dt, event); - } while (intersect && iterations<100); - + printf ("%s:%i: [neutron=%li iteration=%i] intersect %s=%i t0=%g t1=%g dt=%g event=%s\n", NAME_CURRENT_COMP, __LINE__, mcget_run_num (), iterations, + geometry, intersect, t0, t1, dt, event); + } while (intersect && iterations < 100); %} FINALLY %{ @@ -676,41 +693,41 @@ FINALLY %{ MCDISPLAY %{ /* show geometry */ - if (!strcmp(geometry, "sphere")) { - circle("xy", 0, 0, 0, radius); - circle("xz", 0, 0, 0, radius); - circle("yz", 0, 0, 0, radius); - } else if (!strcmp(geometry, "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); - } else if (!strcmp(geometry, "box")) { - box(0,0,0, xwidth, yheight, zdepth,0, 0, 1, 0); - } else if (!strcmp(geometry, "lens_sphere")) { + if (!strcmp (geometry, "sphere")) { + circle ("xy", 0, 0, 0, radius); + circle ("xz", 0, 0, 0, radius); + circle ("yz", 0, 0, 0, radius); + } else if (!strcmp (geometry, "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); + } else if (!strcmp (geometry, "box")) { + box (0, 0, 0, xwidth, yheight, zdepth, 0, 0, 1, 0); + } else if (!strcmp (geometry, "lens_sphere")) { // sphere: x^2+y^2+z^2=radius. In 2D: radius^2=z^2+r^2 int index; - for (index=0; index<=3; index++) { - double z=radius*(index == 3 ? 0.95 : index/3.0); - double r=sqrt(radius*radius-z*z); - circle("xy", 0, 0, z-(radius+zdepth/2), r); - circle("xy", 0, 0,-z+(radius+zdepth/2), r); + for (index = 0; index <= 3; index++) { + double z = radius * (index == 3 ? 0.95 : index / 3.0); + double r = sqrt (radius * radius - z * z); + circle ("xy", 0, 0, z - (radius + zdepth / 2), r); + circle ("xy", 0, 0, -z + (radius + zdepth / 2), r); } - box(0,0,0, 2*radius, 2*radius, 2*radius+zdepth,0, 0, 1, 0); - } else if (!strcmp(geometry, "lens_parabola")) { + box (0, 0, 0, 2 * radius, 2 * radius, 2 * radius + zdepth, 0, 0, 1, 0); + } else if (!strcmp (geometry, "lens_parabola")) { // parabola: z = (x^2+y^2)/4/radius. In 2D: z = r^2/4/radius int index; - for (index=0; index<=3; index++) { - double z=radius*(index == 3 ? 0.95 : index/3.0); - double r=sqrt(z*4*radius); - circle("xy", 0, 0,-z-(zdepth/2), r); - circle("xy", 0, 0, z+(zdepth/2), r); + for (index = 0; index <= 3; index++) { + double z = radius * (index == 3 ? 0.95 : index / 3.0); + double r = sqrt (z * 4 * radius); + circle ("xy", 0, 0, -z - (zdepth / 2), r); + circle ("xy", 0, 0, z + (zdepth / 2), r); } - box(0,0,0, 4*radius, 4*radius, 2*radius+zdepth,0, 0, 1, 0); - } else if (geometry && strcmp(geometry, "NULL") && strcmp(geometry, "0")) { - off_display(offdata); + box (0, 0, 0, 4 * radius, 4 * radius, 2 * radius + zdepth, 0, 0, 1, 0); + } else if (geometry && strcmp (geometry, "NULL") && strcmp (geometry, "0")) { + off_display (offdata); } %} END diff --git a/mcstas-comps/optics/Rotator.comp b/mcstas-comps/optics/Rotator.comp index 9aee360356..b6b693d621 100644 --- a/mcstas-comps/optics/Rotator.comp +++ b/mcstas-comps/optics/Rotator.comp @@ -61,50 +61,46 @@ INITIALIZE %{ if (direction <= 0 || direction > 3) { - fprintf(stderr,"%s: Please indicate direction=1,2 or 3 (x,y or z)\n",NAME_CURRENT_COMP,direction); - exit(-1); + fprintf (stderr, "%s: Please indicate direction=1,2 or 3 (x,y or z)\n", NAME_CURRENT_COMP, direction); + exit (-1); } /* Initialize uservar string */ - sprintf(rot_var,"Rot_%i",_comp->_index); - + sprintf (rot_var, "Rot_%i", _comp->_index); %} TRACE %{ -if (nu != 0 || phase != 0) { /* rotate neutron w/r to position of component */ + if (nu != 0 || phase != 0) { /* rotate neutron w/r to position of component */ /* approximation of rotating frame */ /* current coordinates of neutron in centered static frame */ - double dt=0; + double dt = 0; double angle; Rotation R; - dt = -z/vz; /* time shift to center of component */ - angle = fmod(360*nu*(t+dt)+phase, 360); /* in deg */ - double rx=0,ry=0,rz=0; + dt = -z / vz; /* time shift to center of component */ + angle = fmod (360 * nu * (t + dt) + phase, 360); /* in deg */ + double rx = 0, ry = 0, rz = 0; /* will rotate neutron instead of comp: negative side */ - if (direction==1) { - rx=-angle*DEG2RAD; + if (direction == 1) { + rx = -angle * DEG2RAD; + } else if (direction == 2) { + ry = -angle * DEG2RAD; + } else if (direction == 3) { + rz = -angle * DEG2RAD; } - else if (direction==2) { - ry=-angle*DEG2RAD; - } - else if (direction==3) { - rz=-angle*DEG2RAD; - } - - rot_set_rotation(R, rx, ry, rz); + + rot_set_rotation (R, rx, ry, rz); /* apply rotation to centered coordinates */ - Coords tmp = coords_set(x,y,z); - coords_get(rot_apply(R, tmp), &x, &y, &z); + Coords tmp = coords_set (x, y, z); + coords_get (rot_apply (R, tmp), &x, &y, &z); /* rotate speed */ - tmp = coords_set(vx,vy,vz); - coords_get(rot_apply(R, tmp), &vx, &vy, &vz); - particle_setvar_void(_particle, rot_var, &(R)); + tmp = coords_set (vx, vy, vz); + coords_get (rot_apply (R, tmp), &vx, &vy, &vz); + particle_setvar_void (_particle, rot_var, &(R)); } - %} @@ -112,12 +108,11 @@ MCDISPLAY %{ int ih; - - if (nu || phase) { - double radius = 0.1; - /* cylinder to visualise the rotating frame */ - circle("xz", 0, 0, 0,radius); - } + if (nu || phase) { + double radius = 0.1; + /* cylinder to visualise the rotating frame */ + circle ("xz", 0, 0, 0, radius); + } %} END diff --git a/mcstas-comps/optics/Selector.comp b/mcstas-comps/optics/Selector.comp index e9fcce5a71..a67e0eac76 100644 --- a/mcstas-comps/optics/Selector.comp +++ b/mcstas-comps/optics/Selector.comp @@ -66,8 +66,14 @@ xwidth=0, yheight=0, nslit=72, d=0.0004, radius=0.12, alpha=48.298, nu=500) INITIALIZE %{ -if (xwidth > 0) { xmax=xwidth/2; xmin=-xmax; } - if (yheight > 0) { ymax=yheight/2; ymin=-ymax; } + if (xwidth > 0) { + xmax = xwidth / 2; + xmin = -xmax; + } + if (yheight > 0) { + ymax = yheight / 2; + ymin = -ymax; + } %} TRACE @@ -78,34 +84,34 @@ TRACE double sel_phase, act_radius; // distance between neutron and selector axle PROP_Z0; - E=VS2E*(vx*vx+vy*vy+vz*vz); - if (xxmax || yymax) - ABSORB; /* because outside frame */ - dt = length/vz; + E = VS2E * (vx * vx + vy * vy + vz * vz); + if (x < xmin || x > xmax || y < ymin || y > ymax) + ABSORB; /* because outside frame */ + dt = length / vz; /* get phase angle of selector rotor as MonteCarlo choice only the free space between two neighboring spokes is taken p is adjusted to transmission for parallel beam */ - n_angle_in = atan2( x,y+radius)*RAD2DEG; - act_radius = sqrt(x*x + pow(radius+y,2)); - closed_angle = d/act_radius*RAD2DEG; - open_angle = 360/nslit-closed_angle; - sel_phase = open_angle*rand01(); - p *= (open_angle/(closed_angle+open_angle)); + n_angle_in = atan2 (x, y + radius) * RAD2DEG; + act_radius = sqrt (x * x + pow (radius + y, 2)); + closed_angle = d / act_radius * RAD2DEG; + open_angle = 360 / nslit - closed_angle; + sel_phase = open_angle * rand01 (); + p *= (open_angle / (closed_angle + open_angle)); - PROP_DT(dt); + PROP_DT (dt); - if (xxmax || yymax) - ABSORB; /* because outside frame */ + if (x < xmin || x > xmax || y < ymin || y > ymax) + ABSORB; /* because outside frame */ /* now let's look whether the neutron is still - between the same two spokes or absorbed meanwhile */ + between the same two spokes or absorbed meanwhile */ - n_angle_out = atan2(x,y+radius)*RAD2DEG; /* neutron beam might be divergent */ + n_angle_out = atan2 (x, y + radius) * RAD2DEG; /* neutron beam might be divergent */ - sel_phase = sel_phase + nu*dt*360 - alpha; /* rotor turned, but spokes are torsaded */ + sel_phase = sel_phase + nu * dt * 360 - alpha; /* rotor turned, but spokes are torsaded */ - if (n_angle_out<(n_angle_in-sel_phase) || n_angle_out>(n_angle_in-sel_phase+open_angle) ) - ABSORB; /* because must have passed absorber */ + if (n_angle_out < (n_angle_in - sel_phase) || n_angle_out > (n_angle_in - sel_phase + open_angle)) + ABSORB; /* because must have passed absorber */ else SCATTER; %} @@ -126,61 +132,49 @@ MCDISPLAY double xw, yh; phi = alpha; - Width = (xmax-xmin)/2; - height = (ymax-ymin)/2; - x0 = xmin; x1 = xmax; - y0 = ymin; y1 = ymax; - l0 = length; l1 = l0; + Width = (xmax - xmin) / 2; + height = (ymax - ymin) / 2; + x0 = xmin; + x1 = xmax; + y0 = ymin; + y1 = ymax; + l0 = length; + l1 = l0; r0 = radius; r = r0 + height; - x0 = -Width/2.0; - x1 = Width/2.0; - y0 = -height/2.0; - y1 = height/2.0; - z0 = 0; - z1 = 0; - z2 = l1; - z3 = l0; - - - xw = Width/2.0; - yh = height/2.0; + x0 = -Width / 2.0; + x1 = Width / 2.0; + y0 = -height / 2.0; + y1 = height / 2.0; + z0 = 0; + z1 = 0; + z2 = l1; + z3 = l0; + + xw = Width / 2.0; + yh = height / 2.0; /* Draw apertures */ - for(a = z0;;) - { - multiline(3, x0-xw, (double)y1, a, - (double)x0, (double)y1, a, - (double)x0, y1+yh, a); - multiline(3, x1+xw, (double)y1, a, - (double)x1, (double)y1, a, - (double)x1, y1+yh, a); - multiline(3, x0-xw, (double)y0, a, - (double)x0, (double)y0, a, - (double)x0, y0-yh, a); - multiline(3, x1+xw, (double)y0, a, - (double)x1, (double)y0, a, - (double)x1, y0-yh, a); - if(a == z3) + for (a = z0;;) { + multiline (3, x0 - xw, (double)y1, a, (double)x0, (double)y1, a, (double)x0, y1 + yh, a); + multiline (3, x1 + xw, (double)y1, a, (double)x1, (double)y1, a, (double)x1, y1 + yh, a); + multiline (3, x0 - xw, (double)y0, a, (double)x0, (double)y0, a, (double)x0, y0 - yh, a); + multiline (3, x1 + xw, (double)y0, a, (double)x1, (double)y0, a, (double)x1, y0 - yh, a); + if (a == z3) break; else a = z3; } /* Draw cylinder. */ - circle("xy", 0, -r0, z1, r); - circle("xy", 0, -r0, z2, r); - line(0, -r0, z1, 0, -r0, z2); - for(a = 0; a < 2*PI; a += PI/8) - { - multiline(4, - 0.0, -r0, z1, - r*cos(a), r*sin(a) - r0, z1, - r*cos(a + DEG2RAD*phi), r*sin(a + DEG2RAD*phi) - r0, z2, - 0.0, -r0, z2); + circle ("xy", 0, -r0, z1, r); + circle ("xy", 0, -r0, z2, r); + line (0, -r0, z1, 0, -r0, z2); + for (a = 0; a < 2 * PI; a += PI / 8) { + multiline (4, 0.0, -r0, z1, r * cos (a), r * sin (a) - r0, z1, r * cos (a + DEG2RAD * phi), r * sin (a + DEG2RAD * phi) - r0, z2, 0.0, -r0, z2); } /* - + multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, diff --git a/mcstas-comps/optics/Set_pol.comp b/mcstas-comps/optics/Set_pol.comp index 48d3502f22..54479b6a4f 100644 --- a/mcstas-comps/optics/Set_pol.comp +++ b/mcstas-comps/optics/Set_pol.comp @@ -51,19 +51,17 @@ DECLARE INITIALIZE %{ - if (sqrt(px*px + py*py + pz*pz) > 1+FLT_EPSILON) - { - printf("WARNING: Set_pol(%s): Polarisation vector (px, py, pz) is unphysical!\n" - "px*px + py*py + pz*pz = %.18e> 1. Renormalizing...\n",NAME_CURRENT_COMP,(px*px + py*py + pz*pz)); - NORM(px,py,pz); + if (sqrt (px * px + py * py + pz * pz) > 1 + FLT_EPSILON) { + printf ("WARNING: Set_pol(%s): Polarisation vector (px, py, pz) is unphysical!\n" + "px*px + py*py + pz*pz = %.18e> 1. Renormalizing...\n", + NAME_CURRENT_COMP, (px * px + py * py + pz * pz)); + NORM (px, py, pz); } - if(randomOn!=0){ - printf("INFO: Set_pol(%s): Setting polarization randomly.\n", - NAME_CURRENT_COMP); - }else{ - printf("INFO: Set_pol(%s): Setting polarization to (%f, %f, %f)\n", - NAME_CURRENT_COMP, px, py, pz); + if (randomOn != 0) { + printf ("INFO: Set_pol(%s): Setting polarization randomly.\n", NAME_CURRENT_COMP); + } else { + printf ("INFO: Set_pol(%s): Setting polarization to (%f, %f, %f)\n", NAME_CURRENT_COMP, px, py, pz); } %} @@ -71,41 +69,38 @@ TRACE %{ double theta, phi; - if(randomOn!=0) - { - theta = 2*PI*rand01(); // 0-2*PI - phi = acos(2*rand01()-1); // 0-PI + if (randomOn != 0) { + theta = 2 * PI * rand01 (); // 0-2*PI + phi = acos (2 * rand01 () - 1); // 0-PI - sx = sin(phi)*cos(theta); - sy = sin(phi)*sin(theta); - sz = cos(phi); - if (!normalize){ - double r=rand01(); - sx*=r; - sy*=r; - sz*=r; + sx = sin (phi) * cos (theta); + sy = sin (phi) * sin (theta); + sz = cos (phi); + if (!normalize) { + double r = rand01 (); + sx *= r; + sy *= r; + sz *= r; } } else { sx = px; sy = py; sz = pz; - if (normalize){ - NORM(sx,sy,sz); + if (normalize) { + NORM (sx, sy, sz); } } - - SCATTER; %} MCDISPLAY %{ /* A bit ugly; hard-coded dimensions. */ - - line(0,0,0,0.2,0,0); - line(0,0,0,0,0.2,0); - line(0,0,0,0,0,0.2); + + line (0, 0, 0, 0.2, 0, 0); + line (0, 0, 0, 0, 0.2, 0); + line (0, 0, 0, 0, 0, 0.2); %} END diff --git a/mcstas-comps/optics/Slit.comp b/mcstas-comps/optics/Slit.comp index af56006cad..17fb2300d2 100644 --- a/mcstas-comps/optics/Slit.comp +++ b/mcstas-comps/optics/Slit.comp @@ -48,82 +48,77 @@ DEFINE COMPONENT Slit /* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ SHARE %{ -void slit_print_if(int condition, char* level, char* message, char* component){ - if (condition) fprintf(stderr, "Slit: %s: %s: %s\n", component, level, message); -} -void slit_error_if(int condition, char* message, char* component){ - slit_print_if(condition, "Error", message, component); - if (condition) exit(-1); -} -void slit_warning_if(int condition, char* message, char* component){ - slit_print_if(condition, "Warning", message, component); -} + void + slit_print_if (int condition, char* level, char* message, char* component) { + if (condition) + fprintf (stderr, "Slit: %s: %s: %s\n", component, level, message); + } + void + slit_error_if (int condition, char* message, char* component) { + slit_print_if (condition, "Error", message, component); + if (condition) + exit (-1); + } + void + slit_warning_if (int condition, char* message, char* component) { + slit_print_if (condition, "Warning", message, component); + } %} DECLARE %{ char isradial; %} INITIALIZE %{ -if (is_unset(radius)){ - isradial=0; - if (all_set(3, xwidth, xmin, xmax)){ - slit_error_if(xwidth != xmax - xmin, "specifying xwidth, xmin and xmax requires consistent parameters", NAME_CURRENT_COMP); - } else { - slit_error_if(is_unset(xwidth) && any_unset(2, xmin, xmax), "specify either xwidth or xmin & xmax", NAME_CURRENT_COMP); - } - if (all_set(3, yheight, ymin, ymax)){ - slit_error_if(yheight != ymax - ymin, "specifying yheight, ymin and ymax requires consistent parameters", NAME_CURRENT_COMP); + if (is_unset (radius)) { + isradial = 0; + if (all_set (3, xwidth, xmin, xmax)) { + slit_error_if (xwidth != xmax - xmin, "specifying xwidth, xmin and xmax requires consistent parameters", NAME_CURRENT_COMP); + } else { + slit_error_if (is_unset (xwidth) && any_unset (2, xmin, xmax), "specify either xwidth or xmin & xmax", NAME_CURRENT_COMP); + } + if (all_set (3, yheight, ymin, ymax)) { + slit_error_if (yheight != ymax - ymin, "specifying yheight, ymin and ymax requires consistent parameters", NAME_CURRENT_COMP); + } else { + slit_error_if (is_unset (yheight) && any_unset (2, ymin, ymax), "specify either yheight or ymin & ymax", NAME_CURRENT_COMP); + } + if (is_unset (xmin)) { // xmax also unset but xwidth *is* set + xmax = xwidth / 2; + xmin = -xmax; + } + if (is_unset (ymin)) { // ymax also unset but yheight *is* set + ymax = yheight / 2; + ymin = -ymax; + } + slit_warning_if (xmin == xmax || ymin == ymax, "Running with CLOSED rectangular slit - is this intentional?", NAME_CURRENT_COMP); } else { - slit_error_if(is_unset(yheight) && any_unset(2, ymin, ymax), "specify either yheight or ymin & ymax", NAME_CURRENT_COMP); + isradial = 1; + slit_error_if (any_set (6, xwidth, xmin, xmax, yheight, ymin, ymax), "specify radius OR width and height parameters", NAME_CURRENT_COMP); + slit_warning_if (radius == 0., "Running with CLOSED radial slit - is this intentional?", NAME_CURRENT_COMP); } - if (is_unset(xmin)) { // xmax also unset but xwidth *is* set - xmax = xwidth/2; - xmin = -xmax; - } - if (is_unset(ymin)) { // ymax also unset but yheight *is* set - ymax = yheight/2; - ymin = -ymax; - } - slit_warning_if(xmin == xmax || ymin == ymax, "Running with CLOSED rectangular slit - is this intentional?", NAME_CURRENT_COMP); -} else { - isradial=1; - slit_error_if(any_set(6, xwidth, xmin, xmax, yheight, ymin, ymax), - "specify radius OR width and height parameters", NAME_CURRENT_COMP); - slit_warning_if(radius == 0., "Running with CLOSED radial slit - is this intentional?", NAME_CURRENT_COMP); -} - %} TRACE %{ - PROP_Z0; - if (!isradial ? (x < xmin || x > xmax || y < ymin || y > ymax) : (x * x + y * y > radius * radius)) - ABSORB; - else - SCATTER; + PROP_Z0; + if (!isradial ? (x < xmin || x > xmax || y < ymin || y > ymax) : (x * x + y * y > radius * radius)) + ABSORB; + else + SCATTER; %} MCDISPLAY %{ - - if (is_unset(radius)) { + + if (is_unset (radius)) { double xw, yh; - xw = (xmax - xmin)/2.0; - yh = (ymax - ymin)/2.0; - multiline(3, xmin-xw, (double)ymax, 0.0, - (double)xmin, (double)ymax, 0.0, - (double)xmin, ymax+yh, 0.0); - multiline(3, xmax+xw, (double)ymax, 0.0, - (double)xmax, (double)ymax, 0.0, - (double)xmax, ymax+yh, 0.0); - multiline(3, xmin-xw, (double)ymin, 0.0, - (double)xmin, (double)ymin, 0.0, - (double)xmin, ymin-yh, 0.0); - multiline(3, xmax+xw, (double)ymin, 0.0, - (double)xmax, (double)ymin, 0.0, - (double)xmax, ymin-yh, 0.0); + xw = (xmax - xmin) / 2.0; + yh = (ymax - ymin) / 2.0; + multiline (3, xmin - xw, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, ymax + yh, 0.0); + multiline (3, xmax + xw, (double)ymax, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmax, ymax + yh, 0.0); + multiline (3, xmin - xw, (double)ymin, 0.0, (double)xmin, (double)ymin, 0.0, (double)xmin, ymin - yh, 0.0); + multiline (3, xmax + xw, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, ymin - yh, 0.0); } else { - circle("xy",0,0,0,radius); + circle ("xy", 0, 0, 0, radius); } %} diff --git a/mcstas-comps/optics/V_selector.comp b/mcstas-comps/optics/V_selector.comp index 74f444aa66..a227938bbf 100644 --- a/mcstas-comps/optics/V_selector.comp +++ b/mcstas-comps/optics/V_selector.comp @@ -55,107 +55,94 @@ SETTING PARAMETERS (xwidth=0.03, yheight=0.05, zdepth=0.30, radius=0.12, alpha=4 DECLARE %{ -double omega; -double alpha_rad; + double omega; + double alpha_rad; %} INITIALIZE %{ -omega=nu*2*PI; -alpha_rad = alpha*DEG2RAD; -if (zdepth < length) zdepth=length; + omega = nu * 2 * PI; + alpha_rad = alpha * DEG2RAD; + if (zdepth < length) + zdepth = length; %} TRACE %{ - double dt0,dt1; - double r_i,r_f,r_mean; - double theta_i,theta_f; + double dt0, dt1; + double r_i, r_f, r_mean; + double theta_i, theta_f; double A; double d_s_alpha; if (vz == 0) ABSORB; - dt1= (-zdepth/2.0 - z)/vz; - PROP_DT(dt1); /* Propagate to the entry aperture */ - if (x<(-xwidth/2.0) || x>(xwidth/2.0) || y<(-yheight/2.0) || y>(yheight/2.0)) + dt1 = (-zdepth / 2.0 - z) / vz; + PROP_DT (dt1); /* Propagate to the entry aperture */ + if (x < (-xwidth / 2.0) || x > (xwidth / 2.0) || y < (-yheight / 2.0) || y > (yheight / 2.0)) ABSORB; - dt0 = (zdepth-length)/(2.0*vz); /* Propagate to the cylinder start */ - PROP_DT(dt0); - r_i = sqrt(x*x+(y+radius)*(y+radius)); - theta_i = atan2(x,y+radius); + dt0 = (zdepth - length) / (2.0 * vz); /* Propagate to the cylinder start */ + PROP_DT (dt0); + r_i = sqrt (x * x + (y + radius) * (y + radius)); + theta_i = atan2 (x, y + radius); - dt1 = length/vz; /* Propagate along the cylinder length */ - PROP_DT(dt1); - r_f = sqrt(x*x+(y+radius)*(y+radius)); - theta_f = atan2(x,y+radius); + dt1 = length / vz; /* Propagate along the cylinder length */ + PROP_DT (dt1); + r_f = sqrt (x * x + (y + radius) * (y + radius)); + theta_f = atan2 (x, y + radius); - dt0 = (zdepth-length)/(2.0*vz); /* Propagate to the exit aperture */ - PROP_DT(dt0); - if (x<(-xwidth/2.0) || x>(xwidth/2.0) || y<(-yheight/2.0) || y>(yheight/2.0)) + dt0 = (zdepth - length) / (2.0 * vz); /* Propagate to the exit aperture */ + PROP_DT (dt0); + if (x < (-xwidth / 2.0) || x > (xwidth / 2.0) || y < (-yheight / 2.0) || y > (yheight / 2.0)) ABSORB; /* Calculate analytical transmission assuming continuous source */ - r_mean = (r_i + r_f)/2.0; /* Approximation using mean radius */ - d_s_alpha = theta_f-theta_i; - A = nslit/(2*PI)*( d/r_mean + fabs(alpha_rad+d_s_alpha-omega*length/vz) ); + r_mean = (r_i + r_f) / 2.0; /* Approximation using mean radius */ + d_s_alpha = theta_f - theta_i; + A = nslit / (2 * PI) * (d / r_mean + fabs (alpha_rad + d_s_alpha - omega * length / vz)); if (A >= 1) ABSORB; - p*= (1-A); + p *= (1 - A); SCATTER; %} MCDISPLAY %{ double r = radius + yheight; - double x0 = -xwidth/2.0; - double x1 = xwidth/2.0; - double y0 = -yheight/2.0; - double y1 = yheight/2.0; - double z0 = -zdepth/2.0; - double z1 = -length/2.0; - double z2 = length/2.0; - double z3 = zdepth/2.0; + double x0 = -xwidth / 2.0; + double x1 = xwidth / 2.0; + double y0 = -yheight / 2.0; + double y1 = yheight / 2.0; + double z0 = -zdepth / 2.0; + double z1 = -length / 2.0; + double z2 = length / 2.0; + double z3 = zdepth / 2.0; double a; double xw, yh; - - xw = xwidth/2.0; - yh = yheight/2.0; + xw = xwidth / 2.0; + yh = yheight / 2.0; /* Draw apertures */ - for(a = z0;;) - { - multiline(3, x0-xw, (double)y1, a, - (double)x0, (double)y1, a, - (double)x0, y1+yh, a); - multiline(3, x1+xw, (double)y1, a, - (double)x1, (double)y1, a, - (double)x1, y1+yh, a); - multiline(3, x0-xw, (double)y0, a, - (double)x0, (double)y0, a, - (double)x0, y0-yh, a); - multiline(3, x1+xw, (double)y0, a, - (double)x1, (double)y0, a, - (double)x1, y0-yh, a); - if(a == z3) + for (a = z0;;) { + multiline (3, x0 - xw, (double)y1, a, (double)x0, (double)y1, a, (double)x0, y1 + yh, a); + multiline (3, x1 + xw, (double)y1, a, (double)x1, (double)y1, a, (double)x1, y1 + yh, a); + multiline (3, x0 - xw, (double)y0, a, (double)x0, (double)y0, a, (double)x0, y0 - yh, a); + multiline (3, x1 + xw, (double)y0, a, (double)x1, (double)y0, a, (double)x1, y0 - yh, a); + if (a == z3) break; else a = z3; } /* Draw cylinder. */ - circle("xy", 0, -radius, z1, r); - circle("xy", 0, -radius, z2, r); - line(0, -radius, z1, 0, -radius, z2); - for(a = 0; a < 2*PI; a += PI/8) - { - multiline(4, - 0.0, -radius, z1, - r*cos(a), r*sin(a) - radius, z1, - r*cos(a + DEG2RAD*alpha), r*sin(a + DEG2RAD*alpha) - radius, z2, - 0.0, -radius, z2); + circle ("xy", 0, -radius, z1, r); + circle ("xy", 0, -radius, z2, r); + line (0, -radius, z1, 0, -radius, z2); + for (a = 0; a < 2 * PI; a += PI / 8) { + multiline (4, 0.0, -radius, z1, r * cos (a), r * sin (a) - radius, z1, r * cos (a + DEG2RAD * alpha), r * sin (a + DEG2RAD * alpha) - radius, z2, 0.0, + -radius, z2); } %} diff --git a/mcstas-comps/optics/Vitess_ChopperFermi.comp b/mcstas-comps/optics/Vitess_ChopperFermi.comp index fbaee04bae..84388f9800 100644 --- a/mcstas-comps/optics/Vitess_ChopperFermi.comp +++ b/mcstas-comps/optics/Vitess_ChopperFermi.comp @@ -138,109 +138,105 @@ DECLARE double omega; /* rotation frequency */ double optimal_wl; /* optimal wavelength */ VectorType pos_ch; /* centre pos. of the FC in the frame of the exit of the prev. comp. [cm] */ - %} INITIALIZE %{ -omega = 0.0; -optimal_wl = 0.0; + omega = 0.0; + optimal_wl = 0.0; -double x,y,z; -coords_get(POS_R_COMP_INDEX(INDEX_CURRENT_COMP), &x, &y, &z); + 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(); + McInitVt (); /* transformation of units */ - height *= 100.0; /* m -> cm */ - width *= 100.0; - depth *= 100.0; - diameter *= 100.0; - r_curv *= 100.0; + 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; + 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); + 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"); + 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); + 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); + 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(); + ChopperFermiCleanup (); + McCleanupVt (); %} MCDISPLAY %{ - double index=0; + double index = 0; double xpos, zpos, ymin, ymax, rad, w_ch; Nchannels = (Nchannels > 11 ? 11 : Nchannels); - w_ch = (width - (Nchannels+1) * wallwidth) / Nchannels/100; - rad = diameter/2.0/100; - ymin = -height/2.0/100; - ymax = height/2.0/100; - + w_ch = (width - (Nchannels + 1) * wallwidth) / Nchannels / 100; + rad = diameter / 2.0 / 100; + ymin = -height / 2.0 / 100; + ymax = height / 2.0 / 100; + /* cylinder top/center/bottom */ - circle("xz", 0,ymax,0,rad); - circle("xz", 0,0 ,0,rad); - circle("xz", 0,ymin,0,rad); + 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 ); + 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/100; - 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); + index = -Nchannels / 2; + zpos = depth / 2 / 100; + 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 = 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); + multiline (5, xpos, ymin, -zpos, xpos, ymax, -zpos, xpos, ymax, +zpos, xpos, ymin, +zpos, xpos, ymin, -zpos); %} END