File: Mirror_curved.comp

package info (click to toggle)
mccode 3.5.19%2Bds5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,113,256 kB
  • sloc: ansic: 40,697; python: 25,137; yacc: 8,438; sh: 5,405; javascript: 4,596; lex: 1,632; cpp: 742; perl: 296; lisp: 273; makefile: 226; fortran: 132
file content (159 lines) | stat: -rw-r--r-- 4,103 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/************************************************
* McXtrace, x-ray tracing package
*         Copyright, All rights reserved
*         DTU Physics, Kgs. Lyngby, Denmark
*         Synchrotron SOLEIL, Saint-Aubin, France
*
* %Identification
* Written by: Erik Knudsen
* Date: September 25th, 2009
* Origin: Risoe
*
* A cylindrically curved mirror (in YZ)
*
* %Description
* mirror is in the YZ-plane curved towards positive X if radius is positive
*
* Example: Mirror_curved( radius=2, length=20e-3, width=40e-3, coating="AlMgF2_disco.dat")
* 
* %Parameters
* radius: [m]   Radius of curvature, along Z.
* yheight:[m]   Width of the mirror along Y.
* zdepth: [m]   Length of the unbent mirror along Z.
* coating:[str] Name of file containing the material data (i.e. f1 and f2) for the coating
* R0:     [1]   Constant reflectivity value (mostly relevant for debugging, when coating="").
* width:  [m]   Width of the mirror along Y = yheight
* length: [m]   Length of the unbent mirror along Z = zdepth
*
* %End
***********************************************************************/

DEFINE COMPONENT Mirror_curved

SETTING PARAMETERS (radius=1, R0=1, string coating="Be.txt",
  zdepth=0.2, yheight=0.2, 
  length=0, width=0)

/* X-ray parameters: (x,y,z,kx,ky,kz,phi,t,Ex,Ey,Ez,p) */ 

SHARE
%{
#include <complex.h>
  %include "read_table-lib"
  %include "reflectivity-lib"
%}

DECLARE
%{
  int Z;
  double At;
  double rho;
  t_Table T;
  t_Reflec re;
%}

INITIALIZE
%{
  int status;

  if (coating && strlen(coating)) {
    status=reflec_Init(&re,COATING_UNDEFINED,coating,NULL);
  }else{
    /*assume a constant reflectivity*/
    status=reflec_Init(&re,CONSTANT,NULL, &(R0));
  }
  if (!radius) radius=1e6;
  // compatibility with older use
  if (length) zdepth =length;
  if (width)  yheight=width;
%}

TRACE
%{
  double l0,l1,dl,alpha,n,nx,nz,s,k,knx,knz;

  /*do we hit the mirror within range?*/
  //PROP_Z0;
  k=sqrt(scalar_prod(kx,0,kz,kx,0,kz));
  knx=kx/k;
  knz=kz/k;
  if (solve_2nd_order(&l0,&l1, knx*knx+knz*knz,2*(x*knx+z*knz-radius*knx),x*x-2*x*radius+z*z))
  {
    if (l0<0 && l1>0){
      dl=l1;
    }else if(l1<0 && l0>0){
      dl=l0;
    }else if( l0>0 && l1>0){
      if (fabs(z+knz*l0) <zdepth/2.0  && fabs(x+knx*l0)<fabs(radius)) {
      /*this means that the first positive match is on the mirror z-wise
        - this should be picked. This would work even if mirror is hit from behind*/
        dl=l0;
      }else{
        dl=l1;
      }
    }else{
        /*particle misses the mirror completely (l0<0 and l1<0)*/
        RESTORE_XRAY(INDEX_CURRENT_COMP, x, y, z, kx, ky, kz, phi, t, Ex, Ey, Ez, p);
    }

    /*correction for only solving in xz-plane*/
    dl*=sqrt(scalar_prod(kx,ky,kz,kx,ky,kz)/scalar_prod(kx,0,kz,kx,0,kz));

    PROP_DL(dl);
    alpha=asin(z/radius);
    if ( (zdepth<radius*alpha) || (fabs(y)>yheight/2.0)) {
      RESTORE_XRAY(INDEX_CURRENT_COMP, x, y, z, kx, ky, kz, phi, t, Ex, Ey, Ez, p);
    }else{
      SCATTER;
      /*reflection*/
      nx=radius-x;
      nz=-z;
      n=sqrt(nx*nx+nz*nz);
      nx/=n;
      nz/=n;
      
      s=scalar_prod(kx,0,kz,nx,0,nz);
      kx=kx-2*s*nx;
      kz=kz-2*s*nz;
      
      double Q;
      /*length of wavevector transfer may be compute from s and n_ above*/
      Q=fabs(2*s*sqrt(nx*nx+nz*nz));
      double complex R=refleccq(re,Q,0,k,fabs(90-acos(s/k)*RAD2DEG));
      p*=sqrt(creal(R*conj(R)));
      phi+=atan2(cimag(R),creal(R));
    }
  }else if(fabs(kx)<DBL_EPSILON && fabs(kz)<DBL_EPSILON && ky!=0){
    /*This to catch the extreme case where k//y.*/
    if (y==0){
      /*We hit the "side" of the mirror.*/
      ABSORB;
    }
  }

%}

MCDISPLAY
%{
  double x0,y0,z0,x1,y1,z1,alpha;
  int N=20;

  y0=yheight/2.0;
  y1=-y0;

  alpha=-(zdepth/2.0)/fabs(radius);
  x0=radius*(1-cos(alpha));
  z0=radius*sin(alpha);
  line(x0,y0,z0,x0,y1,z0);
  while (alpha<(zdepth/2.0/fabs(radius))){
    alpha+=zdepth/N/fabs(radius);
    x1=radius*(1-cos(alpha));
    z1=radius*sin(alpha);
    line(x0,y0,z0,x1,y0,z1);
    line(x0,y1,z0,x1,y1,z1);
    x0=x1;z0=z1;
    line(x0,y0,z0,x0,y1,z0);
  }
%}

END