Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 263

Historique | Voir | Annoter | Télécharger (53,9 ko)

1 242 equemene
#!/usr/bin/env python3
2 199 equemene
#
3 242 equemene
# TrouNoir model using PyOpenCL or PyCUDA
4 199 equemene
#
5 234 equemene
# CC BY-NC-SA 2019 : <emmanuel.quemener@ens-lyon.fr>
6 199 equemene
#
7 261 equemene
# Part of matrix programs from: https://forge.cbp.ens-lyon.fr/svn/bench4gpu/
8 261 equemene
#
9 242 equemene
# Thanks to Andreas Klockner for PyOpenCL and PyCUDA:
10 199 equemene
# http://mathema.tician.de/software/pyopencl
11 234 equemene
#
12 204 equemene
# Original code programmed in Fortran 77 in mars 1994
13 204 equemene
# for Practical Work of Numerical Simulation
14 204 equemene
# DEA (old Master2) in astrophysics and spatial techniques in Meudon
15 204 equemene
# by Herve Aussel & Emmanuel Quemener
16 204 equemene
#
17 204 equemene
# Conversion in C done by Emmanuel Quemener in august 1997
18 204 equemene
# GPUfication in OpenCL under Python in july 2019
19 221 equemene
# GPUfication in CUDA under Python in august 2019
20 204 equemene
#
21 204 equemene
# Thanks to :
22 234 equemene
#
23 204 equemene
# - Herve Aussel for his part of code of black body spectrum
24 204 equemene
# - Didier Pelat for his help to perform this work
25 204 equemene
# - Jean-Pierre Luminet for his article published in 1979
26 204 equemene
# - Numerical Recipies for Runge Kutta recipies
27 204 equemene
# - Luc Blanchet for his disponibility about my questions in General Relativity
28 204 equemene
# - Pierre Lena for his passion about science and vulgarisation
29 199 equemene
30 229 equemene
# If crash on OpenCL Intel implementation, add following options and force
31 229 equemene
#export PYOPENCL_COMPILER_OUTPUT=1
32 229 equemene
#export CL_CONFIG_USE_VECTORIZER=True
33 229 equemene
#export CL_CONFIG_CPU_VECTORIZER_MODE=16
34 226 equemene
35 199 equemene
import pyopencl as cl
36 199 equemene
import numpy
37 199 equemene
import time,string
38 199 equemene
from numpy.random import randint as nprnd
39 199 equemene
import sys
40 199 equemene
import getopt
41 199 equemene
import matplotlib.pyplot as plt
42 211 equemene
from socket import gethostname
43 199 equemene
44 211 equemene
def DictionariesAPI():
45 211 equemene
    PhysicsList={'Einstein':0,'Newton':1}
46 211 equemene
    return(PhysicsList)
