/******************************************************************************* * * McStas, neutron ray-tracing package * Copyright(C) 2000 Risoe National Laboratory. * * %I * Written by: Kim Lefmann * Date: 04.02.04 * Version: $Revision: 1.4 $ * Origin: Risoe * * A sample for phonon scattering * based on cross section expressions from Squires, Ch.3. * * %D * Single-cylinder shape. * Absorption included. * No multiple scattering. * No incoherent scattering emitted. * No attenuation from coherent scattering. No Bragg scattering. * fcc crystal n.n. interactions only * One phonon branch only -> phonon polarization not accounted for. * Bravais lattice only. (i.e. just one atom per unit cell) * * Algorithm: * 0. Always perform the scattering if possible (otherwise ABSORB) * 1. Choose direction within a focusing solid angle * 2. Calculate the zeros of (E_i-E_f-hbar omega(kappa)) as a function of k_f * 3. Choose one value of k_f (always at least one is possible!) * 4. Perform the correct weight transformation * * %P * INPUT PARAMETERS: * * radius_o:[m] Outer radius of sample in (x,z) plane * h: [m] Height of sample in y direction * focus_r: [m] Radius of sphere containing target. * focus_xw:[m] horiz. dimension of a rectangular area * focus_yh:[m] vert. dimension of a rectangular area [m] * focus_aw:[m] horiz. angular dimension of a rectangular area [deg] * focus_ah:[m] vert. angular dimension of a rectangular area [deg] * target_x:[m] position of target to focus at . Transverse coordinate * target_y:[m] position of target to focus at [m]. Vertical coordinate * target_z:[m] position of target to focus at [m]. Straight ahead. * sigma_a:[barns] Absorption cross section at 2200 m/s per atom * sigma_i:[barns] Incoherent scattering cross section per atom * a: [AA] Lattice constant (fcc) * b: [fm] Scattering length * M: [a.u.] Atomic mass * c:[meV/AA^(-1)] Velocity of sound * DW: [1] Debye-Waller factor * T: [K] Temperature * * *OUTPUT PARAMETERS: * * V_rho: [AA^-3] Atomic density * V_my_s: [m^-1] Attenuation factor due to incoherent scattering * V_my_a: [m^-1] Attenuation factor due to absorbtion * * %E ******************************************************************************/ DEFINE COMPONENT Phonon_simple DEFINITION PARAMETERS () SETTING PARAMETERS (radius_o,h,focus_r=0,focus_xw=0,focus_yh=0,focus_aw=0,focus_ah=0,sigma_a,sigma_i,a,b,M,c,DW,T,target_x=0, target_y=0, target_z=0, int target_index=0) OUTPUT PARAMETERS (V_rho, V_my_s, V_my_a) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) #define T2E (1/11.605) /* Kelvin to meV */ double parms[8]; double nbose(double omega, double T) /* Other name ?? */ { double nb; nb= (omega>0) ? 1+1/(exp(omega/(T*T2E))-1) : 1/(exp(-omega/(T*T2E))-1); return nb; } #undef T2E /* Routine types from Numerical Recipies book */ #define UNUSED (-1.11e30) #define MAXRIDD 60 void fatalerror(char *s) { fprintf(stderr,"%s \n",s); exit(1); } double zridd(double (*func)(int,double*), double x1, double x2, int Nparms, double *parms, double xacc) { int j; double ans, fh, fl, fm, fnew, s, xh, xl, xm, xnew; /* printf("zridd called with brackets %g %g acceptance %g \n",x1,x2,xacc); printf("and %i parameters %g %g %g %g %g \n",Nparms,parms[0],parms[1],parms[2],parms[3], parms[4]); */ parms[0]=x1; fl=(*func)(Nparms,parms); parms[0]=x2; fh=(*func)(Nparms,parms); /* printf("Function values: %g %g \n",fl,fh); */ if (fl*fh >= 0) { if (fl==0) return x1; if (fh==0) return x2; return UNUSED; } else { xl=x1; xh=x2; ans=UNUSED; for (j=1; j= fh ? 1.0 : -1.0)*fm/s); if (fabs(xnew-ans) <= xacc) return ans; ans=xnew; parms[0]=ans; fnew=(*func)(Nparms,parms); if (fnew == 0.0) return ans; if (SIGN(fm,fnew) != fm) { xl=xm; fl=fm; xh=ans; fh=fnew; } else if (SIGN(fl,fnew) != fl) { xh=ans; fh=fnew; } else if(SIGN(fh,fnew) != fh) { xl=ans; fl=fnew; } else fatalerror("never get here in zridd"); if (fabs(xh-xl) <= xacc) return ans; } fatalerror("zridd exceeded maximum iterations"); } return 0.0; /* Never get here */ } #define ROOTACC 1e-8 int findroots(double brack_low, double brack_mid, double brack_high, double *list, int* index, double (*f)(int, double*) ) { double root,range=brack_mid-brack_low; int i, steps=100; for (i=0; i