1 | /* ------------------------------------------------------------------------- |
---|
2 | * trace_optF1v4.c |
---|
3 | * |
---|
4 | * --- main program of raytracing in the Fresnel lens system |
---|
5 | * |
---|
6 | * Copyright (c) 2000-2007 N.Sakaki, Y.Takizawa, Y.Kawasaki |
---|
7 | * All rights reserved |
---|
8 | * $Id$ |
---|
9 | * ------------------------------------------------------------------------- |
---|
10 | */ |
---|
11 | #include <stdio.h> |
---|
12 | #include <stdlib.h> |
---|
13 | #include <string.h> |
---|
14 | #include <math.h> |
---|
15 | #include "EConst.hh" |
---|
16 | #include "EsafRandom.hh" |
---|
17 | #include "Mspline.hh" |
---|
18 | #include "Mutils.hh" |
---|
19 | #include "Mtrace_optF1v4.hh" |
---|
20 | |
---|
21 | #define RT_SEARCH_ITER_MAX 100 |
---|
22 | #define RT_INTERACTION_MAX 20 |
---|
23 | #define S_DATA 135000 |
---|
24 | |
---|
25 | /* alias */ |
---|
26 | #define X 0 |
---|
27 | #define Y 1 |
---|
28 | #define Z 2 |
---|
29 | #define PX 3 |
---|
30 | #define PY 4 |
---|
31 | #define PZ 5 |
---|
32 | #define L 6 |
---|
33 | #define T 7 |
---|
34 | |
---|
35 | /* lens surface data */ |
---|
36 | static int n_s1=0,n_s2=0,n_s4=0,n_s6=0,n_s7=0; |
---|
37 | static double sr1[S_DATA],sz1[S_DATA]; |
---|
38 | static double sr2[S_DATA],sz2[S_DATA]; |
---|
39 | static double sr4[S_DATA],sz4[S_DATA]; |
---|
40 | static double sr6[S_DATA],sz6[S_DATA]; |
---|
41 | static double sr7[S_DATA],sz7[S_DATA]; |
---|
42 | |
---|
43 | /* lens material data */ |
---|
44 | static int n_acryl=0, n_cytop=0, n_bg3=0; |
---|
45 | static double ac_la[Acryl_N],ac_n[Acryl_N],ac_k[Acryl_N]; |
---|
46 | static double cy_la[Acryl_N],cy_n[Acryl_N],cy_k[Acryl_N]; |
---|
47 | static double bg3_la[Bg3_N],bg3_n[Bg3_N],bg3_k[Bg3_N]; |
---|
48 | |
---|
49 | /* diffractive structure data */ |
---|
50 | static int n_sd1=0; |
---|
51 | #define N_DIFFR_DATA 130000 |
---|
52 | static double SD1_R[N_DIFFR_DATA]; |
---|
53 | static double SD1_D[N_DIFFR_DATA]; |
---|
54 | |
---|
55 | static double ref(double n1, double n2, double ci, double ct); |
---|
56 | static int check_intersect_cylinder(double r1, double z1, double r2, double z2, |
---|
57 | double phot[8], double *dis); |
---|
58 | static int check_intersect_cone (double r1, double z1, double r2, double z2, |
---|
59 | double phot[8], double *dis); |
---|
60 | static int CheckIris(Mtel_param *p, double phot[6], int flag); |
---|
61 | |
---|
62 | /* |
---|
63 | * ======================================================================== |
---|
64 | * functions for diffractive optics start |
---|
65 | * ======================================================================== |
---|
66 | */ |
---|
67 | /* |
---|
68 | * ------------------------------------------------------------------------ |
---|
69 | * Calculate normal vector to the sphere approximating the lens surface |
---|
70 | * Input: |
---|
71 | * aX, aY, aZ: photon position on the lens surface |
---|
72 | * aCZ : center of the approximated sphere |
---|
73 | * |
---|
74 | * Output: |
---|
75 | * nnnDIFF[3]: normal unit vector |
---|
76 | * ------------------------------------------------------------------------ |
---|
77 | */ |
---|
78 | int CalSpheVec(double aX, double aY, double aZ, double aCZ, double nnnDIFF[3]) |
---|
79 | { |
---|
80 | |
---|
81 | double N_; |
---|
82 | |
---|
83 | nnnDIFF[0] = aX; |
---|
84 | nnnDIFF[1] = aY; |
---|
85 | nnnDIFF[2] = aZ - aCZ; |
---|
86 | |
---|
87 | N_ = sqrt(Mvdot(nnnDIFF,nnnDIFF)); |
---|
88 | |
---|
89 | nnnDIFF[0] = nnnDIFF[0]/N_; |
---|
90 | nnnDIFF[1] = nnnDIFF[1]/N_; |
---|
91 | nnnDIFF[2] = nnnDIFF[2]/N_; |
---|
92 | |
---|
93 | return 0; |
---|
94 | } |
---|
95 | |
---|
96 | |
---|
97 | /* |
---|
98 | * ------------------------------------------------------------------------ |
---|
99 | * read parameters of diffractive optics |
---|
100 | * Input: |
---|
101 | * dirname the name of the directory name |
---|
102 | * where data files are stored |
---|
103 | * Output: |
---|
104 | * (return value) status |
---|
105 | * ------------------------------------------------------------------------ |
---|
106 | */ |
---|
107 | int ReadDiffractData(char *dirname, FILE *fplog) |
---|
108 | { |
---|
109 | FILE *fr; |
---|
110 | char Infname[128]; |
---|
111 | |
---|
112 | #ifdef DEBUG |
---|
113 | if(fplog) |
---|
114 | fprintf(fplog,"Reading Diffractive Surface Data.... "); |
---|
115 | #endif |
---|
116 | |
---|
117 | /* read diffractive optics data */ |
---|
118 | sprintf(Infname,"%.100s/DOE_F1v6.dat",dirname); |
---|
119 | |
---|
120 | if(( fr = fopen(Infname,"r" )) == NULL) |
---|
121 | { |
---|
122 | if(fplog) |
---|
123 | fprintf(fplog,"%s not OPEN\n",Infname ); |
---|
124 | return (-1); |
---|
125 | } |
---|
126 | while(n_sd1<N_DIFFR_DATA |
---|
127 | && fscanf(fr,"%lf %lf",&SD1_R[n_sd1],&SD1_D[n_sd1])==2) |
---|
128 | n_sd1++; |
---|
129 | fclose(fr); |
---|
130 | if(n_sd1==N_DIFFR_DATA) |
---|
131 | return (-2); |
---|
132 | |
---|
133 | #ifdef DEBUG |
---|
134 | if(fplog) |
---|
135 | fprintf(fplog,"Done.\n"); |
---|
136 | #endif |
---|
137 | |
---|
138 | return (0); |
---|
139 | } |
---|
140 | |
---|
141 | /* |
---|
142 | * ------------------------------------------------------------------------ |
---|
143 | * calculate the diffractive structure |
---|
144 | * Input: |
---|
145 | * r the distance in mm to the optical axis at the intersection point |
---|
146 | * s surface ID (i.e. S1,S2,...) |
---|
147 | * Output: |
---|
148 | * (return value) |
---|
149 | * ------------------------------------------------------------------------ |
---|
150 | */ |
---|
151 | double MCal_D(double r) |
---|
152 | { |
---|
153 | int i; |
---|
154 | |
---|
155 | i=Mrt_bsearch(SD1_R,r,0,n_sd1-1); |
---|
156 | return (SD1_D[i]); |
---|
157 | } |
---|
158 | |
---|
159 | /* |
---|
160 | * ------------------------------------------------------------------------ |
---|
161 | * calculate the diffracted ray |
---|
162 | * Input: |
---|
163 | * in_ph[3] array x,y,z of photon |
---|
164 | * nnn[3] normal vector to the diffractive surface |
---|
165 | * at the intersection |
---|
166 | * n1 refractive index of xxx |
---|
167 | * n2 refractive index of xxx |
---|
168 | * d |
---|
169 | * wl wavelength in mm |
---|
170 | * m index |
---|
171 | * Output: |
---|
172 | * in_ph[3] |
---|
173 | * ------------------------------------------------------------------------ |
---|
174 | */ |
---|
175 | int diffract(int ID, double in_phdir[3], |
---|
176 | double x3, double y3, double z3, double Zc, |
---|
177 | double n1, double n2, double wl, double wl0, int m) |
---|
178 | { |
---|
179 | int i; |
---|
180 | double CosIN, dir, nnnR[3], r3, ppp[3], nnn[3], d, norm; |
---|
181 | |
---|
182 | r3=sqrt(x3*x3+y3*y3); |
---|
183 | nnnR[0]= x3/r3; |
---|
184 | nnnR[1]= y3/r3; |
---|
185 | nnnR[2]=0.0; |
---|
186 | |
---|
187 | nnn[0]= 0.0; |
---|
188 | nnn[1]= 0.0; |
---|
189 | nnn[2]= 1.0; |
---|
190 | |
---|
191 | d=MCal_D(r3); |
---|
192 | |
---|
193 | if(in_phdir[Z]>0.) |
---|
194 | dir=1.0; |
---|
195 | else |
---|
196 | dir=-1.0; |
---|
197 | |
---|
198 | CosIN=in_phdir[Z]; |
---|
199 | |
---|
200 | for(i=0;i<3;i++) |
---|
201 | ppp[i]=(n1*(in_phdir[i]-CosIN*nnn[i]) |
---|
202 | +(double)m*wl/wl0*d*nnnR[i]*dir)/n2; |
---|
203 | |
---|
204 | norm=Mvdot(ppp,ppp); |
---|
205 | if(norm>1.0) |
---|
206 | return -1; |
---|
207 | |
---|
208 | norm=sqrt(1.0-norm); |
---|
209 | |
---|
210 | #ifdef DEBUG |
---|
211 | fprintf(stderr,"Diffractive: (%.3f , %.3f , %.3f)=>", |
---|
212 | in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
213 | #endif |
---|
214 | |
---|
215 | for(i=0;i<3;i++) |
---|
216 | in_phdir[i]=ppp[i]+norm*nnn[i]*(CosIN>0.0?(1.0):(-1.0)); |
---|
217 | |
---|
218 | #ifdef DEBUG |
---|
219 | fprintf(stderr,"(%.3f , %.3f , %.3f)\n",in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
220 | #endif |
---|
221 | |
---|
222 | return (0); |
---|
223 | } |
---|
224 | |
---|
225 | /* |
---|
226 | * ======================================================================== |
---|
227 | * functions for diffractive optics END |
---|
228 | * ======================================================================== |
---|
229 | */ |
---|
230 | |
---|
231 | /* |
---|
232 | * ------------------------------------------------------------------------ |
---|
233 | * calculate reflection probability assuming no polariation |
---|
234 | * n1,n2: refractive index of the media of this side and the other side |
---|
235 | * ci,ct: cosine of the incident light and reflected light to the surface |
---|
236 | * normal vector |
---|
237 | * ------------------------------------------------------------------------ |
---|
238 | */ |
---|
239 | static double ref(double n1, double n2, double ci, double ct) |
---|
240 | { |
---|
241 | double rp,rs; |
---|
242 | |
---|
243 | rp=(n2*ci-n1*ct)/(n2*ci+n1*ct); |
---|
244 | rs=(n1*ci-n2*ct)/(n1*ci+n2*ct); |
---|
245 | |
---|
246 | return((rp*rp+rs*rs)/2.0); |
---|
247 | } |
---|
248 | |
---|
249 | /* |
---|
250 | * ------------------------------------------------------------------------ |
---|
251 | * read lens surface shapes, and optical indices |
---|
252 | * ------------------------------------------------------------------------ |
---|
253 | */ |
---|
254 | int ReadLensData(Mtel_param *param, FILE *fplog) |
---|
255 | { |
---|
256 | FILE *fp; |
---|
257 | char filename[128]; |
---|
258 | |
---|
259 | #ifdef DEBUG |
---|
260 | if(fplog) |
---|
261 | fprintf(fplog,"Reading Surface Data.... "); |
---|
262 | #endif |
---|
263 | |
---|
264 | /* Read S1 surface */ |
---|
265 | sprintf(filename,"%.100s/S1_F1v6.dat",param->Mlens_dir); |
---|
266 | if((fp=fopen(filename,"r"))==NULL) |
---|
267 | { |
---|
268 | if(fplog) |
---|
269 | fprintf(fplog,"%s not found.\n",filename); |
---|
270 | return -1; |
---|
271 | } |
---|
272 | while(n_s1<S_DATA && |
---|
273 | fscanf(fp,"%lf %lf",&sr1[n_s1], &sz1[n_s1])!=EOF) |
---|
274 | { |
---|
275 | sz1[n_s1]=param->MSz1-sz1[n_s1]; |
---|
276 | n_s1++; |
---|
277 | } |
---|
278 | fclose(fp); |
---|
279 | |
---|
280 | /* Read S2 surface */ |
---|
281 | sprintf(filename,"%.100s/S2_F1v6.dat",param->Mlens_dir); |
---|
282 | if((fp=fopen(filename,"r"))==NULL) |
---|
283 | { |
---|
284 | if(fplog) |
---|
285 | fprintf(fplog,"%s not found.\n",filename); |
---|
286 | return -2; |
---|
287 | } |
---|
288 | while(n_s2<S_DATA && |
---|
289 | fscanf(fp,"%lf %lf",&sr2[n_s2], &sz2[n_s2])!=EOF) |
---|
290 | { |
---|
291 | sz2[n_s2]=param->MSz2-sz2[n_s2]; |
---|
292 | n_s2++; |
---|
293 | } |
---|
294 | fclose(fp); |
---|
295 | |
---|
296 | /* Read S4 surface */ |
---|
297 | sprintf(filename,"%.100s/S4_F1v6.dat",param->Mlens_dir); |
---|
298 | if((fp=fopen(filename,"r"))==NULL) |
---|
299 | { |
---|
300 | if(fplog) |
---|
301 | fprintf(fplog,"%s not found.\n",filename); |
---|
302 | return -4; |
---|
303 | } |
---|
304 | while(n_s4<S_DATA && |
---|
305 | fscanf(fp,"%lf %lf",&sr4[n_s4], &sz4[n_s4])!=EOF) |
---|
306 | { |
---|
307 | sz4[n_s4]=param->MSz4-sz4[n_s4]; |
---|
308 | n_s4++; |
---|
309 | } |
---|
310 | fclose(fp); |
---|
311 | |
---|
312 | /* Read S6 surface */ |
---|
313 | sprintf(filename,"%.100s/S6_F1v6.dat",param->Mlens_dir); |
---|
314 | if((fp=fopen(filename,"r"))==NULL) |
---|
315 | { |
---|
316 | if(fplog) |
---|
317 | fprintf(fplog,"%s not found.\n",filename); |
---|
318 | return -6; |
---|
319 | } |
---|
320 | while(n_s6<S_DATA && |
---|
321 | fscanf(fp,"%lf %lf",&sr6[n_s6], &sz6[n_s6])!=EOF) |
---|
322 | { |
---|
323 | sz6[n_s6]=param->MSz6-sz6[n_s6]; |
---|
324 | n_s6++; |
---|
325 | } |
---|
326 | fclose(fp); |
---|
327 | |
---|
328 | /* Read S7 surface */ |
---|
329 | sprintf(filename,"%.100s/S7_F1v6.dat",param->Mlens_dir); |
---|
330 | if((fp=fopen(filename,"r"))==NULL) |
---|
331 | { |
---|
332 | if(fplog) |
---|
333 | fprintf(fplog,"%s not found.\n",filename); |
---|
334 | return -7; |
---|
335 | } |
---|
336 | while(n_s7<S_DATA && |
---|
337 | fscanf(fp,"%lf %lf",&sr7[n_s7], &sz7[n_s7])!=EOF) |
---|
338 | { |
---|
339 | sz7[n_s7]=param->MSz7-sz7[n_s7]; |
---|
340 | n_s7++; |
---|
341 | } |
---|
342 | fclose(fp); |
---|
343 | |
---|
344 | #ifdef DEBUG |
---|
345 | if(fplog) |
---|
346 | { |
---|
347 | fprintf(fplog,"Done.\n"); |
---|
348 | |
---|
349 | fprintf(fplog,"Reading Optical Data.... "); |
---|
350 | } |
---|
351 | #endif |
---|
352 | |
---|
353 | /* Read PMMA data */ |
---|
354 | sprintf(filename,"%.100s/Mitsubishi_000.dat",param->Mlens_dir); |
---|
355 | if((fp=fopen(filename,"r"))==NULL) |
---|
356 | return -10; |
---|
357 | while(n_acryl<Acryl_N && |
---|
358 | fscanf(fp,"%lf %lf %lf",&ac_la[n_acryl], |
---|
359 | &ac_n[n_acryl], &ac_k[n_acryl])!=EOF) |
---|
360 | { |
---|
361 | n_acryl++; |
---|
362 | } |
---|
363 | fclose(fp); |
---|
364 | |
---|
365 | /* Read CYOP data */ |
---|
366 | sprintf(filename,"%.100s/CYTOP.dat",param->Mlens_dir); |
---|
367 | if((fp=fopen(filename,"r"))==NULL) |
---|
368 | return -10; |
---|
369 | while(n_cytop<Cytop_N && |
---|
370 | fscanf(fp,"%lf %lf %lf",&cy_la[n_cytop], |
---|
371 | &cy_n[n_cytop], &cy_k[n_cytop])!=EOF) |
---|
372 | { |
---|
373 | n_cytop++; |
---|
374 | } |
---|
375 | fclose(fp); |
---|
376 | |
---|
377 | /* Read BG3 data */ |
---|
378 | sprintf(filename,"%.100s/bg3.dat",param->Mlens_dir); |
---|
379 | if((fp=fopen(filename,"r"))==NULL) |
---|
380 | return -11; |
---|
381 | while(n_bg3<Bg3_N && |
---|
382 | fscanf(fp,"%lf %lf %lf",&bg3_la[n_bg3], |
---|
383 | &bg3_n[n_bg3], &bg3_k[n_bg3])!=EOF) |
---|
384 | { |
---|
385 | n_bg3++; |
---|
386 | } |
---|
387 | fclose(fp); |
---|
388 | |
---|
389 | #ifdef DEBUG |
---|
390 | if(fplog) |
---|
391 | fprintf(fplog,"Done.\n"); |
---|
392 | #endif |
---|
393 | return 0; |
---|
394 | } |
---|
395 | |
---|
396 | /* |
---|
397 | * ------------------------------------------------------------------------ |
---|
398 | * get refractive index of the acryl at wavelength lambda |
---|
399 | * using cubic spline interpolation |
---|
400 | * ------------------------------------------------------------------------ |
---|
401 | */ |
---|
402 | double Get_n_Acryl(double lambda) |
---|
403 | { |
---|
404 | static int init=0; |
---|
405 | static double *z; |
---|
406 | |
---|
407 | if(!init) |
---|
408 | { |
---|
409 | init=1; |
---|
410 | if((z=(double *)malloc(sizeof(double)*n_acryl))==NULL) |
---|
411 | return -1000.0; |
---|
412 | Mcsp_maketable(ac_la, ac_n, z, n_acryl); |
---|
413 | } |
---|
414 | |
---|
415 | return Mcspline(lambda, ac_la, ac_n, z, n_acryl); |
---|
416 | } |
---|
417 | |
---|
418 | /* |
---|
419 | * ------------------------------------------------------------------------ |
---|
420 | * get extinction coefficient of the acryl at wavelength lambda |
---|
421 | * using cubic spline interpolation |
---|
422 | * ------------------------------------------------------------------------ |
---|
423 | */ |
---|
424 | double Get_k_Acryl(double lambda) |
---|
425 | { |
---|
426 | static int init=0; |
---|
427 | static double *z; |
---|
428 | |
---|
429 | if(!init) |
---|
430 | { |
---|
431 | init=1; |
---|
432 | if((z=(double *)malloc(sizeof(double)*n_acryl))==NULL) |
---|
433 | return -1000.0; |
---|
434 | Mcsp_maketable(ac_la, ac_k, z, n_acryl); |
---|
435 | } |
---|
436 | |
---|
437 | return Mcspline(lambda, ac_la, ac_k, z, n_acryl); |
---|
438 | } |
---|
439 | |
---|
440 | /* |
---|
441 | * ------------------------------------------------------------------------ |
---|
442 | * get refractive index of CYTOP at wavelength lambda |
---|
443 | * using cubic spline interpolation |
---|
444 | * ------------------------------------------------------------------------ |
---|
445 | */ |
---|
446 | double Get_n_Cytop(double lambda) |
---|
447 | { |
---|
448 | static int init=0; |
---|
449 | static double *z; |
---|
450 | |
---|
451 | if(!init) |
---|
452 | { |
---|
453 | init=1; |
---|
454 | if((z=(double *)malloc(sizeof(double)*n_cytop))==NULL) |
---|
455 | return -1000.0; |
---|
456 | Mcsp_maketable(cy_la, cy_n, z, n_cytop); |
---|
457 | } |
---|
458 | |
---|
459 | return Mcspline(lambda, cy_la, cy_n, z, n_cytop); |
---|
460 | } |
---|
461 | |
---|
462 | /* |
---|
463 | * ------------------------------------------------------------------------ |
---|
464 | * get extinction coefficient of CYTOP at wavelength lambda |
---|
465 | * using cubic spline interpolation |
---|
466 | * ------------------------------------------------------------------------ |
---|
467 | */ |
---|
468 | double Get_k_Cytop(double lambda) |
---|
469 | { |
---|
470 | static int init=0; |
---|
471 | static double *z; |
---|
472 | |
---|
473 | if(!init) |
---|
474 | { |
---|
475 | init=1; |
---|
476 | if((z=(double *)malloc(sizeof(double)*n_cytop))==NULL) |
---|
477 | return -1000.0; |
---|
478 | Mcsp_maketable(cy_la, cy_k, z, n_cytop); |
---|
479 | } |
---|
480 | |
---|
481 | return Mcspline(lambda, cy_la, cy_k, z, n_cytop); |
---|
482 | } |
---|
483 | |
---|
484 | /* |
---|
485 | * ------------------------------------------------------------------------ |
---|
486 | * get the refracted ray |
---|
487 | * if reflected it is thrown away. |
---|
488 | * |
---|
489 | * in_ph[3]: incident photon vector (normalized) |
---|
490 | * nnn[3] : surface normal vector (direct to this side) |
---|
491 | * n1,n2 : refractive indices of the media of this side and the other side |
---|
492 | * ------------------------------------------------------------------------ |
---|
493 | */ |
---|
494 | int refract(double in_phdir[3],double nnn[3],double n1,double n2) |
---|
495 | { |
---|
496 | int i, TotalReflection=0; |
---|
497 | double CosIN, CosOUT=1.0, ppp[3], norm, out_phdir[3]; |
---|
498 | |
---|
499 | CosIN=Mvdot(in_phdir,nnn); |
---|
500 | for(i=0;i<3;i++) |
---|
501 | ppp[i]=(in_phdir[i]-CosIN*nnn[i])*n1/n2; |
---|
502 | |
---|
503 | norm=Mvdot(ppp,ppp); |
---|
504 | #ifdef NO_REFLECTION |
---|
505 | if(norm>1.0) |
---|
506 | return(RT_NO_REFRACTED_LIGHT); /* total reflection */ |
---|
507 | #else |
---|
508 | if(norm>1.0) |
---|
509 | TotalReflection=1; |
---|
510 | else |
---|
511 | { |
---|
512 | #endif |
---|
513 | |
---|
514 | norm=sqrt(1.0-norm); |
---|
515 | for(i=0;i<3;i++) |
---|
516 | out_phdir[i]=ppp[i]+norm*nnn[i]*(CosIN>0.0?(1.0):(-1.0)); |
---|
517 | |
---|
518 | #ifndef NO_REFLECTION |
---|
519 | /* check reflection */ |
---|
520 | CosOUT=Mvdot(out_phdir,nnn); |
---|
521 | } |
---|
522 | |
---|
523 | if(TotalReflection==1 || EsafRandom::Get()->Rndm() < ref(n1,n2,CosIN,CosOUT)) |
---|
524 | { |
---|
525 | #ifdef DEBUG |
---|
526 | fprintf(stderr,"Reflection: (%.3f,%.3f,%.3f)=>", |
---|
527 | in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
528 | #endif |
---|
529 | for(i=0;i<3;i++) |
---|
530 | in_phdir[i]-=2.0*CosIN*nnn[i]; |
---|
531 | #ifdef DEBUG |
---|
532 | fprintf(stderr,"(%.3f,%.3f,%.3f)\n", |
---|
533 | in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
534 | #endif |
---|
535 | return(RT_REFLECTED); |
---|
536 | } |
---|
537 | #endif |
---|
538 | |
---|
539 | /* in_phdir[]: direction of incident ray -> refracted ray */ |
---|
540 | #ifdef DEBUG |
---|
541 | fprintf(stderr,"Refraction: (%.3f,%.3f,%.3f)=>", |
---|
542 | in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
543 | #endif |
---|
544 | for(i=0;i<3;i++) |
---|
545 | in_phdir[i]=out_phdir[i]; |
---|
546 | #ifdef DEBUG |
---|
547 | fprintf(stderr,"(%.3f,%.3f,%.3f)\n", |
---|
548 | in_phdir[0],in_phdir[1],in_phdir[2]); |
---|
549 | #endif |
---|
550 | |
---|
551 | return(RT_REFRACTED); |
---|
552 | } |
---|
553 | |
---|
554 | /* |
---|
555 | * ------------------------------------------------------------------------ |
---|
556 | * calculate the differential coefficient at lens_r[i] |
---|
557 | * Input: |
---|
558 | * i : the radius index of lens_r[i] |
---|
559 | * lens_r[],lens_z[]: lens surface data sets of the radius and the height |
---|
560 | * n_lens_elem : number of data elements of lens_r[] |
---|
561 | * Output: |
---|
562 | * (return value) : differential coefficeint at lens_r[i] |
---|
563 | * ------------------------------------------------------------------------ |
---|
564 | */ |
---|
565 | double differential_r(int i, double *lens_r,double *lens_z, int n_lens_elem) |
---|
566 | { |
---|
567 | double dr1,dr2; |
---|
568 | double dz1,dz2; |
---|
569 | int j1,j2; |
---|
570 | |
---|
571 | dz1=dz2=0.; |
---|
572 | j1=i+1; |
---|
573 | j2=i-1; |
---|
574 | |
---|
575 | if(i>=n_lens_elem-1) |
---|
576 | return 0.0; |
---|
577 | else if(i==n_lens_elem-2) |
---|
578 | { |
---|
579 | if(lens_r[i+1]-lens_r[i]<0.001) |
---|
580 | return 0.0; |
---|
581 | else |
---|
582 | return (lens_z[i+1]-lens_z[i])/(lens_r[i+1]-lens_r[i]); |
---|
583 | } |
---|
584 | |
---|
585 | dr1=lens_r[j1]-lens_r[i]; |
---|
586 | if(dr1<0.001) |
---|
587 | { |
---|
588 | dz1+=lens_z[j1]-lens_z[i]; |
---|
589 | j1++; |
---|
590 | } |
---|
591 | |
---|
592 | if(j2<0) |
---|
593 | { |
---|
594 | j2=-j2; |
---|
595 | dr2=lens_r[i]+lens_r[j2]; |
---|
596 | } |
---|
597 | else |
---|
598 | { |
---|
599 | dr2=lens_r[i]-lens_r[j2]; |
---|
600 | } |
---|
601 | if(dr2<0.001) |
---|
602 | { |
---|
603 | dz2+=lens_z[j2]-lens_z[i]; |
---|
604 | j2--; |
---|
605 | } |
---|
606 | |
---|
607 | return (lens_z[j1]-dz1-lens_z[j2]+dz2)/(dr1+dr2); |
---|
608 | } |
---|
609 | |
---|
610 | /* |
---|
611 | * |
---|
612 | * check if there are any intersections with a cylinder |
---|
613 | * |
---|
614 | */ |
---|
615 | static int check_intersect_cylinder(double r1, double z1, double r2, double z2, |
---|
616 | double phot[8], double *dis) |
---|
617 | { |
---|
618 | double aa[3], xx[2], tmp, z; |
---|
619 | int nroot, i; |
---|
620 | |
---|
621 | aa[0] = phot[PX]*phot[PX] + phot[PY]*phot[PY]; |
---|
622 | aa[1] = 2.0*(phot[X]*phot[PX] + phot[Y]*phot[PY]); |
---|
623 | aa[2] = (phot[X]*phot[X] + phot[Y]*phot[Y]) - r1*r1; |
---|
624 | |
---|
625 | nroot=MSolveQuadratic(aa,xx); |
---|
626 | if(nroot<2) |
---|
627 | return(RT_NO_INTERSECTION1); |
---|
628 | |
---|
629 | /* solution is the smaller positive value */ |
---|
630 | /* swap */ |
---|
631 | if(xx[0]>xx[1]) |
---|
632 | { |
---|
633 | tmp=xx[0]; |
---|
634 | xx[0]=xx[1]; |
---|
635 | xx[1]=tmp; |
---|
636 | } |
---|
637 | if(xx[1]<0) |
---|
638 | return(RT_NO_INTERSECTION1); |
---|
639 | |
---|
640 | for(i=0;i<2;i++) |
---|
641 | { |
---|
642 | if(xx[i]>=0.0) |
---|
643 | { |
---|
644 | z=phot[Z]+phot[PZ]*xx[i]; |
---|
645 | /* check if the solution is in the specified range */ |
---|
646 | if((z-z1)*(z-z2)<0) |
---|
647 | { |
---|
648 | *dis=xx[i]; |
---|
649 | return 0; |
---|
650 | } |
---|
651 | } |
---|
652 | } |
---|
653 | |
---|
654 | *dis=(xx[0]>0 ? xx[0]:xx[1]); |
---|
655 | return(RT_NO_INTERSECTION2); |
---|
656 | } |
---|
657 | |
---|
658 | /* |
---|
659 | * |
---|
660 | * check if there are any intersections with a cone |
---|
661 | * |
---|
662 | */ |
---|
663 | static int check_intersect_cone(double r1, double z1, double r2, double z2, |
---|
664 | double phot[8], double *dis) |
---|
665 | { |
---|
666 | double a00, a0, aa[3], xx[2], z0, dbuf1, tmp, x, y, r, zz[2]; |
---|
667 | int nroot, i; |
---|
668 | |
---|
669 | a00 = (z2-z1)/(r2-r1); |
---|
670 | z0 = z1-a00*r1; |
---|
671 | a0 = a00*a00; |
---|
672 | |
---|
673 | dbuf1 = phot[Z]-z0; |
---|
674 | aa[0] = a0*phot[PX]*phot[PX] + a0*phot[PY]*phot[PY] - phot[PZ]*phot[PZ]; |
---|
675 | aa[1] = 2.0*(a0*phot[PX]*phot[X] + a0*phot[PY]*phot[Y] - phot[PZ]*dbuf1); |
---|
676 | aa[2] = a0*phot[X]*phot[X] + a0*phot[Y]*phot[Y] - dbuf1*dbuf1; |
---|
677 | |
---|
678 | nroot=MSolveQuadratic(aa,xx); |
---|
679 | if(nroot<2) |
---|
680 | return(RT_NO_INTERSECTION1); |
---|
681 | |
---|
682 | /* solution is the smaller positive value */ |
---|
683 | /* swap */ |
---|
684 | if(xx[0]>xx[1]) |
---|
685 | { |
---|
686 | tmp=xx[0]; |
---|
687 | xx[0]=xx[1]; |
---|
688 | xx[1]=tmp; |
---|
689 | } |
---|
690 | if(xx[1]<0.0) |
---|
691 | return(RT_NO_INTERSECTION1); |
---|
692 | |
---|
693 | /* We usually have a solution on a virtual cone with -a00 */ |
---|
694 | /* check this condition */ |
---|
695 | for(i=0;i<2;i++) |
---|
696 | if(xx[i]>=0.0) |
---|
697 | { |
---|
698 | x=phot[PX]*xx[i]+phot[X]; |
---|
699 | y=phot[PY]*xx[i]+phot[Y]; |
---|
700 | zz[i]=phot[PZ]*xx[i]+phot[Z]; |
---|
701 | r=sqrt(x*x+y*y); |
---|
702 | if((r-r1)*(r-r2)<0.0) |
---|
703 | { |
---|
704 | *dis=xx[i]; |
---|
705 | return 0; |
---|
706 | } |
---|
707 | } |
---|
708 | |
---|
709 | if(xx[0]<0.0) |
---|
710 | *dis=xx[1]; |
---|
711 | else |
---|
712 | { |
---|
713 | /* the nearer one to the surface will be what we want... */ |
---|
714 | if(fabs(zz[0]-z1)<fabs(zz[1]-z1)) |
---|
715 | *dis=xx[0]; |
---|
716 | else |
---|
717 | *dis=xx[1]; |
---|
718 | } |
---|
719 | |
---|
720 | return(RT_NO_INTERSECTION2); |
---|
721 | } |
---|
722 | |
---|
723 | /* |
---|
724 | * ------------------------------------------------------------------------ |
---|
725 | * |
---|
726 | * ID: Lens Surface ID |
---|
727 | * phot[8]: input and output photon data |
---|
728 | * phot[0,1,2]: x,y,z position in mm |
---|
729 | * phot[3,4,5]: l,m,n direction |
---|
730 | * phot[6] : wavelength in nm |
---|
731 | * phot[7] : time in ns |
---|
732 | * offset_z : the offset z-position of sphare center approximating |
---|
733 | * lens surface |
---|
734 | * radius : the radius of sphare approximated lens surface |
---|
735 | * lens_r[],lens_z[]: lens surface data sets of the radius and the height |
---|
736 | * n_lens_elem : number of data elements of lens_r[] |
---|
737 | * medium1_n, medium2_n: refractive indices of the media in this side |
---|
738 | * and the other side |
---|
739 | * ------------------------------------------------------------------------ |
---|
740 | */ |
---|
741 | int lens_interaction(int ID, double phot[8], |
---|
742 | double Zc, double radius, double lens_r_max, |
---|
743 | double *lens_r, double *lens_z, int n_lens_elem, |
---|
744 | double medium1_n, double medium2_n, double *dis) |
---|
745 | { |
---|
746 | int r_idx,iter,flag,Found,nroot,dir,status; |
---|
747 | double dbuf1, aa[3], xx[2], x3,y3,z3,r3, r1,r2, z1,z2; |
---|
748 | double nnn[3]; |
---|
749 | double a00; |
---|
750 | double tmp, v[3]; |
---|
751 | #ifdef DEBUG |
---|
752 | double approx_x[3]; |
---|
753 | #endif |
---|
754 | |
---|
755 | if(phot[PZ]==0) |
---|
756 | return(RT_HIT_SIDE_WALL); |
---|
757 | |
---|
758 | if(ID==4 || ID==5) /* plain surface */ |
---|
759 | { |
---|
760 | dbuf1 = (Zc-phot[Z])/phot[PZ]; |
---|
761 | x3=phot[PX]*dbuf1+phot[X]; |
---|
762 | y3=phot[PY]*dbuf1+phot[Y]; |
---|
763 | z3=phot[PZ]*dbuf1+phot[Z]; |
---|
764 | r3=sqrt(x3*x3+y3*y3); |
---|
765 | if(r3>lens_r_max) |
---|
766 | return(RT_HIT_SIDE_WALL); |
---|
767 | *dis=dbuf1; |
---|
768 | } |
---|
769 | else |
---|
770 | { |
---|
771 | /* as an initial guess, intersection with an approximated sphere |
---|
772 | is calculated */ |
---|
773 | |
---|
774 | dbuf1 = phot[Z]-Zc; |
---|
775 | aa[0] = phot[PX]*phot[PX] + phot[PY]*phot[PY] + phot[PZ]*phot[PZ]; |
---|
776 | aa[1] = 2.0*(phot[PX]*phot[X] + phot[PY]*phot[Y] + phot[PZ]*dbuf1); |
---|
777 | aa[2] = phot[X]*phot[X] + phot[Y]*phot[Y] + dbuf1*dbuf1-radius*radius; |
---|
778 | |
---|
779 | nroot=MSolveQuadratic(aa,xx); |
---|
780 | if(nroot<2) |
---|
781 | return(RT_NO_INTERSECTION1); |
---|
782 | |
---|
783 | /* swap */ |
---|
784 | if(xx[0]>xx[1]) |
---|
785 | { |
---|
786 | tmp=xx[0]; |
---|
787 | xx[0]=xx[1]; |
---|
788 | xx[1]=tmp; |
---|
789 | } |
---|
790 | |
---|
791 | /* We need a positive, smaller solution. */ |
---|
792 | if(xx[0]>0.0) |
---|
793 | dbuf1=xx[0]; |
---|
794 | else |
---|
795 | { |
---|
796 | if(xx[1]>0.0) |
---|
797 | dbuf1=xx[1]; |
---|
798 | else |
---|
799 | return(RT_NO_INTERSECTION1); |
---|
800 | } |
---|
801 | |
---|
802 | x3=phot[PX]*dbuf1+phot[X]; |
---|
803 | y3=phot[PY]*dbuf1+phot[Y]; |
---|
804 | z3=phot[PZ]*dbuf1+phot[Z]; |
---|
805 | /* distance to the optical axis at the initially guessed intersection */ |
---|
806 | r3=sqrt(x3*x3+y3*y3); |
---|
807 | |
---|
808 | if(r3>lens_r_max && xx[0]>-100.0) /* -100 is not optimized */ |
---|
809 | { |
---|
810 | /* The other solution may be acceptable just for an initial guess. */ |
---|
811 | dbuf1=xx[0]; |
---|
812 | x3=phot[PX]*dbuf1+phot[X]; |
---|
813 | y3=phot[PY]*dbuf1+phot[Y]; |
---|
814 | z3=phot[PZ]*dbuf1+phot[Z]; |
---|
815 | |
---|
816 | r3=sqrt(x3*x3+y3*y3); |
---|
817 | if(r3>lens_r_max) |
---|
818 | return(RT_HIT_SIDE_WALL); |
---|
819 | } |
---|
820 | *dis=dbuf1; |
---|
821 | |
---|
822 | #ifdef DEBUG |
---|
823 | approx_x[0]=x3;approx_x[1]=y3;approx_x[2]=z3; |
---|
824 | #endif |
---|
825 | } |
---|
826 | |
---|
827 | if(ID==5) /* not Fresnel */ |
---|
828 | { |
---|
829 | nnn[0]=nnn[1]=0.; |
---|
830 | nnn[2]=1.0; |
---|
831 | } |
---|
832 | else |
---|
833 | { |
---|
834 | /* search the index near r3 */ |
---|
835 | r_idx=Mrt_bsearch(lens_r,r3,0,n_lens_elem-1); |
---|
836 | |
---|
837 | if(r_idx>n_lens_elem-2) |
---|
838 | r_idx=n_lens_elem-2; |
---|
839 | |
---|
840 | /* search intersection point with real fresnel lens */ |
---|
841 | iter=0; /* number of iterations */ |
---|
842 | do{ |
---|
843 | Found=0; |
---|
844 | |
---|
845 | r1=lens_r[r_idx]; |
---|
846 | z1=lens_z[r_idx]; |
---|
847 | r2=lens_r[r_idx+1]; |
---|
848 | z2=lens_z[r_idx+1]; |
---|
849 | |
---|
850 | if(r1==r2) |
---|
851 | { |
---|
852 | /* intersection with a part of the cylinder */ |
---|
853 | status=check_intersect_cylinder(r1, z1, r2, z2, phot, dis); |
---|
854 | |
---|
855 | x3=phot[PX]*(*dis)+phot[X]; |
---|
856 | y3=phot[PY]*(*dis)+phot[Y]; |
---|
857 | z3=phot[PZ]*(*dis)+phot[Z]; |
---|
858 | |
---|
859 | if(!status) /* intersection found */ |
---|
860 | { |
---|
861 | Found=1; |
---|
862 | #ifdef DEBUG |
---|
863 | fprintf(stderr,"Hit Backcut\n"); |
---|
864 | /* return (RT_ABSORBED);*/ |
---|
865 | #endif |
---|
866 | /* normal vector */ |
---|
867 | if(z2>z1) |
---|
868 | dir=1; |
---|
869 | else |
---|
870 | dir=-1; |
---|
871 | nnn[X]=dir*x3/r1; |
---|
872 | nnn[Y]=dir*y3/r1; |
---|
873 | nnn[Z]=0.0; |
---|
874 | } |
---|
875 | else /* intersection with cylinder not found */ |
---|
876 | { |
---|
877 | if(status==RT_NO_INTERSECTION2 && fabs(z3-z1)<100.0) |
---|
878 | { |
---|
879 | v[X]=x3; |
---|
880 | v[Y]=y3; |
---|
881 | v[Z]=0.0; |
---|
882 | |
---|
883 | if((z3-z1)*Mvdot(v,&phot[PX])*phot[PZ]>0) |
---|
884 | r_idx--; |
---|
885 | else |
---|
886 | r_idx++; |
---|
887 | } |
---|
888 | else |
---|
889 | { |
---|
890 | *dis=(z1-phot[Z])/phot[PZ]; |
---|
891 | z3=z1; |
---|
892 | x3=phot[PX]*(*dis)+phot[X]; |
---|
893 | y3=phot[PY]*(*dis)+phot[Y]; |
---|
894 | r3=sqrt(x3*x3+y3*y3); |
---|
895 | r_idx=Mrt_bsearch(lens_r,r3,0,n_lens_elem-1); |
---|
896 | } |
---|
897 | } |
---|
898 | #ifdef DEBUG |
---|
899 | fprintf(stderr,"ridx0(%d): %d (%.1f: %.3f %.3f %.3f (%.1f %.1f %.1f)(%.3f %.3f %.3f))\n", |
---|
900 | status,r_idx,z1,r1,r2,r3,phot[X],phot[Y],phot[Z],phot[PX],phot[PY],phot[PZ]); |
---|
901 | #endif |
---|
902 | } |
---|
903 | else /* r1 != r2 */ |
---|
904 | { |
---|
905 | /* intersection with a part of the cone */ |
---|
906 | status=check_intersect_cone(r1, z1, r2, z2, phot, dis); |
---|
907 | |
---|
908 | x3=phot[PX]*(*dis)+phot[X]; |
---|
909 | y3=phot[PY]*(*dis)+phot[Y]; |
---|
910 | z3=phot[PZ]*(*dis)+phot[Z]; |
---|
911 | |
---|
912 | r3=sqrt(x3*x3+y3*y3); |
---|
913 | |
---|
914 | if(!status) /* intersection found */ |
---|
915 | { |
---|
916 | Found=1; |
---|
917 | /* normal vector */ |
---|
918 | if(r_idx>n_lens_elem-2) |
---|
919 | r_idx=n_lens_elem-2; |
---|
920 | a00=(differential_r(r_idx,lens_r,lens_z,n_lens_elem) |
---|
921 | *(r3-lens_r[r_idx])- |
---|
922 | differential_r(r_idx+1,lens_r,lens_z,n_lens_elem) |
---|
923 | *(r3-lens_r[r_idx+1]))/(lens_r[r_idx+1]-lens_r[r_idx]); |
---|
924 | nnn[X]=a00*x3; |
---|
925 | nnn[Y]=a00*y3; |
---|
926 | nnn[Z]=-r3; |
---|
927 | dbuf1=sqrt(Mvdot(nnn,nnn)); |
---|
928 | nnn[X]/=dbuf1; |
---|
929 | nnn[Y]/=dbuf1; |
---|
930 | nnn[Z]/=dbuf1; |
---|
931 | } |
---|
932 | else /* not found */ |
---|
933 | { |
---|
934 | if(status==RT_NO_INTERSECTION2 && |
---|
935 | fabs(z3-z1)<10. && fabs(r3-r1)<5.) |
---|
936 | { |
---|
937 | if(r3<r1) |
---|
938 | r_idx--; |
---|
939 | if(r3>r2) |
---|
940 | r_idx++; |
---|
941 | } |
---|
942 | else |
---|
943 | { |
---|
944 | *dis=(z1-phot[Z])/phot[PZ]; |
---|
945 | z3=z1; |
---|
946 | x3=phot[PX]*(*dis)+phot[X]; |
---|
947 | y3=phot[PY]*(*dis)+phot[Y]; |
---|
948 | r3=sqrt(x3*x3+y3*y3); |
---|
949 | r_idx=Mrt_bsearch(lens_r,r3,0,n_lens_elem-1); |
---|
950 | } |
---|
951 | } |
---|
952 | #ifdef DEBUG |
---|
953 | fprintf(stderr,"ridx1(%d): %d (%.1f: %.3f %.3f %.3f (%.1f %.1f %.1f)(%.3f %.3f %.3f))\n", |
---|
954 | status,r_idx,z1,r1,r2,r3,phot[X],phot[Y],phot[Z],phot[PX],phot[PY],phot[PZ]); |
---|
955 | #endif |
---|
956 | } |
---|
957 | |
---|
958 | if(r_idx>=S_DATA) |
---|
959 | return(RT_OUT_OF_SURFACE2); |
---|
960 | if(r_idx<0 && r3>lens_r_max && fabs(z3-z1)<10.0) |
---|
961 | return(RT_OUT_OF_SURFACE2); |
---|
962 | if(r_idx<0) |
---|
963 | { |
---|
964 | r_idx=1; |
---|
965 | /* return(RT_OUT_OF_SURFACE1); */ |
---|
966 | } |
---|
967 | |
---|
968 | /* iteration doesn't converge */ |
---|
969 | if(iter>RT_SEARCH_ITER_MAX) |
---|
970 | { |
---|
971 | #ifdef DEBUG |
---|
972 | fprintf(stderr,"app.(%.1f,%.1f,%.1f)=>end(%.1f,%.1f,%.1f)\n", |
---|
973 | approx_x[0],approx_x[1],approx_x[2],x3,y3,z3); |
---|
974 | #endif |
---|
975 | return(RT_EXCEED_ITER_MAX); |
---|
976 | } |
---|
977 | |
---|
978 | iter++; |
---|
979 | |
---|
980 | } while(!Found); |
---|
981 | |
---|
982 | #if 0 |
---|
983 | int idx_dir; |
---|
984 | double tmp_dis, tmp_x[3]; |
---|
985 | |
---|
986 | /* |
---|
987 | * check no intersections at a nearer point |
---|
988 | */ |
---|
989 | v[X]=x3; |
---|
990 | v[Y]=y3; |
---|
991 | v[Z]=0.0; |
---|
992 | if(Mvdot(v,&phot[PX])<0) |
---|
993 | idx_dir=1; |
---|
994 | else |
---|
995 | idx_dir=-1; |
---|
996 | |
---|
997 | do { |
---|
998 | r_idx+=idx_dir; |
---|
999 | |
---|
1000 | r1=lens_r[r_idx]; |
---|
1001 | z1=lens_z[r_idx]; |
---|
1002 | r2=lens_r[r_idx+1]; |
---|
1003 | z2=lens_z[r_idx+1]; |
---|
1004 | |
---|
1005 | if(r1==r2) |
---|
1006 | status=check_intersect_cylinder(r1, z1, r2, z2, phot, &tmp_dis); |
---|
1007 | else |
---|
1008 | status=check_intersect_cone(r1, z1, r2, z2, phot, &tmp_dis); |
---|
1009 | |
---|
1010 | if(!status) /* intersection found */ |
---|
1011 | { |
---|
1012 | #ifdef DEBUG |
---|
1013 | if(r1==r2) |
---|
1014 | { |
---|
1015 | fprintf(stderr,"Hit Backcut2\n"); |
---|
1016 | /*return (RT_ABSORBED);*/ |
---|
1017 | } |
---|
1018 | #endif |
---|
1019 | tmp_x[X]=phot[PX]*tmp_dis+phot[X]; |
---|
1020 | tmp_x[Y]=phot[PY]*tmp_dis+phot[Y]; |
---|
1021 | tmp_x[Z]=phot[PZ]*tmp_dis+phot[Z]; |
---|
1022 | r3=sqrt(tmp_x[X]*tmp_x[X]+tmp_x[Y]*tmp_x[Y]); |
---|
1023 | |
---|
1024 | if(r1==r2) |
---|
1025 | { |
---|
1026 | if(z2>z1) |
---|
1027 | dir=1; |
---|
1028 | else |
---|
1029 | dir=-1; |
---|
1030 | nnn[X]=dir*tmp_x[X]/r3; |
---|
1031 | nnn[Y]=dir*tmp_x[Y]/r3; |
---|
1032 | nnn[Z]=0.0; |
---|
1033 | } |
---|
1034 | else |
---|
1035 | { |
---|
1036 | /* normal vector */ |
---|
1037 | if(r_idx>n_lens_elem-2) |
---|
1038 | r_idx=n_lens_elem-2; |
---|
1039 | a00=(differential_r(r_idx,lens_r,lens_z,n_lens_elem) |
---|
1040 | *(r3-lens_r[r_idx])- |
---|
1041 | differential_r(r_idx+1,lens_r,lens_z,n_lens_elem) |
---|
1042 | *(r3-lens_r[r_idx+1]))/(lens_r[r_idx+1]-lens_r[r_idx]); |
---|
1043 | nnn[X]=a00*tmp_x[X]; |
---|
1044 | nnn[Y]=a00*tmp_x[Y]; |
---|
1045 | nnn[Z]=-r3; |
---|
1046 | dbuf1=sqrt(Mvdot(nnn,nnn)); |
---|
1047 | nnn[X]/=dbuf1; |
---|
1048 | nnn[Y]/=dbuf1; |
---|
1049 | nnn[Z]/=dbuf1; |
---|
1050 | } |
---|
1051 | |
---|
1052 | if(Mvdot(nnn,&phot[PX])>=0) /* wrong intersection; back side */ |
---|
1053 | status=1; |
---|
1054 | else /* update intersection point */ |
---|
1055 | { |
---|
1056 | x3=tmp_x[X]; |
---|
1057 | y3=tmp_x[Y]; |
---|
1058 | z3=tmp_x[Z]; |
---|
1059 | *dis=tmp_dis; |
---|
1060 | } |
---|
1061 | } |
---|
1062 | }while(!status); |
---|
1063 | #endif |
---|
1064 | } |
---|
1065 | |
---|
1066 | /* refraction */ |
---|
1067 | if(phot[PZ]<0.0) |
---|
1068 | { |
---|
1069 | tmp=medium2_n; |
---|
1070 | medium2_n=medium1_n; |
---|
1071 | medium1_n=tmp; |
---|
1072 | } |
---|
1073 | flag=refract(&phot[PX], nnn, medium1_n, medium2_n); |
---|
1074 | #if 0 |
---|
1075 | if(flag==RT_REFLECTED) |
---|
1076 | return(RT_REFLECTION_DISCARDED); /* reflected photons are thrown away */ |
---|
1077 | #endif |
---|
1078 | |
---|
1079 | /* distance between injection point and the Surface */ |
---|
1080 | phot[T]+=(*dis)* medium1_n/EConst::Clight(); |
---|
1081 | |
---|
1082 | phot[X]=x3; |
---|
1083 | phot[Y]=y3; |
---|
1084 | phot[Z]=z3; |
---|
1085 | |
---|
1086 | return flag; |
---|
1087 | } |
---|
1088 | |
---|
1089 | int CheckRcut(Mtel_param *param, double in_ph[6], int flag) |
---|
1090 | { |
---|
1091 | int surfid; |
---|
1092 | surfid=(-flag)/1000; |
---|
1093 | if(surfid>8) |
---|
1094 | surfid=8; |
---|
1095 | |
---|
1096 | if(fabs(in_ph[Y])>param->Mr_cut[surfid]) |
---|
1097 | return RT_OUT_OF_SURFACE1; |
---|
1098 | else |
---|
1099 | return 0; |
---|
1100 | } |
---|
1101 | |
---|
1102 | static int CheckIris(Mtel_param *param, double in_ph[6], int flag) |
---|
1103 | { |
---|
1104 | double x3, y3, z3=0.0, r3=0.0, dist, radius; |
---|
1105 | |
---|
1106 | if(flag==SURFACE3) |
---|
1107 | { |
---|
1108 | z3=param->MZc3; |
---|
1109 | r3=param->MRc3; |
---|
1110 | } |
---|
1111 | else if(flag==SURFACED) |
---|
1112 | { |
---|
1113 | z3=param->MZcD; |
---|
1114 | r3=param->MRcD; |
---|
1115 | } |
---|
1116 | |
---|
1117 | dist=(z3 - in_ph[Z])/in_ph[PZ]; |
---|
1118 | if(dist>=0.0) |
---|
1119 | { |
---|
1120 | x3=in_ph[PX]*dist+in_ph[X]; |
---|
1121 | y3=in_ph[PY]*dist+in_ph[Y]; |
---|
1122 | |
---|
1123 | in_ph[X]=x3; |
---|
1124 | in_ph[Y]=y3; |
---|
1125 | in_ph[Z]=z3; |
---|
1126 | in_ph[T]+=dist/EConst::Clight(); |
---|
1127 | |
---|
1128 | radius=sqrt(x3*x3+y3*y3); |
---|
1129 | if(radius > param->Mr_wall) |
---|
1130 | return RT_HIT_SIDE_WALL; |
---|
1131 | else if(radius > r3) |
---|
1132 | { |
---|
1133 | if(flag==SURFACE3) |
---|
1134 | return RT_OUT_OF_IRIS; |
---|
1135 | else if(flag==SURFACED) |
---|
1136 | return RT_OUT_OF_DOES; |
---|
1137 | } |
---|
1138 | } |
---|
1139 | |
---|
1140 | return 0; |
---|
1141 | } |
---|
1142 | |
---|
1143 | /* ------------------------------------------------------------------------- |
---|
1144 | * int trace_lens(Mtel_param *param, double ph_in[8], double ph_out[8], |
---|
1145 | * FILE *fp) |
---|
1146 | * |
---|
1147 | * --- trace photons in the EUSO lens system (the first lens to the last one) |
---|
1148 | * |
---|
1149 | * Input: |
---|
1150 | * param tel_param* to store the optics parameters |
---|
1151 | * (see also in tracemain_optF1v2.h) |
---|
1152 | * ph_in[] info on injected photon |
---|
1153 | * ph_out[] info on output photon |
---|
1154 | * ph_xx[0,1,2] x,y,z position in mm |
---|
1155 | * ph_xx[3,4,5] x,y,z direction (unit vector) |
---|
1156 | * ph_xx[6] wavelength in nm |
---|
1157 | * ph_xx[7] time in ns |
---|
1158 | * fp FILE* for (error) message logging |
---|
1159 | * |
---|
1160 | * Output: |
---|
1161 | * return value |
---|
1162 | * 0 normal end |
---|
1163 | * <0 error |
---|
1164 | * (see trace_optF1v2.h for more detail |
---|
1165 | * from RT_NO_SPINTERSECTION to RT_ESCAPE_FROM_ENTRANCE) |
---|
1166 | * ------------------------------------------------------------------------- |
---|
1167 | */ |
---|
1168 | int trace_lens(Mtel_param *param, double ph_in[], double ph_out[], FILE *fplog) |
---|
1169 | { |
---|
1170 | int status=0, n_int, WithinOptics; |
---|
1171 | int PrevPoint, CurPoint, NextPoint; |
---|
1172 | double nn_cytop,kk_cytop,nn_pmma,kk_pmma; |
---|
1173 | double AbsorbCoeff, TransProb; |
---|
1174 | double dis; |
---|
1175 | |
---|
1176 | ph_out[L]=ph_in[L]; |
---|
1177 | |
---|
1178 | |
---|
1179 | /* Opt. index for this lambda */ |
---|
1180 | nn_cytop=Get_n_Cytop(ph_in[L]); |
---|
1181 | kk_cytop=Get_k_Cytop(ph_in[L]); |
---|
1182 | nn_pmma=Get_n_Acryl(ph_in[L]); |
---|
1183 | kk_pmma=Get_k_Acryl(ph_in[L]); |
---|
1184 | |
---|
1185 | if(ph_in[Z]>=param->MSz7 && ph_in[PZ]<0.0) |
---|
1186 | { |
---|
1187 | PrevPoint=SURFACE_FS; |
---|
1188 | CurPoint=SURFACE_FS; |
---|
1189 | NextPoint=SURFACE7; |
---|
1190 | } |
---|
1191 | else |
---|
1192 | { |
---|
1193 | PrevPoint=SURFACE0; |
---|
1194 | CurPoint=SURFACE0; |
---|
1195 | NextPoint=SURFACE1; |
---|
1196 | } |
---|
1197 | n_int=0; |
---|
1198 | WithinOptics=1; |
---|
1199 | |
---|
1200 | while(n_int++ < RT_INTERACTION_MAX && WithinOptics) |
---|
1201 | { |
---|
1202 | PrevPoint=CurPoint; |
---|
1203 | CurPoint=NextPoint; |
---|
1204 | |
---|
1205 | switch(NextPoint) |
---|
1206 | { |
---|
1207 | case SURFACE0: |
---|
1208 | case SURFACE_FS: |
---|
1209 | WithinOptics=0; |
---|
1210 | break; |
---|
1211 | |
---|
1212 | case SURFACE1: |
---|
1213 | status=lens_interaction(1, ph_in, param->MZc1, param->MRc1, |
---|
1214 | param->Mr_lens, sr1, sz1, n_s1, |
---|
1215 | REFRACTIVE_IDX_MEDIA,nn_cytop,&dis); |
---|
1216 | //printf("1 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1217 | #ifdef DEBUG |
---|
1218 | printf("1 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1219 | #endif |
---|
1220 | if(status==RT_REFLECTED) |
---|
1221 | { |
---|
1222 | NextPoint=PrevPoint; |
---|
1223 | status=0; |
---|
1224 | } |
---|
1225 | else if(PrevPoint==SURFACE0) |
---|
1226 | NextPoint=SURFACE2; |
---|
1227 | else |
---|
1228 | NextPoint=SURFACE0; |
---|
1229 | break; |
---|
1230 | |
---|
1231 | case SURFACE2: |
---|
1232 | status=lens_interaction(2, ph_in, param->MZc2, param->MRc2, |
---|
1233 | param->Mr_lens, sr2, sz2, n_s2, |
---|
1234 | nn_cytop,REFRACTIVE_IDX_MEDIA, &dis); |
---|
1235 | //printf("2 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1236 | #ifdef DEBUG |
---|
1237 | printf("2 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1238 | #endif |
---|
1239 | if(status==RT_REFLECTED) |
---|
1240 | { |
---|
1241 | NextPoint=PrevPoint; |
---|
1242 | status=0; |
---|
1243 | } |
---|
1244 | else if(PrevPoint==SURFACE1) |
---|
1245 | NextPoint=SURFACE3; |
---|
1246 | else |
---|
1247 | NextPoint=SURFACE1; |
---|
1248 | break; |
---|
1249 | |
---|
1250 | case SURFACE3: |
---|
1251 | if((status=CheckIris(param,ph_in,SURFACE3))<0) |
---|
1252 | return (status+SURFACE3); |
---|
1253 | if(ph_in[PZ]>0.0) |
---|
1254 | NextPoint=SURFACE4; |
---|
1255 | else |
---|
1256 | NextPoint=SURFACE2; |
---|
1257 | break; |
---|
1258 | |
---|
1259 | case SURFACE4: |
---|
1260 | status=lens_interaction(4, ph_in, param->MZc4, param->MRc4, |
---|
1261 | param->Mr_lens, sr4, sz4, n_s4, |
---|
1262 | REFRACTIVE_IDX_MEDIA, nn_pmma, &dis); |
---|
1263 | if(status==RT_REFLECTED) |
---|
1264 | { |
---|
1265 | NextPoint=PrevPoint; |
---|
1266 | status=0; |
---|
1267 | } |
---|
1268 | else if(ph_in[PZ]>0.0) |
---|
1269 | NextPoint=SURFACED; |
---|
1270 | else |
---|
1271 | NextPoint=SURFACE3; |
---|
1272 | break; |
---|
1273 | |
---|
1274 | case SURFACED: |
---|
1275 | #ifndef NO_DIFFRACTIVE |
---|
1276 | if(ph_in[PZ]<0) |
---|
1277 | diffract(1, &ph_in[PX], ph_in[X], ph_in[Y], ph_in[Z], |
---|
1278 | param->MZcD, 1.0003, 1.0003, ph_in[L]*1e-6, |
---|
1279 | param->Mlambda0*1e-6, 1); |
---|
1280 | #endif |
---|
1281 | status=lens_interaction(5, ph_in, param->MZcD, 0.0, |
---|
1282 | param->MRcD, NULL, NULL, 0, |
---|
1283 | nn_pmma, REFRACTIVE_IDX_MEDIA, &dis); |
---|
1284 | if(status==RT_REFLECTED) |
---|
1285 | { |
---|
1286 | NextPoint=PrevPoint; |
---|
1287 | status=0; |
---|
1288 | } |
---|
1289 | else |
---|
1290 | { |
---|
1291 | #ifndef NO_DIFFRACTIVE |
---|
1292 | if(ph_in[PZ]>0) |
---|
1293 | diffract(1, &ph_in[PX], ph_in[X], ph_in[Y], ph_in[Z], |
---|
1294 | param->MZcD, 1.0003, 1.0003, ph_in[L]*1e-6, |
---|
1295 | param->Mlambda0*1e-6, 1); |
---|
1296 | #endif |
---|
1297 | } |
---|
1298 | if(ph_in[PZ]>0.0) |
---|
1299 | NextPoint=SURFACE6; |
---|
1300 | else |
---|
1301 | NextPoint=SURFACE4; |
---|
1302 | break; |
---|
1303 | |
---|
1304 | case SURFACE6: |
---|
1305 | status=lens_interaction(6, ph_in, param->MZc6, param->MRc6, |
---|
1306 | param->Mr_lens, sr6, sz6, n_s6, |
---|
1307 | REFRACTIVE_IDX_MEDIA, nn_cytop, &dis); |
---|
1308 | //printf("6 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1309 | #ifdef DEBUG |
---|
1310 | printf("6 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1311 | #endif |
---|
1312 | if(status==RT_REFLECTED) |
---|
1313 | { |
---|
1314 | NextPoint=PrevPoint; |
---|
1315 | status=0; |
---|
1316 | } |
---|
1317 | else if(PrevPoint==SURFACED) |
---|
1318 | NextPoint=SURFACE7; |
---|
1319 | else |
---|
1320 | NextPoint=SURFACED; |
---|
1321 | break; |
---|
1322 | |
---|
1323 | case SURFACE7: |
---|
1324 | status=lens_interaction(7, ph_in, param->MZc7, param->MRc7, |
---|
1325 | param->Mr_lens, sr7, sz7, n_s7, |
---|
1326 | nn_cytop, REFRACTIVE_IDX_MEDIA, &dis); |
---|
1327 | //printf("7 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1328 | #ifdef DEBUG |
---|
1329 | printf("7 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]); |
---|
1330 | #endif |
---|
1331 | if(status==RT_REFLECTED) |
---|
1332 | { |
---|
1333 | NextPoint=PrevPoint; |
---|
1334 | status=0; |
---|
1335 | } |
---|
1336 | else if(PrevPoint==SURFACE6) |
---|
1337 | NextPoint=SURFACE_FS; |
---|
1338 | else |
---|
1339 | NextPoint=SURFACE6; |
---|
1340 | break; |
---|
1341 | } |
---|
1342 | #ifdef DEBUG |
---|
1343 | fprintf(stderr,"%d %.1f %.1f %.1f %.3f %.3f %.3f\n", |
---|
1344 | -CurPoint/1000, |
---|
1345 | ph_in[X],ph_in[Y],ph_in[Z],ph_in[PX],ph_in[PY],ph_in[PZ]); |
---|
1346 | #endif |
---|
1347 | if(status<0) return (status+CurPoint); |
---|
1348 | status=CheckRcut(param,ph_in,CurPoint); |
---|
1349 | if(status<0) return (status+CurPoint); |
---|
1350 | |
---|
1351 | #ifndef NO_ABSORPTION |
---|
1352 | /* absorption between S1 and S2 or between S6 and S7 */ |
---|
1353 | if((PrevPoint==SURFACE1 && CurPoint==SURFACE2) || |
---|
1354 | (PrevPoint==SURFACE2 && CurPoint==SURFACE1) || |
---|
1355 | (PrevPoint==SURFACE6 && CurPoint==SURFACE7) || |
---|
1356 | (PrevPoint==SURFACE7 && CurPoint==SURFACE6)) |
---|
1357 | { |
---|
1358 | AbsorbCoeff=kk_cytop*M_PI*4.0/(ph_in[L]*1.e-6); |
---|
1359 | TransProb=exp(-AbsorbCoeff*dis); |
---|
1360 | |
---|
1361 | if(EsafRandom::Get()->Rndm() >TransProb) |
---|
1362 | return(RT_ABSORBED+CurPoint); |
---|
1363 | } |
---|
1364 | if((PrevPoint==SURFACE4 && CurPoint==SURFACED) || |
---|
1365 | (PrevPoint==SURFACED && CurPoint==SURFACE4)) |
---|
1366 | { |
---|
1367 | AbsorbCoeff=kk_pmma*M_PI*4.0/(ph_in[L]*1.e-6); |
---|
1368 | TransProb=exp(-AbsorbCoeff*dis); |
---|
1369 | |
---|
1370 | if(EsafRandom::Get()->Rndm() >TransProb) |
---|
1371 | return(RT_ABSORBED+CurPoint); |
---|
1372 | } |
---|
1373 | |
---|
1374 | #endif |
---|
1375 | } |
---|
1376 | |
---|
1377 | if(n_int>=RT_INTERACTION_MAX) |
---|
1378 | return (RT_STRAY_LIGHT); |
---|
1379 | |
---|
1380 | ph_out[X] = ph_in[X]; |
---|
1381 | ph_out[Y] = ph_in[Y]; |
---|
1382 | ph_out[Z] = ph_in[Z]; |
---|
1383 | ph_out[PX] = ph_in[PX]; |
---|
1384 | ph_out[PY] = ph_in[PY]; |
---|
1385 | ph_out[PZ] = ph_in[PZ]; |
---|
1386 | ph_out[T] = ph_in[T]; |
---|
1387 | |
---|
1388 | return 0; |
---|
1389 | } |
---|