47 204 equemene
48 226 equemene
#
49 226 equemene
# Blank space below to simplify debugging on OpenCL code
50 226 equemene
#
51 226 equemene
52 226 equemene
53 226 equemene
54 226 equemene
55 226 equemene
56 226 equemene
57 226 equemene
58 226 equemene
59 226 equemene
60 226 equemene
61 226 equemene
62 226 equemene
63 226 equemene
64 226 equemene
65 226 equemene
66 226 equemene
67 226 equemene
68 226 equemene
69 226 equemene
70 226 equemene
71 226 equemene
72 226 equemene
73 226 equemene
74 226 equemene
75 226 equemene
76 226 equemene
77 226 equemene
78 226 equemene
79 226 equemene
80 226 equemene
81 226 equemene
82 226 equemene
83 226 equemene
84 226 equemene
85 226 equemene
86 226 equemene
87 226 equemene
88 226 equemene
89 226 equemene
90 226 equemene
91 226 equemene
92 226 equemene
93 226 equemene
94 226 equemene
95 226 equemene
96 226 equemene
97 226 equemene
98 226 equemene
99 226 equemene
100 226 equemene
101 226 equemene
102 226 equemene
103 226 equemene
104 226 equemene
105 211 equemene
BlobOpenCL= """
106 204 equemene

107 234 equemene
#define PI (float)3.14159265359e0f
108 209 equemene
#define nbr 256
109 199 equemene

110 211 equemene
#define EINSTEIN 0
111 211 equemene
#define NEWTON 1
112 211 equemene

113 224 equemene
#ifdef SETTRACKPOINTS
114 224 equemene
#define TRACKPOINTS SETTRACKPOINTS
115 224 equemene
#else
116 217 equemene
#define TRACKPOINTS 2048
117 224 equemene
#endif
118 217 equemene

119 199 equemene
float atanp(float x,float y)
120 199 equemene
{
121 199 equemene
  float angle;
122 199 equemene

123 199 equemene
  angle=atan2(y,x);
124 199 equemene

125 204 equemene
  if (angle<0.e0f)
126 199 equemene
    {
127 199 equemene
      angle+=(float)2.e0f*PI;
128 199 equemene
    }
129 199 equemene

130 199 equemene
  return angle;
131 199 equemene
}
132 199 equemene

133 199 equemene
float f(float v)
134 199 equemene
{
135 199 equemene
  return v;
136 199 equemene
}
137 199 equemene

138 211 equemene
#if PHYSICS == NEWTON
139 199 equemene
float g(float u,float m,float b)
140 199 equemene
{
141 211 equemene
  return (-u);
142 211 equemene
}
143 211 equemene
#else
144 211 equemene
float g(float u,float m,float b)
145 211 equemene
{
146 204 equemene
  return (3.e0f*m/b*pow(u,2)-u);
147 199 equemene
}
148 211 equemene
#endif
149 199 equemene

150 199 equemene
void calcul(float *us,float *vs,float up,float vp,
151 234 equemene
            float h,float m,float b)
152 199 equemene
{
153 199 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
154 199 equemene

155 199 equemene
  c0=h*f(vp);
156 234 equemene
  c1=h*f(vp+c0/2.e0f);
157 234 equemene
  c2=h*f(vp+c1/2.e0f);
158 199 equemene
  c3=h*f(vp+c2);
159 199 equemene
  d0=h*g(up,m,b);
160 234 equemene
  d1=h*g(up+d0/2.e0f,m,b);
161 234 equemene
  d2=h*g(up+d1/2.e0f,m,b);
162 199 equemene
  d3=h*g(up+d2,m,b);
163 199 equemene

164 234 equemene
  *us=up+(c0+2.e0f*c1+2.e0f*c2+c3)/6.e0f;
165 234 equemene
  *vs=vp+(d0+2.e0f*d1+2.e0f*d2+d3)/6.e0f;
166 199 equemene
}
167 199 equemene

168 199 equemene
void rungekutta(float *ps,float *us,float *vs,
169 234 equemene
                float pp,float up,float vp,
170 234 equemene
                float h,float m,float b)
171 199 equemene
{
172 199 equemene
  calcul(us,vs,up,vp,h,m,b);
173 199 equemene
  *ps=pp+h;
174 199 equemene
}
175 199 equemene

176 199 equemene
float decalage_spectral(float r,float b,float phi,
177 234 equemene
                        float tho,float m)
178 199 equemene
{
179 199 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
180 199 equemene
}
181 199 equemene

182 199 equemene
float spectre(float rf,int q,float b,float db,
183 234 equemene
              float h,float r,float m,float bss)
184 199 equemene
{
185 199 equemene
  float flx;
186 199 equemene

187 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
188 234 equemene
  flx=exp(q*log(r/m)+4.e0f*log(rf))*b*db*h;
189 199 equemene
  return(flx);
190 199 equemene
}
191 199 equemene

192 209 equemene
float spectre_cn(float rf32,float b32,float db32,
193 234 equemene
                 float h32,float r32,float m32,float bss32)
194 199 equemene
{
195 234 equemene

196 213 equemene
#define MYFLOAT float
197 209 equemene

198 209 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
199 209 equemene
  MYFLOAT b=(MYFLOAT)(b32);
200 209 equemene
  MYFLOAT db=(MYFLOAT)(db32);
201 209 equemene
  MYFLOAT h=(MYFLOAT)(h32);
202 209 equemene
  MYFLOAT r=(MYFLOAT)(r32);
203 209 equemene
  MYFLOAT m=(MYFLOAT)(m32);
204 209 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
205 209 equemene

206 209 equemene
  MYFLOAT flx;
207 209 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
208 199 equemene
  int fi,posfreq;
209 199 equemene

210 234 equemene
#define planck 6.62e-34f
211 234 equemene
#define k 1.38e-23f
212 234 equemene
#define c2 9.e16f
213 234 equemene
#define temp 3.e7f
214 234 equemene
#define m_point 1.e0f
215 199 equemene

216 234 equemene
#define lplanck (log(6.62e0f)-34.e0f*log(10.e0f))
217 234 equemene
#define lk (log(1.38e0f)-23.e0f*log(10.e0f))
218 234 equemene
#define lc2 (log(9.e0f)+16.e0f*log(10.e0f))
219 199 equemene

220 234 equemene
  MYFLOAT v=1.e0f-3.e0f/r;
221 199 equemene

222 234 equemene
  qu=1.e0f/sqrt((1.e0f-3.e0f/r)*r)*(sqrt(r)-sqrt(6.e0f)+sqrt(3.e0f)/2.e0f*log((sqrt(r)+sqrt(3.e0f))/(sqrt(r)-sqrt(3.e0f))* 0.17157287525380988e0f ));
223 199 equemene

224 234 equemene
  temp_em=temp*sqrt(m)*exp(0.25e0f*log(m_point)-0.75e0f*log(r)-0.125e0f*log(v)+0.25e0f*log(fabs(qu)));
225 209 equemene

226 234 equemene
  flux_int=0.e0f;
227 234 equemene
  flx=0.e0f;
228 209 equemene

229 201 equemene
  for (fi=0;fi<nbr;fi++)
230 199 equemene
    {
231 209 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
232 209 equemene
      nu_rec=nu_em*rf;
233 209 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
234 199 equemene
      if ((posfreq>0)&&(posfreq<nbr))
235 234 equemene
        {
236 209 equemene
          // Initial version
237 234 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
238 209 equemene
          // Version with log used
239 234 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
240 234 equemene
          // flux_int*=pow(rf,3)*b*db*h;
241 234 equemene
          //flux_int*=exp(3.e0f*log(rf))*b*db*h;
242 234 equemene
          flux_int=2.e0f*exp(lplanck-lc2+3.e0f*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.e0f)*exp(3.e0f*log(rf))*b*db*h;
243 211 equemene

244 234 equemene
          flx+=flux_int;
245 234 equemene
        }
246 199 equemene
    }
247 209 equemene

248 209 equemene
  return((float)(flx));
249 199 equemene
}
250 199 equemene

251 199 equemene
void impact(float phi,float r,float b,float tho,float m,
252 234 equemene
            float *zp,float *fp,
253 234 equemene
            int q,float db,
254 234 equemene
            float h,int raie)
255 199 equemene
{
256 204 equemene
  float flx,rf,bss;
257 199 equemene

258 199 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
259 199 equemene

260 199 equemene
  if (raie==0)
261 199 equemene
    {
262 234 equemene
      bss=1.e19f;
263 209 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
264 209 equemene
    }
265 209 equemene
  else
266 234 equemene
    {
267 234 equemene
      bss=2.e0f;
268 199 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
269 199 equemene
    }
270 234 equemene

271 234 equemene
  *zp=1.e0f/rf;
272 199 equemene
  *fp=flx;
273 199 equemene

274 199 equemene
}
275 199 equemene

276 204 equemene
__kernel void EachPixel(__global float *zImage,__global float *fImage,
277 204 equemene
                        float Mass,float InternalRadius,
278 204 equemene
                        float ExternalRadius,float Angle,
279 209 equemene
                        int Line)
280 199 equemene
{
281 199 equemene
   uint xi=(uint)get_global_id(0);
282 199 equemene
   uint yi=(uint)get_global_id(1);
283 199 equemene
   uint sizex=(uint)get_global_size(0);
284 199 equemene
   uint sizey=(uint)get_global_size(1);
285 199 equemene

286 204 equemene
   // Perform trajectory for each pixel, exit on hit
287 199 equemene

288 226 equemene
  float m,rs,ri,re,tho;
289 226 equemene
  int q,raie;
290 199 equemene

291 204 equemene
  m=Mass;
292 228 equemene
  rs=2.e0f*m;
293 204 equemene
  ri=InternalRadius;
294 204 equemene
  re=ExternalRadius;
295 204 equemene
  tho=Angle;
296 204 equemene
  q=-2;
297 209 equemene
  raie=Line;
298 204 equemene

299 226 equemene
  float bmx,db,b,h;
300 234 equemene
  float rp0,rps;
301 226 equemene
  float phi,phd;
302 228 equemene
  uint nh=0;
303 228 equemene
  float zp=0.e0f,fp=0.e0f;
304 199 equemene

305 199 equemene
  // Autosize for image
306 228 equemene
  bmx=1.25e0f*re;
307 199 equemene

308 217 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
309 201 equemene

310 199 equemene
  // set origin as center of image
311 228 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5.e-1f;
312 228 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5.e-1f;
313 199 equemene
  // angle extracted from cylindric symmetry
314 199 equemene
  phi=atanp(x,y);
315 199 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
316 199 equemene

317 228 equemene

318 204 equemene
  float up,vp,pp,us,vs,ps;
319 204 equemene

320 204 equemene
  // impact parameter
321 204 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
322 204 equemene
  // step of impact parameter;
323 209 equemene
  db=bmx/(float)(sizex);
324 204 equemene

325 228 equemene
  up=0.e0f;
326 228 equemene
  vp=1.e0f;
327 228 equemene
  pp=0.e0f;
328 199 equemene

329 199 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
330 226 equemene

331 218 equemene
  rps=fabs(b/us);
332 218 equemene
  rp0=rps;
333 199 equemene

334 204 equemene
  int ExitOnImpact=0;
335 199 equemene

336 199 equemene
  do
337 199 equemene
  {
338 199 equemene
     nh++;
339 199 equemene
     pp=ps;
340 199 equemene
     up=us;
341 199 equemene
     vp=vs;
342 227 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
343 218 equemene
     rps=fabs(b/us);
344 226 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>=ri)&&(rps<=re)?1:0;
345 199 equemene

346 228 equemene
  } while ((rps>=rs)&&(rps<=rp0)&&(ExitOnImpact==0)&&(nh<TRACKPOINTS));
347 199 equemene

348 228 equemene

349 199 equemene
  if (ExitOnImpact==1) {
350 228 equemene
     impact(phi,rps,b,tho,m,&zp,&fp,q,db,h,raie);
351 199 equemene
  }
352 199 equemene
  else
353 199 equemene
  {
354 228 equemene
     zp=0.e0f;
355 228 equemene
     fp=0.e0f;
356 199 equemene
  }
357 199 equemene

358 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
359 204 equemene

360 201 equemene
  zImage[yi+sizex*xi]=(float)zp;
361 234 equemene
  fImage[yi+sizex*xi]=(float)fp;
362 204 equemene
}
363 199 equemene

364 204 equemene
__kernel void Pixel(__global float *zImage,__global float *fImage,
365 204 equemene
                    __global float *Trajectories,__global int *IdLast,
366 224 equemene
                    uint ImpactParameter,
367 204 equemene
                    float Mass,float InternalRadius,
368 204 equemene
                    float ExternalRadius,float Angle,
369 209 equemene
                    int Line)
370 204 equemene
{
371 204 equemene
   uint xi=(uint)get_global_id(0);
372 204 equemene
   uint yi=(uint)get_global_id(1);
373 204 equemene
   uint sizex=(uint)get_global_size(0);
374 204 equemene
   uint sizey=(uint)get_global_size(1);
375 204 equemene

376 204 equemene
   // Perform trajectory for each pixel
377 204 equemene

378 226 equemene
  float m,ri,re,tho;
379 209 equemene
  int q,raie;
380 204 equemene

381 204 equemene
  m=Mass;
382 204 equemene
  ri=InternalRadius;
383 204 equemene
  re=ExternalRadius;
384 204 equemene
  tho=Angle;
385 204 equemene
  q=-2;
386 209 equemene
  raie=Line;
387 204 equemene

388 226 equemene
  float bmx,db,b,h;
389 226 equemene
  float phi,phd,php,nr,r;
390 234 equemene
  float zp=0.e0f,fp=0.e0f;
391 204 equemene

392 209 equemene
  // Autosize for image, 25% greater than external radius
393 234 equemene
  bmx=1.25e0f*re;
394 204 equemene

395 204 equemene
  // Angular step of integration
396 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
397 204 equemene

398 204 equemene
  // Step of Impact Parameter
399 234 equemene
  db=bmx/(2.e0f*(float)ImpactParameter);
400 204 equemene

401 204 equemene
  // set origin as center of image
402 234 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5.e-1f;
403 234 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5.e-1f;
404 204 equemene

405 204 equemene
  // angle extracted from cylindric symmetry
406 204 equemene
  phi=atanp(x,y);
407 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
408 204 equemene

409 204 equemene
  // Real Impact Parameter
410 204 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
411 204 equemene

412 204 equemene
  // Integer Impact Parameter
413 204 equemene
  uint bi=(uint)sqrt(x*x+y*y);
414 204 equemene

415 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
416 204 equemene

417 204 equemene
  if (bi<ImpactParameter)
418 204 equemene
  {
419 204 equemene
    do
420 204 equemene
    {
421 204 equemene
      php=phd+(float)HalfLap*PI;
422 204 equemene
      nr=php/h;
423 204 equemene
      ni=(int)nr;
424 204 equemene

425 204 equemene
      if (ni<IdLast[bi])
426 204 equemene
      {
427 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
428 204 equemene
      }
429 204 equemene
      else
430 204 equemene
      {
431 224 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
432 204 equemene
      }
433 234 equemene

434 204 equemene
      if ((r<=re)&&(r>=ri))
435 204 equemene
      {
436 204 equemene
        ExitOnImpact=1;
437 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
438 204 equemene
      }
439 234 equemene

440 204 equemene
      HalfLap++;
441 204 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
442 204 equemene

443 204 equemene
  }
444 204 equemene

445 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
446 204 equemene

447 204 equemene
  zImage[yi+sizex*xi]=zp;
448 204 equemene
  fImage[yi+sizex*xi]=fp;
449 204 equemene
}
450 204 equemene

451 204 equemene
__kernel void Circle(__global float *Trajectories,__global int *IdLast,
452 204 equemene
                     __global float *zImage,__global float *fImage,
453 204 equemene
                     float Mass,float InternalRadius,
454 204 equemene
                     float ExternalRadius,float Angle,
455 209 equemene
                     int Line)
456 204 equemene
{
457 234 equemene
   // Integer Impact Parameter ID
458 204 equemene
   int bi=get_global_id(0);
459 204 equemene
   // Integer points on circle
460 204 equemene
   int i=get_global_id(1);
461 204 equemene
   // Integer Impact Parameter Size (half of image)
462 204 equemene
   int bmaxi=get_global_size(0);
463 204 equemene
   // Integer Points on circle
464 204 equemene
   int imx=get_global_size(1);
465 204 equemene

466 204 equemene
   // Perform trajectory for each pixel
467 204 equemene

468 226 equemene
  float m,ri,re,tho;
469 209 equemene
  int q,raie;
470 204 equemene

471 204 equemene
  m=Mass;
472 204 equemene
  ri=InternalRadius;
473 204 equemene
  re=ExternalRadius;
474 204 equemene
  tho=Angle;
475 209 equemene
  raie=Line;
476 204 equemene

477 204 equemene
  float bmx,db,b,h;
478 226 equemene
  float phi,phd;
479 234 equemene
  float zp=0.e0f,fp=0.e0f;
480 204 equemene

481 204 equemene
  // Autosize for image
482 234 equemene
  bmx=1.25e0f*re;
483 204 equemene

484 204 equemene
  // Angular step of integration
485 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
486 204 equemene

487 204 equemene
  // impact parameter
488 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
489 224 equemene
  db=bmx/(2.e0f*(float)bmaxi);
490 204 equemene

491 234 equemene
  phi=2.e0f*PI/(float)imx*(float)i;
492 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
493 204 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
494 204 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
495 204 equemene

496 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
497 204 equemene
  float php,nr,r;
498 204 equemene

499 204 equemene
  do
500 204 equemene
  {
501 204 equemene
     php=phd+(float)HalfLap*PI;
502 204 equemene
     nr=php/h;
503 204 equemene
     ni=(int)nr;
504 204 equemene

505 204 equemene
     if (ni<IdLast[bi])
506 204 equemene
     {
507 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
508 204 equemene
     }
509 204 equemene
     else
510 204 equemene
     {
511 234 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
512 204 equemene
     }
513 234 equemene

514 204 equemene
     if ((r<=re)&&(r>=ri))
515 204 equemene
     {
516 234 equemene
        ExitOnImpact=1;
517 234 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
518 204 equemene
     }
519 234 equemene

520 204 equemene
     HalfLap++;
521 204 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
522 234 equemene

523 204 equemene
  zImage[yi+2*bmaxi*xi]=zp;
524 234 equemene
  fImage[yi+2*bmaxi*xi]=fp;
525 204 equemene

526 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
527 204 equemene

528 204 equemene
}
529 204 equemene

530 224 equemene
__kernel void Trajectory(__global float *Trajectories,__global int *IdLast,
531 204 equemene
                         float Mass,float InternalRadius,
532 204 equemene
                         float ExternalRadius,float Angle,
533 209 equemene
                         int Line)
534 204 equemene
{
535 234 equemene
  // Integer Impact Parameter ID
536 204 equemene
  int bi=get_global_id(0);
537 204 equemene
  // Integer Impact Parameter Size (half of image)
538 204 equemene
  int bmaxi=get_global_size(0);
539 204 equemene

540 204 equemene
  // Perform trajectory for each pixel
541 204 equemene

542 224 equemene
  float m,rs,re;
543 224 equemene

544 224 equemene
  m=Mass;
545 234 equemene
  rs=2.e0f*m;
546 224 equemene
  re=ExternalRadius;
547 224 equemene

548 224 equemene
  float bmx,b,h;
549 224 equemene
  int nh;
550 224 equemene

551 224 equemene
  // Autosize for image
552 234 equemene
  bmx=1.25e0f*re;
553 224 equemene

554 224 equemene
  // Angular step of integration
555 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
556 224 equemene

557 224 equemene
  // impact parameter
558 224 equemene
  b=(float)bi/(float)bmaxi*bmx;
559 224 equemene

560 224 equemene
  float up,vp,pp,us,vs,ps;
561 224 equemene

562 234 equemene
  up=0.e0f;
563 234 equemene
  vp=1.e0f;
564 234 equemene

565 234 equemene
  pp=0.e0f;
566 224 equemene
  nh=0;
567 224 equemene

568 224 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
569 234 equemene

570 224 equemene
  // b versus us
571 224 equemene
  float bvus=fabs(b/us);
572 224 equemene
  float bvus0=bvus;
573 224 equemene
  Trajectories[bi*TRACKPOINTS+nh]=bvus;
574 224 equemene

575 224 equemene
  do
576 224 equemene
  {
577 224 equemene
     nh++;
578 224 equemene
     pp=ps;
579 224 equemene
     up=us;
580 224 equemene
     vp=vs;
581 224 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
582 224 equemene
     bvus=fabs(b/us);
583 224 equemene
     Trajectories[bi*TRACKPOINTS+nh]=bvus;
584 224 equemene

585 224 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
586 224 equemene

587 224 equemene
  IdLast[bi]=nh;
588 224 equemene

589 224 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
590 234 equemene

591 224 equemene
}
592 224 equemene

593 225 equemene
__kernel void EachCircle(__global float *zImage,__global float *fImage,
594 225 equemene
                         float Mass,float InternalRadius,
595 225 equemene
                         float ExternalRadius,float Angle,
596 225 equemene
                         int Line)
597 224 equemene
{
598 234 equemene
   // Integer Impact Parameter ID
599 234 equemene
   uint bi=(uint)get_global_id(0);
600 234 equemene
   // Integer Impact Parameter Size (half of image)
601 234 equemene
   uint bmaxi=(uint)get_global_size(0);
602 224 equemene

603 234 equemene
  private float Trajectory[TRACKPOINTS];
604 224 equemene

605 209 equemene
  float m,rs,ri,re,tho;
606 209 equemene
  int raie,q;
607 204 equemene

608 204 equemene
  m=Mass;
609 234 equemene
  rs=2.e0f*m;
610 204 equemene
  ri=InternalRadius;
611 204 equemene
  re=ExternalRadius;
612 204 equemene
  tho=Angle;
613 204 equemene
  q=-2;
614 209 equemene
  raie=Line;
615 204 equemene

616 224 equemene
  float bmx,db,b,h;
617 234 equemene
  uint nh;
618 204 equemene

619 234 equemene

620 204 equemene
  // Autosize for image
621 224 equemene
  bmx=1.25e0f*re;
622 204 equemene

623 204 equemene
  // Angular step of integration
624 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
625 204 equemene

626 204 equemene
  // impact parameter
627 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
628 224 equemene
  db=bmx/(2.e0f*(float)bmaxi);
629 204 equemene

630 204 equemene
  float up,vp,pp,us,vs,ps;
631 204 equemene

632 234 equemene
  up=0.e0f;
633 234 equemene
  vp=1.e0f;
634 234 equemene

635 234 equemene
  pp=0.e0f;
636 204 equemene
  nh=0;
637 204 equemene

638 204 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
639 234 equemene

640 204 equemene
  // b versus us
641 204 equemene
  float bvus=fabs(b/us);
642 204 equemene
  float bvus0=bvus;
643 225 equemene
  Trajectory[nh]=bvus;
644 204 equemene

645 204 equemene
  do
646 204 equemene
  {
647 204 equemene
     nh++;
648 204 equemene
     pp=ps;
649 204 equemene
     up=us;
650 204 equemene
     vp=vs;
651 204 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
652 234 equemene
     bvus=(float)fabs(b/us);
653 225 equemene
     Trajectory[nh]=bvus;
654 204 equemene

655 204 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
656 204 equemene

657 234 equemene

658 225 equemene
  for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
659 225 equemene
     Trajectory[i]=0.e0f;
660 225 equemene
  }
661 225 equemene

662 204 equemene

663 234 equemene
  uint imx=(uint)(16*bi);
664 234 equemene

665 234 equemene
  for (uint i=0;i<imx;i++)
666 224 equemene
  {
667 234 equemene
     float zp=0.e0f,fp=0.e0f;
668 234 equemene
     float phi=2.e0f*PI/(float)imx*(float)i;
669 224 equemene
     float phd=atanp(cos(phi)*sin(tho),cos(tho));
670 224 equemene
     uint yi=(uint)((float)bi*sin(phi)+bmaxi);
671 224 equemene
     uint xi=(uint)((float)bi*cos(phi)+bmaxi);
672 224 equemene

673 234 equemene
     uint HalfLap=0,ExitOnImpact=0,ni;
674 224 equemene
     float php,nr,r;
675 224 equemene

676 224 equemene
     do
677 224 equemene
     {
678 224 equemene
        php=phd+(float)HalfLap*PI;
679 224 equemene
        nr=php/h;
680 224 equemene
        ni=(int)nr;
681 224 equemene

682 224 equemene
        if (ni<nh)
683 224 equemene
        {
684 234 equemene
           r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.e0f)+Trajectory[ni];
685 224 equemene
        }
686 224 equemene
        else
687 224 equemene
        {
688 225 equemene
           r=Trajectory[ni];
689 224 equemene
        }
690 234 equemene

691 224 equemene
        if ((r<=re)&&(r>=ri))
692 224 equemene
        {
693 224 equemene
           ExitOnImpact=1;
694 224 equemene
           impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
695 224 equemene
        }
696 234 equemene

697 224 equemene
        HalfLap++;
698 224 equemene

699 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
700 234 equemene

701 224 equemene
     zImage[yi+2*bmaxi*xi]=zp;
702 224 equemene
     fImage[yi+2*bmaxi*xi]=fp;
703 224 equemene

704 224 equemene
  }
705 224 equemene

706 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
707 234 equemene

708 199 equemene
}
709 225 equemene

710 225 equemene
__kernel void Original(__global float *zImage,__global float *fImage,
711 225 equemene
                       uint Size,float Mass,float InternalRadius,
712 225 equemene
                       float ExternalRadius,float Angle,
713 225 equemene
                       int Line)
714 225 equemene
{
715 225 equemene
   // Integer Impact Parameter Size (half of image)
716 225 equemene
   uint bmaxi=(uint)Size;
717 225 equemene

718 225 equemene
   float Trajectory[TRACKPOINTS];
719 225 equemene

720 225 equemene
   // Perform trajectory for each pixel
721 225 equemene

722 225 equemene
   float m,rs,ri,re,tho;
723 225 equemene
   int raie,q;
724 225 equemene

725 225 equemene
   m=Mass;
726 234 equemene
   rs=2.e0f*m;
727 225 equemene
   ri=InternalRadius;
728 225 equemene
   re=ExternalRadius;
729 225 equemene
   tho=Angle;
730 225 equemene
   q=-2;
731 225 equemene
   raie=Line;
732 225 equemene

733 225 equemene
   float bmx,db,b,h;
734 234 equemene
   uint nh;
735 225 equemene

736 225 equemene
   // Autosize for image
737 225 equemene
   bmx=1.25e0f*re;
738 225 equemene

739 225 equemene
   // Angular step of integration
740 225 equemene
   h=4.e0f*PI/(float)TRACKPOINTS;
741 225 equemene

742 234 equemene
   // Integer Impact Parameter ID
743 225 equemene
   for (int bi=0;bi<bmaxi;bi++)
744 225 equemene
   {
745 225 equemene
      // impact parameter
746 225 equemene
      b=(float)bi/(float)bmaxi*bmx;
747 225 equemene
      db=bmx/(2.e0f*(float)bmaxi);
748 225 equemene

749 225 equemene
      float up,vp,pp,us,vs,ps;
750 225 equemene

751 234 equemene
      up=0.e0f;
752 234 equemene
      vp=1.e0f;
753 234 equemene

754 234 equemene
      pp=0.e0f;
755 225 equemene
      nh=0;
756 225 equemene

757 225 equemene
      rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
758 234 equemene

759 225 equemene
      // b versus us
760 225 equemene
      float bvus=fabs(b/us);
761 225 equemene
      float bvus0=bvus;
762 225 equemene
      Trajectory[nh]=bvus;
763 225 equemene

764 225 equemene
      do
765 225 equemene
      {
766 225 equemene
         nh++;
767 225 equemene
         pp=ps;
768 225 equemene
         up=us;
769 225 equemene
         vp=vs;
770 225 equemene
         rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
771 225 equemene
         bvus=fabs(b/us);
772 225 equemene
         Trajectory[nh]=bvus;
773 225 equemene

774 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
775 225 equemene

776 225 equemene
      for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
777 225 equemene
         Trajectory[i]=0.e0f;
778 225 equemene
      }
779 225 equemene

780 225 equemene
      int imx=(int)(16*bi);
781 225 equemene

782 225 equemene
      for (int i=0;i<imx;i++)
783 225 equemene
      {
784 234 equemene
         float zp=0.e0f,fp=0.e0f;
785 225 equemene
         float phi=2.e0f*PI/(float)imx*(float)i;
786 225 equemene
         float phd=atanp(cos(phi)*sin(tho),cos(tho));
787 225 equemene
         uint yi=(uint)((float)bi*sin(phi)+bmaxi);
788 225 equemene
         uint xi=(uint)((float)bi*cos(phi)+bmaxi);
789 225 equemene

790 234 equemene
         uint HalfLap=0,ExitOnImpact=0,ni;
791 225 equemene
         float php,nr,r;
792 225 equemene

793 225 equemene
         do
794 225 equemene
         {
795 225 equemene
            php=phd+(float)HalfLap*PI;
796 225 equemene
            nr=php/h;
797 225 equemene
            ni=(int)nr;
798 225 equemene

799 225 equemene
            if (ni<nh)
800 225 equemene
            {
801 234 equemene
               r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.e0f)+Trajectory[ni];
802 225 equemene
            }
803 225 equemene
            else
804 225 equemene
            {
805 225 equemene
               r=Trajectory[ni];
806 225 equemene
            }
807 234 equemene

808 225 equemene
            if ((r<=re)&&(r>=ri))
809 225 equemene
            {
810 225 equemene
               ExitOnImpact=1;
811 225 equemene
               impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
812 225 equemene
            }
813 234 equemene

814 225 equemene
            HalfLap++;
815 234 equemene

816 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
817 234 equemene

818 225 equemene
         zImage[yi+2*bmaxi*xi]=zp;
819 225 equemene
         fImage[yi+2*bmaxi*xi]=fp;
820 234 equemene

821 225 equemene
      }
822 225 equemene

823 234 equemene
   }
824 234 equemene

825 225 equemene
   barrier(CLK_GLOBAL_MEM_FENCE);
826 234 equemene

827 225 equemene
}
828 211 equemene
"""
829 199 equemene
830 243 equemene
831 243 equemene
832 243 equemene
833 243 equemene
834 243 equemene
835 243 equemene
836 243 equemene
837 243 equemene
838 243 equemene
839 243 equemene
840 243 equemene
841 243 equemene
842 243 equemene
843 243 equemene
844 243 equemene
845 243 equemene
846 243 equemene
847 243 equemene
848 243 equemene
849 243 equemene
850 243 equemene
851 243 equemene
852 243 equemene
853 243 equemene
854 243 equemene
855 243 equemene
856 243 equemene
857 243 equemene
858 243 equemene
859 243 equemene
860 243 equemene
861 243 equemene
862 243 equemene
863 243 equemene
864 243 equemene
865 243 equemene
866 243 equemene
867 243 equemene
868 243 equemene
869 243 equemene
870 243 equemene
871 243 equemene
872 243 equemene
873 243 equemene
874 243 equemene
875 243 equemene
876 243 equemene
877 243 equemene
878 243 equemene
879 243 equemene
880 243 equemene
881 243 equemene
882 243 equemene
883 243 equemene
884 243 equemene
885 243 equemene
886 243 equemene
887 243 equemene
888 243 equemene
889 243 equemene
890 243 equemene
891 243 equemene
892 243 equemene
893 243 equemene
894 243 equemene
895 243 equemene
896 243 equemene
897 243 equemene
898 243 equemene
899 243 equemene
900 243 equemene
901 217 equemene
def KernelCodeCuda():
902 217 equemene
    BlobCUDA= """
903 217 equemene

904 217 equemene
#define PI (float)3.14159265359
905 217 equemene
#define nbr 256
906 217 equemene

907 217 equemene
#define EINSTEIN 0
908 217 equemene
#define NEWTON 1
909 217 equemene

910 224 equemene
#ifdef SETTRACKPOINTS
911 224 equemene
#define TRACKPOINTS SETTRACKPOINTS
912 224 equemene
#else
913 224 equemene
#define TRACKPOINTS
914 224 equemene
#endif
915 217 equemene
__device__ float nothing(float x)
916 217 equemene
{
917 217 equemene
  return(x);
918 217 equemene
}
919 217 equemene

920 217 equemene
__device__ float atanp(float x,float y)
921 217 equemene
{
922 217 equemene
  float angle;
923 217 equemene

924 217 equemene
  angle=atan2(y,x);
925 217 equemene

926 217 equemene
  if (angle<0.e0f)
927 217 equemene
    {
928 217 equemene
      angle+=(float)2.e0f*PI;
929 217 equemene
    }
930 217 equemene

931 217 equemene
  return(angle);
932 217 equemene
}
933 217 equemene

934 217 equemene
__device__ float f(float v)
935 217 equemene
{
936 217 equemene
  return(v);
937 217 equemene
}
938 217 equemene

939 217 equemene
#if PHYSICS == NEWTON
940 217 equemene
__device__ float g(float u,float m,float b)
941 217 equemene
{
942 217 equemene
  return (-u);
943 217 equemene
}
944 217 equemene
#else
945 217 equemene
__device__ float g(float u,float m,float b)
946 217 equemene
{
947 217 equemene
  return (3.e0f*m/b*pow(u,2)-u);
948 217 equemene
}
949 217 equemene
#endif
950 217 equemene

951 217 equemene
__device__ void calcul(float *us,float *vs,float up,float vp,
952 234 equemene
                       float h,float m,float b)
953 217 equemene
{
954 217 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
955 217 equemene

956 217 equemene
  c0=h*f(vp);
957 217 equemene
  c1=h*f(vp+c0/2.);
958 217 equemene
  c2=h*f(vp+c1/2.);
959 217 equemene
  c3=h*f(vp+c2);
960 217 equemene
  d0=h*g(up,m,b);
961 217 equemene
  d1=h*g(up+d0/2.,m,b);
962 217 equemene
  d2=h*g(up+d1/2.,m,b);
963 217 equemene
  d3=h*g(up+d2,m,b);
964 217 equemene

965 217 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
966 217 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
967 217 equemene
}
968 217 equemene

969 217 equemene
__device__ void rungekutta(float *ps,float *us,float *vs,
970 234 equemene
                           float pp,float up,float vp,
971 234 equemene
                           float h,float m,float b)
972 217 equemene
{
973 217 equemene
  calcul(us,vs,up,vp,h,m,b);
974 217 equemene
  *ps=pp+h;
975 217 equemene
}
976 217 equemene

977 217 equemene
__device__ float decalage_spectral(float r,float b,float phi,
978 234 equemene
                                   float tho,float m)
979 217 equemene
{
980 217 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
981 217 equemene
}
982 217 equemene

983 217 equemene
__device__ float spectre(float rf,int q,float b,float db,
984 234 equemene
                         float h,float r,float m,float bss)
985 217 equemene
{
986 217 equemene
  float flx;
987 217 equemene

988 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
989 221 equemene
  flx=exp(q*log(r/m)+4.*log(rf))*b*db*h;
990 217 equemene
  return(flx);
991 217 equemene
}
992 217 equemene

993 217 equemene
__device__ float spectre_cn(float rf32,float b32,float db32,
994 234 equemene
                            float h32,float r32,float m32,float bss32)
995 217 equemene
{
996 234 equemene

997 217 equemene
#define MYFLOAT float
998 217 equemene

999 217 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
1000 217 equemene
  MYFLOAT b=(MYFLOAT)(b32);
1001 217 equemene
  MYFLOAT db=(MYFLOAT)(db32);
1002 217 equemene
  MYFLOAT h=(MYFLOAT)(h32);
1003 217 equemene
  MYFLOAT r=(MYFLOAT)(r32);
1004 217 equemene
  MYFLOAT m=(MYFLOAT)(m32);
1005 217 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
1006 217 equemene

1007 217 equemene
  MYFLOAT flx;
1008 217 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
1009 217 equemene
  int fi,posfreq;
1010 217 equemene

1011 217 equemene
#define planck 6.62e-34
1012 217 equemene
#define k 1.38e-23
1013 217 equemene
#define c2 9.e16
1014 217 equemene
#define temp 3.e7
1015 217 equemene
#define m_point 1.
1016 217 equemene

1017 217 equemene
#define lplanck (log(6.62)-34.*log(10.))
1018 217 equemene
#define lk (log(1.38)-23.*log(10.))
1019 217 equemene
#define lc2 (log(9.)+16.*log(10.))
1020 217 equemene

1021 217 equemene
  MYFLOAT v=1.-3./r;
1022 217 equemene

1023 217 equemene
  qu=1./sqrt((1.-3./r)*r)*(sqrt(r)-sqrt(6.)+sqrt(3.)/2.*log((sqrt(r)+sqrt(3.))/(sqrt(r)-sqrt(3.))* 0.17157287525380988 ));
1024 217 equemene

1025 217 equemene
  temp_em=temp*sqrt(m)*exp(0.25*log(m_point)-0.75*log(r)-0.125*log(v)+0.25*log(fabs(qu)));
1026 217 equemene

1027 217 equemene
  flux_int=0.;
1028 217 equemene
  flx=0.;
1029 217 equemene

1030 217 equemene
  for (fi=0;fi<nbr;fi++)
1031 217 equemene
    {
1032 217 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
1033 217 equemene
      nu_rec=nu_em*rf;
1034 217 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
1035 217 equemene
      if ((posfreq>0)&&(posfreq<nbr))
1036 234 equemene
        {
1037 217 equemene
          // Initial version
1038 234 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
1039 217 equemene
          // Version with log used
1040 234 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
1041 234 equemene
          // flux_int*=pow(rf,3)*b*db*h;
1042 234 equemene
          //flux_int*=exp(3.*log(rf))*b*db*h;
1043 234 equemene
          flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.)*exp(3.*log(rf))*b*db*h;
1044 217 equemene

1045 234 equemene
          flx+=flux_int;
1046 234 equemene
        }
1047 217 equemene
    }
1048 217 equemene

1049 217 equemene
  return((float)(flx));
1050 217 equemene
}
1051 217 equemene

1052 217 equemene
__device__ void impact(float phi,float r,float b,float tho,float m,
1053 234 equemene
                       float *zp,float *fp,
1054 234 equemene
                       int q,float db,
1055 234 equemene
                       float h,int raie)
1056 217 equemene
{
1057 217 equemene
  float flx,rf,bss;
1058 217 equemene

1059 217 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
1060 217 equemene

1061 217 equemene
  if (raie==0)
1062 217 equemene
    {
1063 217 equemene
      bss=1.e19;
1064 217 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
1065 217 equemene
    }
1066 217 equemene
  else
1067 234 equemene
    {
1068 217 equemene
      bss=2.;
1069 217 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
1070 217 equemene
    }
1071 234 equemene

1072 217 equemene
  *zp=1./rf;
1073 217 equemene
  *fp=flx;
1074 217 equemene

1075 217 equemene
}
1076 217 equemene

1077 217 equemene
__global__ void EachPixel(float *zImage,float *fImage,
1078 217 equemene
                          float Mass,float InternalRadius,
1079 217 equemene
                          float ExternalRadius,float Angle,
1080 217 equemene
                          int Line)
1081 217 equemene
{
1082 218 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1083 218 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1084 217 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1085 217 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1086 217 equemene

1087 243 equemene

1088 217 equemene
   // Perform trajectory for each pixel, exit on hit
1089 217 equemene

1090 217 equemene
  float m,rs,ri,re,tho;
1091 217 equemene
  int q,raie;
1092 217 equemene

1093 217 equemene
  m=Mass;
1094 217 equemene
  rs=2.*m;
1095 217 equemene
  ri=InternalRadius;
1096 217 equemene
  re=ExternalRadius;
1097 217 equemene
  tho=Angle;
1098 217 equemene
  q=-2;
1099 217 equemene
  raie=Line;
1100 217 equemene

1101 243 equemene
  float bmx,db,b,h;
1102 218 equemene
  float rp0,rpp,rps;
1103 243 equemene
  float phi,phd;
1104 217 equemene
  int nh;
1105 217 equemene
  float zp,fp;
1106 217 equemene

1107 217 equemene
  // Autosize for image
1108 217 equemene
  bmx=1.25*re;
1109 217 equemene
  b=0.;
1110 217 equemene

1111 217 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1112 217 equemene

1113 217 equemene
  // set origin as center of image
1114 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1115 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1116 217 equemene
  // angle extracted from cylindric symmetry
1117 217 equemene
  phi=atanp(x,y);
1118 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1119 217 equemene

1120 217 equemene
  float up,vp,pp,us,vs,ps;
1121 217 equemene

1122 217 equemene
  // impact parameter
1123 217 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
1124 217 equemene
  // step of impact parameter;
1125 217 equemene
//  db=bmx/(float)(sizex/2);
1126 217 equemene
  db=bmx/(float)(sizex);
1127 217 equemene

1128 217 equemene
  up=0.;
1129 217 equemene
  vp=1.;
1130 217 equemene
  pp=0.;
1131 217 equemene
  nh=0;
1132 217 equemene

1133 217 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1134 234 equemene

1135 218 equemene
  rps=fabs(b/us);
1136 218 equemene
  rp0=rps;
1137 217 equemene

1138 217 equemene
  int ExitOnImpact=0;
1139 217 equemene

1140 217 equemene
  do
1141 217 equemene
  {
1142 217 equemene
     nh++;
1143 217 equemene
     pp=ps;
1144 217 equemene
     up=us;
1145 217 equemene
     vp=vs;
1146 218 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1147 234 equemene
     rpp=rps;
1148 218 equemene
     rps=fabs(b/us);
1149 218 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>ri)&&(rps<re)?1:0;
1150 217 equemene

1151 218 equemene
  } while ((rps>=rs)&&(rps<=rp0)&&(ExitOnImpact==0));
1152 217 equemene

1153 217 equemene
  if (ExitOnImpact==1) {
1154 218 equemene
     impact(phi,rpp,b,tho,m,&zp,&fp,q,db,h,raie);
1155 217 equemene
  }
1156 217 equemene
  else
1157 217 equemene
  {
1158 234 equemene
     zp=0.e0f;
1159 234 equemene
     fp=0.e0f;
1160 217 equemene
  }
1161 217 equemene

1162 218 equemene
  __syncthreads();
1163 218 equemene

1164 217 equemene
  zImage[yi+sizex*xi]=(float)zp;
1165 217 equemene
  fImage[yi+sizex*xi]=(float)fp;
1166 217 equemene
}
1167 217 equemene

1168 217 equemene
__global__ void Pixel(float *zImage,float *fImage,
1169 217 equemene
                      float *Trajectories,int *IdLast,
1170 224 equemene
                      uint ImpactParameter,
1171 217 equemene
                      float Mass,float InternalRadius,
1172 217 equemene
                      float ExternalRadius,float Angle,
1173 217 equemene
                      int Line)
1174 217 equemene
{
1175 219 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1176 219 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1177 219 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1178 219 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1179 217 equemene

1180 217 equemene
  // Perform trajectory for each pixel
1181 217 equemene

1182 243 equemene
  float m,ri,re,tho;
1183 217 equemene
  int q,raie;
1184 217 equemene

1185 217 equemene
  m=Mass;
1186 217 equemene
  ri=InternalRadius;
1187 217 equemene
  re=ExternalRadius;
1188 217 equemene
  tho=Angle;
1189 217 equemene
  q=-2;
1190 217 equemene
  raie=Line;
1191 217 equemene

1192 243 equemene
  float bmx,db,b,h;
1193 243 equemene
  float phi,phd,php,nr,r;
1194 217 equemene
  float zp=0,fp=0;
1195 217 equemene
  // Autosize for image, 25% greater than external radius
1196 234 equemene
  bmx=1.25e0f*re;
1197 217 equemene

1198 217 equemene
  // Angular step of integration
1199 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1200 217 equemene

1201 217 equemene
  // Step of Impact Parameter
1202 234 equemene
  db=bmx/(2.e0f*(float)ImpactParameter);
1203 217 equemene

1204 217 equemene
  // set origin as center of image
1205 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1206 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1207 217 equemene
  // angle extracted from cylindric symmetry
1208 217 equemene
  phi=atanp(x,y);
1209 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1210 217 equemene

1211 217 equemene
  // Real Impact Parameter
1212 217 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
1213 217 equemene

1214 217 equemene
  // Integer Impact Parameter
1215 217 equemene
  uint bi=(uint)sqrt(x*x+y*y);
1216 217 equemene

1217 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1218 217 equemene

1219 217 equemene
  if (bi<ImpactParameter)
1220 217 equemene
  {
1221 217 equemene
    do
1222 217 equemene
    {
1223 217 equemene
      php=phd+(float)HalfLap*PI;
1224 217 equemene
      nr=php/h;
1225 217 equemene
      ni=(int)nr;
1226 217 equemene

1227 217 equemene
      if (ni<IdLast[bi])
1228 217 equemene
      {
1229 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1230 217 equemene
      }
1231 217 equemene
      else
1232 217 equemene
      {
1233 224 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1234 217 equemene
      }
1235 234 equemene

1236 217 equemene
      if ((r<=re)&&(r>=ri))
1237 217 equemene
      {
1238 217 equemene
        ExitOnImpact=1;
1239 217 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1240 217 equemene
      }
1241 234 equemene

1242 217 equemene
      HalfLap++;
1243 217 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
1244 217 equemene

1245 217 equemene
  }
1246 217 equemene

1247 217 equemene
  zImage[yi+sizex*xi]=zp;
1248 217 equemene
  fImage[yi+sizex*xi]=fp;
1249 217 equemene
}
1250 217 equemene

1251 217 equemene
__global__ void Circle(float *Trajectories,int *IdLast,
1252 217 equemene
                       float *zImage,float *fImage,
1253 217 equemene
                       float Mass,float InternalRadius,
1254 217 equemene
                       float ExternalRadius,float Angle,
1255 217 equemene
                       int Line)
1256 217 equemene
{
1257 234 equemene
   // Integer Impact Parameter ID
1258 219 equemene
   int bi=blockIdx.x*blockDim.x+threadIdx.x;
1259 217 equemene
   // Integer points on circle
1260 219 equemene
   int i=blockIdx.y*blockDim.y+threadIdx.y;
1261 217 equemene
   // Integer Impact Parameter Size (half of image)
1262 217 equemene
   int bmaxi=gridDim.x*blockDim.x;
1263 217 equemene
   // Integer Points on circle
1264 217 equemene
   int imx=gridDim.y*blockDim.y;
1265 217 equemene

1266 217 equemene
   // Perform trajectory for each pixel
1267 217 equemene

1268 243 equemene
  float m,ri,re,tho;
1269 217 equemene
  int q,raie;
1270 217 equemene

1271 217 equemene
  m=Mass;
1272 217 equemene
  ri=InternalRadius;
1273 217 equemene
  re=ExternalRadius;
1274 217 equemene
  tho=Angle;
1275 217 equemene
  raie=Line;
1276 217 equemene

1277 217 equemene
  float bmx,db,b,h;
1278 243 equemene
  float phi,phd;
1279 217 equemene
  float zp=0,fp=0;
1280 217 equemene

1281 217 equemene
  // Autosize for image
1282 234 equemene
  bmx=1.25e0f*re;
1283 217 equemene

1284 217 equemene
  // Angular step of integration
1285 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1286 217 equemene

1287 217 equemene
  // impact parameter
1288 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1289 234 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1290 217 equemene

1291 234 equemene
  phi=2.e0f*PI/(float)imx*(float)i;
1292 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1293 217 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
1294 217 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
1295 217 equemene

1296 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1297 217 equemene
  float php,nr,r;
1298 217 equemene

1299 217 equemene
  do
1300 217 equemene
  {
1301 217 equemene
     php=phd+(float)HalfLap*PI;
1302 217 equemene
     nr=php/h;
1303 217 equemene
     ni=(int)nr;
1304 217 equemene

1305 217 equemene
     if (ni<IdLast[bi])
1306 217 equemene
     {
1307 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1308 217 equemene
     }
1309 217 equemene
     else
1310 217 equemene
     {
1311 234 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1312 217 equemene
     }
1313 234 equemene

1314 217 equemene
     if ((r<=re)&&(r>=ri))
1315 217 equemene
     {
1316 234 equemene
        ExitOnImpact=1;
1317 234 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1318 217 equemene
     }
1319 234 equemene

1320 217 equemene
     HalfLap++;
1321 217 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
1322 234 equemene

1323 217 equemene
  zImage[yi+2*bmaxi*xi]=zp;
1324 234 equemene
  fImage[yi+2*bmaxi*xi]=fp;
1325 217 equemene

1326 217 equemene
}
1327 217 equemene

1328 224 equemene
__global__ void Trajectory(float *Trajectories,int *IdLast,
1329 217 equemene
                           float Mass,float InternalRadius,
1330 217 equemene
                           float ExternalRadius,float Angle,
1331 217 equemene
                           int Line)
1332 217 equemene
{
1333 234 equemene
  // Integer Impact Parameter ID
1334 219 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1335 217 equemene
  // Integer Impact Parameter Size (half of image)
1336 217 equemene
  int bmaxi=gridDim.x*blockDim.x;
1337 217 equemene

1338 217 equemene
  // Perform trajectory for each pixel
1339 217 equemene

1340 243 equemene
  float m,rs,re;
1341 217 equemene

1342 217 equemene
  m=Mass;
1343 234 equemene
  rs=2.e0f*m;
1344 217 equemene
  re=ExternalRadius;
1345 217 equemene

1346 243 equemene
  float bmx,b,h;
1347 217 equemene
  int nh;
1348 217 equemene

1349 217 equemene
  // Autosize for image
1350 234 equemene
  bmx=1.25e0f*re;
1351 217 equemene

1352 217 equemene
  // Angular step of integration
1353 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1354 217 equemene

1355 217 equemene
  // impact parameter
1356 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1357 217 equemene

1358 217 equemene
  float up,vp,pp,us,vs,ps;
1359 217 equemene

1360 234 equemene
  up=0.e0f;
1361 234 equemene
  vp=1.e0f;
1362 234 equemene
  pp=0.e0f;
1363 217 equemene
  nh=0;
1364 217 equemene

1365 217 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1366 234 equemene

1367 217 equemene
  // b versus us
1368 217 equemene
  float bvus=fabs(b/us);
1369 217 equemene
  float bvus0=bvus;
1370 224 equemene
  Trajectories[bi*TRACKPOINTS+nh]=bvus;
1371 217 equemene

1372 217 equemene
  do
1373 217 equemene
  {
1374 217 equemene
     nh++;
1375 217 equemene
     pp=ps;
1376 217 equemene
     up=us;
1377 217 equemene
     vp=vs;
1378 217 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1379 217 equemene
     bvus=fabs(b/us);
1380 224 equemene
     Trajectories[bi*TRACKPOINTS+nh]=bvus;
1381 217 equemene

1382 217 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1383 217 equemene

1384 217 equemene
  IdLast[bi]=nh;
1385 217 equemene

1386 217 equemene
}
1387 224 equemene

1388 225 equemene
__global__ void EachCircle(float *zImage,float *fImage,
1389 225 equemene
                           float Mass,float InternalRadius,
1390 225 equemene
                           float ExternalRadius,float Angle,
1391 225 equemene
                           int Line)
1392 224 equemene
{
1393 234 equemene
  // Integer Impact Parameter ID
1394 224 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1395 224 equemene

1396 224 equemene
  // Integer Impact Parameter Size (half of image)
1397 224 equemene
  int bmaxi=gridDim.x*blockDim.x;
1398 224 equemene

1399 225 equemene
  float Trajectory[2048];
1400 224 equemene

1401 224 equemene
  // Perform trajectory for each pixel
1402 224 equemene

1403 224 equemene
  float m,rs,ri,re,tho;
1404 224 equemene
  int raie,q;
1405 224 equemene

1406 224 equemene
  m=Mass;
1407 224 equemene
  rs=2.*m;
1408 224 equemene
  ri=InternalRadius;
1409 224 equemene
  re=ExternalRadius;
1410 224 equemene
  tho=Angle;
1411 224 equemene
  q=-2;
1412 224 equemene
  raie=Line;
1413 224 equemene

1414 224 equemene
  float bmx,db,b,h;
1415 224 equemene
  int nh;
1416 224 equemene

1417 224 equemene
  // Autosize for image
1418 224 equemene
  bmx=1.25e0f*re;
1419 224 equemene

1420 224 equemene
  // Angular step of integration
1421 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1422 224 equemene

1423 224 equemene
  // impact parameter
1424 224 equemene
  b=(float)bi/(float)bmaxi*bmx;
1425 224 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1426 224 equemene

1427 224 equemene
  float up,vp,pp,us,vs,ps;
1428 224 equemene

1429 224 equemene
  up=0.;
1430 224 equemene
  vp=1.;
1431 224 equemene
  pp=0.;
1432 224 equemene
  nh=0;
1433 224 equemene

1434 224 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1435 234 equemene

1436 224 equemene
  // b versus us
1437 224 equemene
  float bvus=fabs(b/us);
1438 224 equemene
  float bvus0=bvus;
1439 225 equemene
  Trajectory[nh]=bvus;
1440 224 equemene

1441 224 equemene
  do
1442 224 equemene
  {
1443 224 equemene
     nh++;
1444 224 equemene
     pp=ps;
1445 224 equemene
     up=us;
1446 224 equemene
     vp=vs;
1447 224 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1448 224 equemene
     bvus=fabs(b/us);
1449 225 equemene
     Trajectory[nh]=bvus;
1450 224 equemene

1451 224 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1452 224 equemene

1453 224 equemene
  int imx=(int)(16*bi);
1454 224 equemene

1455 224 equemene
  for (int i=0;i<imx;i++)
1456 224 equemene
  {
1457 224 equemene
     float zp=0,fp=0;
1458 224 equemene
     float phi=2.*PI/(float)imx*(float)i;
1459 224 equemene
     float phd=atanp(cos(phi)*sin(tho),cos(tho));
1460 224 equemene
     uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1461 224 equemene
     uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1462 224 equemene

1463 224 equemene
     int HalfLap=0,ExitOnImpact=0,ni;
1464 224 equemene
     float php,nr,r;
1465 224 equemene

1466 224 equemene
     do
1467 224 equemene
     {
1468 224 equemene
        php=phd+(float)HalfLap*PI;
1469 224 equemene
        nr=php/h;
1470 224 equemene
        ni=(int)nr;
1471 224 equemene

1472 224 equemene
        if (ni<nh)
1473 224 equemene
        {
1474 225 equemene
           r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1475 224 equemene
        }
1476 224 equemene
        else
1477 224 equemene
        {
1478 225 equemene
           r=Trajectory[ni];
1479 224 equemene
        }
1480 234 equemene

1481 224 equemene
        if ((r<=re)&&(r>=ri))
1482 224 equemene
        {
1483 224 equemene
           ExitOnImpact=1;
1484 224 equemene
           impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1485 224 equemene
        }
1486 234 equemene

1487 224 equemene
        HalfLap++;
1488 224 equemene

1489 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
1490 224 equemene

1491 224 equemene
   __syncthreads();
1492 224 equemene

1493 224 equemene
   zImage[yi+2*bmaxi*xi]=zp;
1494 224 equemene
   fImage[yi+2*bmaxi*xi]=fp;
1495 224 equemene

1496 224 equemene
  }
1497 234 equemene

1498 224 equemene
}
1499 225 equemene

1500 225 equemene
__global__ void Original(float *zImage,float *fImage,
1501 225 equemene
                         uint Size,float Mass,float InternalRadius,
1502 225 equemene
                         float ExternalRadius,float Angle,
1503 225 equemene
                         int Line)
1504 225 equemene
{
1505 225 equemene
   // Integer Impact Parameter Size (half of image)
1506 225 equemene
   uint bmaxi=(uint)Size;
1507 225 equemene

1508 225 equemene
   float Trajectory[TRACKPOINTS];
1509 225 equemene

1510 225 equemene
   // Perform trajectory for each pixel
1511 225 equemene

1512 225 equemene
   float m,rs,ri,re,tho;
1513 225 equemene
   int raie,q;
1514 225 equemene

1515 225 equemene
   m=Mass;
1516 234 equemene
   rs=2.e0f*m;
1517 225 equemene
   ri=InternalRadius;
1518 225 equemene
   re=ExternalRadius;
1519 225 equemene
   tho=Angle;
1520 225 equemene
   q=-2;
1521 225 equemene
   raie=Line;
1522 225 equemene

1523 225 equemene
   float bmx,db,b,h;
1524 225 equemene
   int nh;
1525 225 equemene

1526 225 equemene
   // Autosize for image
1527 225 equemene
   bmx=1.25e0f*re;
1528 225 equemene

1529 225 equemene
   // Angular step of integration
1530 225 equemene
   h=4.e0f*PI/(float)TRACKPOINTS;
1531 225 equemene

1532 234 equemene
   // Integer Impact Parameter ID
1533 225 equemene
   for (int bi=0;bi<bmaxi;bi++)
1534 225 equemene
   {
1535 225 equemene
      // impact parameter
1536 225 equemene
      b=(float)bi/(float)bmaxi*bmx;
1537 225 equemene
      db=bmx/(2.e0f*(float)bmaxi);
1538 225 equemene

1539 225 equemene
      float up,vp,pp,us,vs,ps;
1540 225 equemene

1541 225 equemene
      up=0.;
1542 225 equemene
      vp=1.;
1543 225 equemene
      pp=0.;
1544 225 equemene
      nh=0;
1545 225 equemene

1546 225 equemene
      rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1547 234 equemene

1548 225 equemene
      // b versus us
1549 225 equemene
      float bvus=fabs(b/us);
1550 225 equemene
      float bvus0=bvus;
1551 225 equemene
      Trajectory[nh]=bvus;
1552 225 equemene

1553 225 equemene
      do
1554 225 equemene
      {
1555 225 equemene
         nh++;
1556 225 equemene
         pp=ps;
1557 225 equemene
         up=us;
1558 225 equemene
         vp=vs;
1559 225 equemene
         rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1560 225 equemene
         bvus=fabs(b/us);
1561 225 equemene
         Trajectory[nh]=bvus;
1562 225 equemene

1563 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
1564 225 equemene

1565 225 equemene
      for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
1566 225 equemene
         Trajectory[i]=0.e0f;
1567 225 equemene
      }
1568 225 equemene

1569 225 equemene
      int imx=(int)(16*bi);
1570 225 equemene

1571 225 equemene
      for (int i=0;i<imx;i++)
1572 225 equemene
      {
1573 225 equemene
         float zp=0,fp=0;
1574 225 equemene
         float phi=2.e0f*PI/(float)imx*(float)i;
1575 225 equemene
         float phd=atanp(cos(phi)*sin(tho),cos(tho));
1576 225 equemene
         uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1577 225 equemene
         uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1578 225 equemene

1579 225 equemene
         int HalfLap=0,ExitOnImpact=0,ni;
1580 225 equemene
         float php,nr,r;
1581 225 equemene

1582 225 equemene
         do
1583 225 equemene
         {
1584 225 equemene
            php=phd+(float)HalfLap*PI;
1585 225 equemene
            nr=php/h;
1586 225 equemene
            ni=(int)nr;
1587 225 equemene

1588 225 equemene
            if (ni<nh)
1589 225 equemene
            {
1590 225 equemene
               r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1591 225 equemene
            }
1592 225 equemene
            else
1593 225 equemene
            {
1594 225 equemene
               r=Trajectory[ni];
1595 225 equemene
            }
1596 234 equemene

1597 225 equemene
            if ((r<=re)&&(r>=ri))
1598 225 equemene
            {
1599 225 equemene
               ExitOnImpact=1;
1600 225 equemene
               impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1601 225 equemene
            }
1602 234 equemene

1603 225 equemene
            HalfLap++;
1604 234 equemene

1605 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
1606 234 equemene

1607 225 equemene
         zImage[yi+2*bmaxi*xi]=zp;
1608 225 equemene
         fImage[yi+2*bmaxi*xi]=fp;
1609 234 equemene

1610 225 equemene
      }
1611 225 equemene

1612 234 equemene
   }
1613 234 equemene

1614 225 equemene
}
1615 217 equemene
"""
1616 217 equemene
    return(BlobCUDA)
1617 234 equemene
1618 211 equemene
# def ImageOutput(sigma,prefix):
1619 211 equemene
#     from PIL import Image
1620 211 equemene
#     Max=sigma.max()
1621 211 equemene
#     Min=sigma.min()
1622 211 equemene
#     # Normalize value as 8bits Integer
1623 211 equemene
#     SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
1624 211 equemene
#     image = Image.fromarray(SigmaInt)
1625 211 equemene
#     image.save("%s.jpg" % prefix)
1626 211 equemene
1627 211 equemene
def ImageOutput(sigma,prefix,Colors):
1628 263 equemene
    try:
1629 263 equemene
        import matplotlib.pyplot as plt
1630 263 equemene
        start_time=time.time()
1631 263 equemene
        if Colors == 'Red2Yellow':
1632 263 equemene
            plt.imsave("%s.png" % prefix, sigma, cmap='afmhot')
1633 263 equemene
        else:
1634 263 equemene
            plt.imsave("%s.png" % prefix, sigma, cmap='Greys_r')
1635 263 equemene
        save_time = time.time()-start_time
1636 263 equemene
        print("Save image as %s.png file" % prefix)
1637 263 equemene
        print("Save Time : %f" % save_time)
1638 263 equemene
    except:
1639 263 equemene
        from PIL import Image
1640 263 equemene
        start_time=time.time()
1641 263 equemene
        Max = sigma.max()
1642 263 equemene
        Min = sigma.min()
1643 263 equemene
        # Normalize value as 8bits Integer
1644 263 equemene
        SigmaInt = (255 * (sigma - Min) / (Max - Min)).astype("uint8")
1645 263 equemene
        image = Image.fromarray(SigmaInt)
1646 263 equemene
        image.save("%s.jpg" % prefix)
1647 263 equemene
        save_time = time.time()-start_time
1648 263 equemene
        print("Save image as %s.png file" % prefix)
1649 263 equemene
        print("Save Time : %f" % save_time)
1650 263 equemene
1651 204 equemene
def BlackHoleCL(zImage,fImage,InputCL):
1652 199 equemene
1653 199 equemene
    kernel_params = {}
1654 199 equemene
1655 204 equemene
    Device=InputCL['Device']
1656 204 equemene
    GpuStyle=InputCL['GpuStyle']
1657 204 equemene
    VariableType=InputCL['VariableType']
1658 204 equemene
    Size=InputCL['Size']
1659 204 equemene
    Mass=InputCL['Mass']
1660 204 equemene
    InternalRadius=InputCL['InternalRadius']
1661 204 equemene
    ExternalRadius=InputCL['ExternalRadius']
1662 204 equemene
    Angle=InputCL['Angle']
1663 204 equemene
    Method=InputCL['Method']
1664 204 equemene
    TrackPoints=InputCL['TrackPoints']
1665 211 equemene
    Physics=InputCL['Physics']
1666 237 equemene
    NoImage=InputCL['NoImage']
1667 257 equemene
    TrackSave=InputCL['TrackSave']
1668 204 equemene
1669 211 equemene
    PhysicsList=DictionariesAPI()
1670 211 equemene
1671 204 equemene
    if InputCL['BlackBody']:
1672 209 equemene
        # Spectrum is Black Body one
1673 209 equemene
        Line=0
1674 204 equemene
    else:
1675 209 equemene
        # Spectrum is Monochromatic Line one
1676 209 equemene
        Line=1
1677 204 equemene
1678 217 equemene
    Trajectories=numpy.zeros((int(InputCL['Size']/2),InputCL['TrackPoints']),dtype=numpy.float32)
1679 217 equemene
    IdLast=numpy.zeros(int(InputCL['Size']/2),dtype=numpy.int32)
1680 204 equemene
1681 199 equemene
    # Je detecte un peripherique GPU dans la liste des peripheriques
1682 199 equemene
    Id=0
1683 199 equemene
    HasXPU=False
1684 199 equemene
    for platform in cl.get_platforms():
1685 199 equemene
        for device in platform.get_devices():
1686 199 equemene
            if Id==Device:
1687 234 equemene
                PF4XPU=platform.name
1688 199 equemene
                XPU=device
1689 217 equemene
                print("CPU/GPU selected: ",device.name.lstrip())
1690 199 equemene
                HasXPU=True
1691 199 equemene
            Id+=1
1692 199 equemene
1693 199 equemene
    if HasXPU==False:
1694 217 equemene
        print("No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1))
1695 234 equemene
        sys.exit()
1696 234 equemene
1697 199 equemene
    ctx = cl.Context([XPU])
1698 199 equemene
    queue = cl.CommandQueue(ctx,
1699 199 equemene
                            properties=cl.command_queue_properties.PROFILING_ENABLE)
1700 199 equemene
1701 228 equemene
    BuildOptions="-DPHYSICS=%i -DSETTRACKPOINTS=%i " % (PhysicsList[Physics],InputCL['TrackPoints'])
1702 211 equemene
1703 234 equemene
    print('My Platform is ',PF4XPU)
1704 228 equemene
1705 234 equemene
    if 'Intel' in PF4XPU or 'Experimental' in PF4XPU or 'Clover' in PF4XPU or 'Portable' in PF4XPU :
1706 228 equemene
        print('No extra options for Intel and Clover!')
1707 228 equemene
    else:
1708 228 equemene
        BuildOptions = BuildOptions+" -cl-mad-enable"
1709 228 equemene
1710 211 equemene
    BlackHoleCL = cl.Program(ctx,BlobOpenCL).build(options = BuildOptions)
1711 211 equemene
1712 199 equemene
    # Je recupere les flag possibles pour les buffers
1713 199 equemene
    mf = cl.mem_flags
1714 199 equemene
1715 228 equemene
    if Method=='TrajectoPixel' or Method=='TrajectoCircle':
1716 263 equemene
    #     TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
1717 263 equemene
    #     IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
1718 228 equemene
1719 263 equemene
    # zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
1720 263 equemene
    # fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
1721 263 equemene
1722 263 equemene
        TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY, Trajectories.nbytes)
1723 263 equemene
        IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY, IdLast.nbytes)
1724 263 equemene
1725 263 equemene
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY, zImage.nbytes)
1726 263 equemene
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY, fImage.nbytes)
1727 199 equemene
1728 234 equemene
    start_time=time.time()
1729 199 equemene
1730 204 equemene
    if Method=='EachPixel':
1731 204 equemene
        CLLaunch=BlackHoleCL.EachPixel(queue,(zImage.shape[0],zImage.shape[1]),
1732 204 equemene
                                       None,zImageCL,fImageCL,
1733 204 equemene
                                       numpy.float32(Mass),
1734 204 equemene
                                       numpy.float32(InternalRadius),
1735 204 equemene
                                       numpy.float32(ExternalRadius),
1736 204 equemene
                                       numpy.float32(Angle),
1737 209 equemene
                                       numpy.int32(Line))
1738 204 equemene
        CLLaunch.wait()
1739 224 equemene
    elif Method=='Original':
1740 225 equemene
        CLLaunch=BlackHoleCL.Original(queue,(1,),
1741 224 equemene
                                      None,zImageCL,fImageCL,
1742 225 equemene
                                      numpy.uint32(zImage.shape[0]/2),
1743 224 equemene
                                      numpy.float32(Mass),
1744 224 equemene
                                      numpy.float32(InternalRadius),
1745 224 equemene
                                      numpy.float32(ExternalRadius),
1746 224 equemene
                                      numpy.float32(Angle),
1747 224 equemene
                                      numpy.int32(Line))
1748 224 equemene
        CLLaunch.wait()
1749 225 equemene
    elif Method=='EachCircle':
1750 244 equemene
        CLLaunch=BlackHoleCL.EachCircle(queue,(int(zImage.shape[0]/2),),
1751 225 equemene
                                        None,zImageCL,fImageCL,
1752 225 equemene
                                        numpy.float32(Mass),
1753 225 equemene
                                        numpy.float32(InternalRadius),
1754 225 equemene
                                        numpy.float32(ExternalRadius),
1755 225 equemene
                                        numpy.float32(Angle),
1756 225 equemene
                                        numpy.int32(Line))
1757 225 equemene
        CLLaunch.wait()
1758 204 equemene
    elif Method=='TrajectoCircle':
1759 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
1760 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
1761 204 equemene
                                        numpy.float32(Mass),
1762 204 equemene
                                        numpy.float32(InternalRadius),
1763 204 equemene
                                        numpy.float32(ExternalRadius),
1764 204 equemene
                                        numpy.float32(Angle),
1765 209 equemene
                                        numpy.int32(Line))
1766 204 equemene
1767 204 equemene
        CLLaunch=BlackHoleCL.Circle(queue,(Trajectories.shape[0],
1768 244 equemene
                                           int(zImage.shape[0]*4)),None,
1769 204 equemene
                                    TrajectoriesCL,IdLastCL,
1770 204 equemene
                                    zImageCL,fImageCL,
1771 204 equemene
                                    numpy.float32(Mass),
1772 204 equemene
                                    numpy.float32(InternalRadius),
1773 204 equemene
                                    numpy.float32(ExternalRadius),
1774 204 equemene
                                    numpy.float32(Angle),
1775 209 equemene
                                    numpy.int32(Line))
1776 204 equemene
        CLLaunch.wait()
1777 204 equemene
    else:
1778 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
1779 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
1780 204 equemene
                                        numpy.float32(Mass),
1781 204 equemene
                                        numpy.float32(InternalRadius),
1782 204 equemene
                                        numpy.float32(ExternalRadius),
1783 204 equemene
                                        numpy.float32(Angle),
1784 209 equemene
                                        numpy.int32(Line))
1785 204 equemene
1786 228 equemene
        CLLaunch=BlackHoleCL.Pixel(queue,(zImage.shape[0],zImage.shape[1]),None,
1787 204 equemene
                                   zImageCL,fImageCL,TrajectoriesCL,IdLastCL,
1788 204 equemene
                                   numpy.uint32(Trajectories.shape[0]),
1789 228 equemene
                                   numpy.float32(Mass),
1790 228 equemene
                                   numpy.float32(InternalRadius),
1791 228 equemene
                                   numpy.float32(ExternalRadius),
1792 228 equemene
                                   numpy.float32(Angle),
1793 228 equemene
                                   numpy.int32(Line))
1794 204 equemene
        CLLaunch.wait()
1795 204 equemene
1796 218 equemene
    compute = time.time()-start_time
1797 199 equemene
1798 201 equemene
    cl.enqueue_copy(queue,zImage,zImageCL).wait()
1799 201 equemene
    cl.enqueue_copy(queue,fImage,fImageCL).wait()
1800 228 equemene
    if Method=='TrajectoPixel' or Method=='TrajectoCircle':
1801 228 equemene
        cl.enqueue_copy(queue,Trajectories,TrajectoriesCL).wait()
1802 228 equemene
        cl.enqueue_copy(queue,IdLast,IdLastCL).wait()
1803 218 equemene
    elapsed = time.time()-start_time
1804 218 equemene
    print("\nCompute Time : %f" % compute)
1805 218 equemene
    print("Elapsed Time : %f\n" % elapsed)
1806 211 equemene
1807 211 equemene
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
1808 211 equemene
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
1809 236 equemene
    print("Z max @(%f,%f) : %f" % ((1.*zMaxPosition[1][0]/zImage.shape[1]-0.5,1.*zMaxPosition[0][0]/zImage.shape[0]-0.5,zImage.max())))
1810 236 equemene
    print("Flux max @(%f,%f) : %f" % ((1.*fMaxPosition[1][0]/fImage.shape[1]-0.5,1.*fMaxPosition[0][0]/fImage.shape[0]-0.5,fImage.max())))
1811 201 equemene
    zImageCL.release()
1812 201 equemene
    fImageCL.release()
1813 204 equemene
1814 228 equemene
    if Method=='TrajectoPixel' or Method=='TrajectoCircle':
1815 237 equemene
        if not NoImage:
1816 237 equemene
            AngleStep=4*numpy.pi/TrackPoints
1817 237 equemene
            Angles=numpy.arange(0.,4*numpy.pi,AngleStep)
1818 237 equemene
            Angles.shape=(1,TrackPoints)
1819 237 equemene
            Hostname=gethostname()
1820 237 equemene
            Date=time.strftime("%Y%m%d_%H%M%S")
1821 237 equemene
            ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
1822 237 equemene
1823 257 equemene
            if TrackSave:
1824 257 equemene
                # numpy.savetxt("TrouNoirTrajectories_%s.csv" % ImageInfo,
1825 257 equemene
                #               numpy.transpose(numpy.concatenate((Angles,Trajectories),axis=0)),
1826 257 equemene
                #               delimiter=' ', fmt='%.2e')
1827 257 equemene
                numpy.savetxt("TrouNoirTrajectories.csv",
1828 257 equemene
                            numpy.transpose(numpy.concatenate((Angles,Trajectories),axis=0)),delimiter=' ', fmt='%.2e')
1829 237 equemene
1830 228 equemene
        TrajectoriesCL.release()
1831 228 equemene
        IdLastCL.release()
1832 237 equemene
1833 199 equemene
    return(elapsed)
1834 199 equemene
1835 217 equemene
def BlackHoleCUDA(zImage,fImage,InputCL):
1836 217 equemene
1837 217 equemene
    kernel_params = {}
1838 217 equemene
1839 217 equemene
    Device=InputCL['Device']
1840 217 equemene
    GpuStyle=InputCL['GpuStyle']
1841 217 equemene
    VariableType=InputCL['VariableType']
1842 217 equemene
    Size=InputCL['Size']
1843 217 equemene
    Mass=InputCL['Mass']
1844 217 equemene
    InternalRadius=InputCL['InternalRadius']
1845 217 equemene
    ExternalRadius=InputCL['ExternalRadius']
1846 217 equemene
    Angle=InputCL['Angle']
1847 217 equemene
    Method=InputCL['Method']
1848 217 equemene
    TrackPoints=InputCL['TrackPoints']
1849 217 equemene
    Physics=InputCL['Physics']
1850 235 equemene
    Threads=InputCL['Threads']
1851 217 equemene
1852 217 equemene
    PhysicsList=DictionariesAPI()
1853 217 equemene
1854 217 equemene
    if InputCL['BlackBody']:
1855 217 equemene
        # Spectrum is Black Body one
1856 217 equemene
        Line=0
1857 217 equemene
    else:
1858 217 equemene
        # Spectrum is Monochromatic Line one
1859 217 equemene
        Line=1
1860 217 equemene
1861 217 equemene
    Trajectories=numpy.zeros((int(InputCL['Size']/2),InputCL['TrackPoints']),dtype=numpy.float32)
1862 217 equemene
    IdLast=numpy.zeros(int(InputCL['Size']/2),dtype=numpy.int32)
1863 217 equemene
1864 217 equemene
    try:
1865 217 equemene
        # For PyCUDA import
1866 217 equemene
        import pycuda.driver as cuda
1867 217 equemene
        from pycuda.compiler import SourceModule
1868 217 equemene
1869 217 equemene
        cuda.init()
1870 217 equemene
        for Id in range(cuda.Device.count()):
1871 217 equemene
            if Id==Device:
1872 217 equemene
                XPU=cuda.Device(Id)
1873 217 equemene
                print("GPU selected %s" % XPU.name())
1874 217 equemene
        print
1875 217 equemene
1876 217 equemene
    except ImportError:
1877 217 equemene
        print("Platform does not seem to support CUDA")
1878 217 equemene
1879 217 equemene
    Context=XPU.make_context()
1880 217 equemene
1881 217 equemene
    try:
1882 224 equemene
        mod = SourceModule(KernelCodeCuda(),options=['--compiler-options','-DPHYSICS=%i -DSETTRACKPOINTS=%i' % (PhysicsList[Physics],TrackPoints)])
1883 217 equemene
        print("Compilation seems to be OK")
1884 217 equemene
    except:
1885 217 equemene
        print("Compilation seems to break")
1886 217 equemene
1887 217 equemene
    EachPixelCU=mod.get_function("EachPixel")
1888 224 equemene
    OriginalCU=mod.get_function("Original")
1889 225 equemene
    EachCircleCU=mod.get_function("EachCircle")
1890 217 equemene
    TrajectoryCU=mod.get_function("Trajectory")
1891 217 equemene
    PixelCU=mod.get_function("Pixel")
1892 217 equemene
    CircleCU=mod.get_function("Circle")
1893 217 equemene
1894 217 equemene
    TrajectoriesCU = cuda.mem_alloc(Trajectories.size*Trajectories.dtype.itemsize)
1895 217 equemene
    cuda.memcpy_htod(TrajectoriesCU, Trajectories)
1896 217 equemene
    zImageCU = cuda.mem_alloc(zImage.size*zImage.dtype.itemsize)
1897 217 equemene
    cuda.memcpy_htod(zImageCU, zImage)
1898 217 equemene
    fImageCU = cuda.mem_alloc(fImage.size*fImage.dtype.itemsize)
1899 217 equemene
    cuda.memcpy_htod(zImageCU, fImage)
1900 217 equemene
    IdLastCU = cuda.mem_alloc(IdLast.size*IdLast.dtype.itemsize)
1901 217 equemene
    cuda.memcpy_htod(IdLastCU, IdLast)
1902 217 equemene
1903 234 equemene
    start_time=time.time()
1904 217 equemene
1905 217 equemene
    if Method=='EachPixel':
1906 217 equemene
        EachPixelCU(zImageCU,fImageCU,
1907 217 equemene
                    numpy.float32(Mass),
1908 217 equemene
                    numpy.float32(InternalRadius),
1909 217 equemene
                    numpy.float32(ExternalRadius),
1910 217 equemene
                    numpy.float32(Angle),
1911 217 equemene
                    numpy.int32(Line),
1912 243 equemene
                    grid=(int(zImage.shape[0]/Threads),
1913 243 equemene
                          int(zImage.shape[1]/Threads)),
1914 235 equemene
                    block=(Threads,Threads,1))
1915 225 equemene
    elif Method=='EachCircle':
1916 225 equemene
        EachCircleCU(zImageCU,fImageCU,
1917 225 equemene
                   numpy.float32(Mass),
1918 225 equemene
                   numpy.float32(InternalRadius),
1919 225 equemene
                   numpy.float32(ExternalRadius),
1920 225 equemene
                   numpy.float32(Angle),
1921 225 equemene
                   numpy.int32(Line),
1922 241 equemene
                   grid=(int(zImage.shape[0]/Threads/2),1),
1923 235 equemene
                   block=(Threads,1,1))
1924 224 equemene
    elif Method=='Original':
1925 224 equemene
        OriginalCU(zImageCU,fImageCU,
1926 225 equemene
                   numpy.uint32(zImage.shape[0]/2),
1927 224 equemene
                   numpy.float32(Mass),
1928 224 equemene
                   numpy.float32(InternalRadius),
1929 224 equemene
                   numpy.float32(ExternalRadius),
1930 224 equemene
                   numpy.float32(Angle),
1931 224 equemene
                   numpy.int32(Line),
1932 225 equemene
                   grid=(1,1),
1933 225 equemene
                   block=(1,1,1))
1934 217 equemene
    elif Method=='TrajectoCircle':
1935 217 equemene
        TrajectoryCU(TrajectoriesCU,IdLastCU,
1936 217 equemene
                     numpy.float32(Mass),
1937 217 equemene
                     numpy.float32(InternalRadius),
1938 217 equemene
                     numpy.float32(ExternalRadius),
1939 217 equemene
                     numpy.float32(Angle),
1940 217 equemene
                     numpy.int32(Line),
1941 241 equemene
                     grid=(int(Trajectories.shape[0]/Threads),1),
1942 235 equemene
                     block=(Threads,1,1))
1943 217 equemene
1944 217 equemene
        CircleCU(TrajectoriesCU,IdLastCU,zImageCU,fImageCU,
1945 217 equemene
                 numpy.float32(Mass),
1946 217 equemene
                 numpy.float32(InternalRadius),
1947 217 equemene
                 numpy.float32(ExternalRadius),
1948 217 equemene
                 numpy.float32(Angle),
1949 217 equemene
                 numpy.int32(Line),
1950 241 equemene
                 grid=(int(Trajectories.shape[0]/Threads),
1951 241 equemene
                       int(zImage.shape[0]*4/Threads)),
1952 235 equemene
                 block=(Threads,Threads,1))
1953 217 equemene
    else:
1954 241 equemene
        # Default method: TrajectoPixel
1955 217 equemene
        TrajectoryCU(TrajectoriesCU,IdLastCU,
1956 217 equemene
                     numpy.float32(Mass),
1957 217 equemene
                     numpy.float32(InternalRadius),
1958 217 equemene
                     numpy.float32(ExternalRadius),
1959 217 equemene
                     numpy.float32(Angle),
1960 217 equemene
                     numpy.int32(Line),
1961 241 equemene
                     grid=(int(Trajectories.shape[0]/Threads),1),
1962 235 equemene
                     block=(Threads,1,1))
1963 217 equemene
1964 217 equemene
        PixelCU(zImageCU,fImageCU,TrajectoriesCU,IdLastCU,
1965 217 equemene
                numpy.uint32(Trajectories.shape[0]),
1966 217 equemene
                numpy.float32(Mass),
1967 217 equemene
                numpy.float32(InternalRadius),
1968 217 equemene
                numpy.float32(ExternalRadius),
1969 217 equemene
                numpy.float32(Angle),
1970 217 equemene
                numpy.int32(Line),
1971 241 equemene
                grid=(int(zImage.shape[0]/Threads),
1972 241 equemene
                      int(zImage.shape[1]/Threads),1),
1973 235 equemene
                block=(Threads,Threads,1))
1974 217 equemene
1975 220 equemene
    Context.synchronize()
1976 220 equemene
1977 218 equemene
    compute = time.time()-start_time
1978 217 equemene
1979 217 equemene
    cuda.memcpy_dtoh(zImage,zImageCU)
1980 217 equemene
    cuda.memcpy_dtoh(fImage,fImageCU)
1981 238 equemene
    if Method=='TrajectoPixel' or Method=='TrajectoCircle':
1982 238 equemene
        cuda.memcpy_dtoh(Trajectories,TrajectoriesCU)
1983 218 equemene
    elapsed = time.time()-start_time
1984 218 equemene
    print("\nCompute Time : %f" % compute)
1985 218 equemene
    print("Elapsed Time : %f\n" % elapsed)
1986 217 equemene
1987 217 equemene
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
1988 217 equemene
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
1989 236 equemene
    print("Z max @(%f,%f) : %f" % ((1.*zMaxPosition[1][0]/zImage.shape[1]-0.5,1.*zMaxPosition[0][0]/zImage.shape[0]-0.5,zImage.max())))
1990 236 equemene
    print("Flux max @(%f,%f) : %f" % ((1.*fMaxPosition[1][0]/fImage.shape[1]-0.5,1.*fMaxPosition[0][0]/fImage.shape[0]-0.5,fImage.max())))
1991 217 equemene
1992 220 equemene
1993 218 equemene
    Context.pop()
1994 220 equemene
1995 217 equemene
    Context.detach()
1996 217 equemene
1997 238 equemene
    if Method=='TrajectoPixel' or Method=='TrajectoCircle':
1998 238 equemene
        if not NoImage:
1999 238 equemene
            AngleStep=4*numpy.pi/TrackPoints
2000 238 equemene
            Angles=numpy.arange(0.,4*numpy.pi,AngleStep)
2001 238 equemene
            Angles.shape=(1,TrackPoints)
2002 238 equemene
            Hostname=gethostname()
2003 238 equemene
            Date=time.strftime("%Y%m%d_%H%M%S")
2004 238 equemene
            ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
2005 238 equemene
2006 238 equemene
            # numpy.savetxt("TrouNoirTrajectories_%s.csv" % ImageInfo,
2007 238 equemene
            #               numpy.transpose(numpy.concatenate((Angles,Trajectories),axis=0)),
2008 238 equemene
            #               delimiter=' ', fmt='%.2e')
2009 238 equemene
            numpy.savetxt("TrouNoirTrajectories.csv",
2010 238 equemene
                          numpy.transpose(numpy.concatenate((Angles,Trajectories),axis=0)),
2011 238 equemene
                          delimiter=' ', fmt='%.2e')
2012 238 equemene
2013 238 equemene
2014 217 equemene
    return(elapsed)
2015 217 equemene
2016 199 equemene
if __name__=='__main__':
2017 257 equemene
2018 257 equemene
    # Default device: first one!
2019 257 equemene
    Device=0
2020 257 equemene
    # Default implementation: OpenCL, most versatile!
2021 199 equemene
    GpuStyle = 'OpenCL'
2022 199 equemene
    Mass = 1.
2023 199 equemene
    # Internal Radius 3 times de Schwarzschild Radius
2024 199 equemene
    InternalRadius=6.*Mass
2025 199 equemene
    #
2026 199 equemene
    ExternalRadius=12.
2027 199 equemene
    #
2028 199 equemene
    # Angle with normal to disc 10 degrees
2029 199 equemene
    Angle = numpy.pi/180.*(90.-10.)
2030 199 equemene
    # Radiation of disc : BlackBody or Monochromatic
2031 209 equemene
    BlackBody = False
2032 199 equemene
    # Size of image
2033 257 equemene
    Size=1024
2034 199 equemene
    # Variable Type
2035 199 equemene
    VariableType='FP32'
2036 199 equemene
    # ?
2037 199 equemene
    q=-2
2038 204 equemene
    # Method of resolution
2039 209 equemene
    Method='TrajectoPixel'
2040 211 equemene
    # Colors for output image
2041 211 equemene
    Colors='Greyscale'
2042 211 equemene
    # Physics
2043 211 equemene
    Physics='Einstein'
2044 211 equemene
    # No output as image
2045 211 equemene
    NoImage = False
2046 235 equemene
    # Threads in CUDA
2047 235 equemene
    Threads = 32
2048 238 equemene
    # Trackpoints of trajectories
2049 238 equemene
    TrackPoints=2048
2050 257 equemene
    # Tracksave of trajectories
2051 257 equemene
    TrackSave=False
2052 211 equemene
2053 257 equemene
    HowToUse='%s -h [Help] -b [BlackBodyEmission] -j [TrackSave] -n [NoImage] -p <Einstein/Newton> -s <SizeInPixels> -m <Mass> -i <DiscInternalRadius> -x <DiscExternalRadius> -a <AngleAboveDisc> -d <DeviceId> -c <Greyscale/Red2Yellow> -g <CUDA/OpenCL> -o <EachPixel/TrajectoCircle/TrajectoPixel/EachCircle/Original> -t <ThreadsInCuda> -v <FP32/FP64> -k <TrackPoints>'
2054 199 equemene
2055 199 equemene
    try:
2056 257 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hbnjs:m:i:x:a:d:g:v:o:t:c:p:k:",["tracksave","blackbody","noimage","camera","size=","mass=","internal=","external=","angle=","device=","gpustyle=","variabletype=","method=","threads=","colors=","physics=","trackpoints="])
2057 199 equemene
    except getopt.GetoptError:
2058 199 equemene
        print(HowToUse % sys.argv[0])
2059 199 equemene
        sys.exit(2)
2060 199 equemene
2061 199 equemene
    # List of Devices
2062 199 equemene
    Devices=[]
2063 199 equemene
    Alu={}
2064 199 equemene
2065 199 equemene
    for opt, arg in opts:
2066 199 equemene
        if opt == '-h':
2067 199 equemene
            print(HowToUse % sys.argv[0])
2068 199 equemene
2069 199 equemene
            print("\nInformations about devices detected under OpenCL API:")
2070 199 equemene
            # For PyOpenCL import
2071 199 equemene
            try:
2072 199 equemene
                import pyopencl as cl
2073 199 equemene
                Id=0
2074 199 equemene
                for platform in cl.get_platforms():
2075 199 equemene
                    for device in platform.get_devices():
2076 199 equemene
                        #deviceType=cl.device_type.to_string(device.type)
2077 199 equemene
                        deviceType="xPU"
2078 199 equemene
                        print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip(),deviceType,device.name.lstrip()))
2079 199 equemene
                        Id=Id+1
2080 199 equemene
2081 199 equemene
            except:
2082 199 equemene
                print("Your platform does not seem to support OpenCL")
2083 199 equemene
2084 199 equemene
            print("\nInformations about devices detected under CUDA API:")
2085 199 equemene
                # For PyCUDA import
2086 199 equemene
            try:
2087 199 equemene
                import pycuda.driver as cuda
2088 199 equemene
                cuda.init()
2089 199 equemene
                for Id in range(cuda.Device.count()):
2090 199 equemene
                    device=cuda.Device(Id)
2091 199 equemene
                    print("Device #%i of type GPU : %s" % (Id,device.name()))
2092 199 equemene
                print
2093 199 equemene
            except:
2094 199 equemene
                print("Your platform does not seem to support CUDA")
2095 199 equemene
2096 199 equemene
            sys.exit()
2097 199 equemene
2098 199 equemene
        elif opt in ("-d", "--device"):
2099 199 equemene
#            Devices.append(int(arg))
2100 199 equemene
            Device=int(arg)
2101 199 equemene
        elif opt in ("-g", "--gpustyle"):
2102 199 equemene
            GpuStyle = arg
2103 204 equemene
        elif opt in ("-v", "--variabletype"):
2104 199 equemene
            VariableType = arg
2105 199 equemene
        elif opt in ("-s", "--size"):
2106 199 equemene
            Size = int(arg)
2107 238 equemene
        elif opt in ("-k", "--trackpoints"):
2108 238 equemene
            TrackPoints = int(arg)
2109 199 equemene
        elif opt in ("-m", "--mass"):
2110 199 equemene
            Mass = float(arg)
2111 199 equemene
        elif opt in ("-i", "--internal"):
2112 199 equemene
            InternalRadius = float(arg)
2113 199 equemene
        elif opt in ("-e", "--external"):
2114 199 equemene
            ExternalRadius = float(arg)
2115 199 equemene
        elif opt in ("-a", "--angle"):
2116 199 equemene
            Angle = numpy.pi/180.*(90.-float(arg))
2117 199 equemene
        elif opt in ("-b", "--blackbody"):
2118 199 equemene
            BlackBody = True
2119 257 equemene
        elif opt in ("-j", "--tracksave"):
2120 257 equemene
            TrackSave = True
2121 211 equemene
        elif opt in ("-n", "--noimage"):
2122 211 equemene
            NoImage = True
2123 235 equemene
        elif opt in ("-o", "--method"):
2124 204 equemene
            Method = arg
2125 235 equemene
        elif opt in ("-t", "--threads"):
2126 235 equemene
            Threads = int(arg)
2127 211 equemene
        elif opt in ("-c", "--colors"):
2128 211 equemene
            Colors = arg
2129 211 equemene
        elif opt in ("-p", "--physics"):
2130 211 equemene
            Physics = arg
2131 199 equemene
2132 199 equemene
    print("Device Identification selected : %s" % Device)
2133 199 equemene
    print("GpuStyle used : %s" % GpuStyle)
2134 199 equemene
    print("VariableType : %s" % VariableType)
2135 199 equemene
    print("Size : %i" % Size)
2136 199 equemene
    print("Mass : %f" % Mass)
2137 199 equemene
    print("Internal Radius : %f" % InternalRadius)
2138 199 equemene
    print("External Radius : %f" % ExternalRadius)
2139 199 equemene
    print("Angle with normal of (in radians) : %f" % Angle)
2140 199 equemene
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
2141 204 equemene
    print("Method of resolution : %s" % Method)
2142 211 equemene
    print("Colors for output images : %s" % Colors)
2143 211 equemene
    print("Physics used for Trajectories : %s" % Physics)
2144 238 equemene
    print("Trackpoints of Trajectories : %i" % TrackPoints)
2145 257 equemene
    print("Tracksave of Trajectories : %i" % TrackSave)
2146 199 equemene
2147 199 equemene
    if GpuStyle=='CUDA':
2148 199 equemene
        print("\nSelection of CUDA device")
2149 199 equemene
        try:
2150 199 equemene
            # For PyCUDA import
2151 199 equemene
            import pycuda.driver as cuda
2152 199 equemene
2153 199 equemene
            cuda.init()
2154 199 equemene
            for Id in range(cuda.Device.count()):
2155 199 equemene
                device=cuda.Device(Id)
2156 199 equemene
                print("Device #%i of type GPU : %s" % (Id,device.name()))
2157 199 equemene
                if Id in Devices:
2158 199 equemene
                    Alu[Id]='GPU'
2159 199 equemene
2160 199 equemene
        except ImportError:
2161 199 equemene
            print("Platform does not seem to support CUDA")
2162 199 equemene
2163 199 equemene
    if GpuStyle=='OpenCL':
2164 199 equemene
        print("\nSelection of OpenCL device")
2165 199 equemene
        try:
2166 199 equemene
            # For PyOpenCL import
2167 199 equemene
            import pyopencl as cl
2168 199 equemene
            Id=0
2169 199 equemene
            for platform in cl.get_platforms():
2170 199 equemene
                for device in platform.get_devices():
2171 199 equemene
                    #deviceType=cl.device_type.to_string(device.type)
2172 199 equemene
                    deviceType="xPU"
2173 199 equemene
                    print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip().rstrip(),deviceType,device.name.lstrip().rstrip()))
2174 199 equemene
2175 199 equemene
                    if Id in Devices:
2176 199 equemene
                    # Set the Alu as detected Device Type
2177 199 equemene
                        Alu[Id]=deviceType
2178 199 equemene
                    Id=Id+1
2179 199 equemene
        except ImportError:
2180 199 equemene
            print("Platform does not seem to support OpenCL")
2181 199 equemene
2182 199 equemene
2183 201 equemene
    zImage=numpy.zeros((Size,Size),dtype=numpy.float32)
2184 201 equemene
    fImage=numpy.zeros((Size,Size),dtype=numpy.float32)
2185 199 equemene
2186 204 equemene
    InputCL={}
2187 204 equemene
    InputCL['Device']=Device
2188 204 equemene
    InputCL['GpuStyle']=GpuStyle
2189 204 equemene
    InputCL['VariableType']=VariableType
2190 204 equemene
    InputCL['Size']=Size
2191 204 equemene
    InputCL['Mass']=Mass
2192 204 equemene
    InputCL['InternalRadius']=InternalRadius
2193 204 equemene
    InputCL['ExternalRadius']=ExternalRadius
2194 204 equemene
    InputCL['Angle']=Angle
2195 204 equemene
    InputCL['BlackBody']=BlackBody
2196 204 equemene
    InputCL['Method']=Method
2197 204 equemene
    InputCL['TrackPoints']=TrackPoints
2198 211 equemene
    InputCL['Physics']=Physics
2199 235 equemene
    InputCL['Threads']=Threads
2200 237 equemene
    InputCL['NoImage']=NoImage
2201 257 equemene
    InputCL['TrackSave']=TrackSave
2202 199 equemene
2203 217 equemene
    if GpuStyle=='OpenCL':
2204 217 equemene
        duration=BlackHoleCL(zImage,fImage,InputCL)
2205 217 equemene
    else:
2206 217 equemene
        duration=BlackHoleCUDA(zImage,fImage,InputCL)
2207 217 equemene
2208 211 equemene
    Hostname=gethostname()
2209 211 equemene
    Date=time.strftime("%Y%m%d_%H%M%S")
2210 211 equemene
    ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
2211 211 equemene
2212 211 equemene
2213 211 equemene
    if not NoImage:
2214 211 equemene
        ImageOutput(zImage,"TrouNoirZ_%s" % ImageInfo,Colors)
2215 211 equemene
        ImageOutput(fImage,"TrouNoirF_%s" % ImageInfo,Colors)