Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 308

Historique | Voir | Annoter | Télécharger (53,99 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 292 equemene
  float Trajectory[TRACKPOINTS];
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 292 equemene
  for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
1454 292 equemene
     Trajectory[i]=0.e0f;
1455 292 equemene
  }
1456 292 equemene

1457 224 equemene
  int imx=(int)(16*bi);
1458 224 equemene

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

1467 224 equemene
     int HalfLap=0,ExitOnImpact=0,ni;
1468 224 equemene
     float php,nr,r;
1469 224 equemene

1470 224 equemene
     do
1471 224 equemene
     {
1472 224 equemene
        php=phd+(float)HalfLap*PI;
1473 224 equemene
        nr=php/h;
1474 224 equemene
        ni=(int)nr;
1475 224 equemene

1476 224 equemene
        if (ni<nh)
1477 224 equemene
        {
1478 225 equemene
           r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1479 224 equemene
        }
1480 224 equemene
        else
1481 224 equemene
        {
1482 225 equemene
           r=Trajectory[ni];
1483 224 equemene
        }
1484 234 equemene

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

1491 224 equemene
        HalfLap++;
1492 224 equemene

1493 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
1494 224 equemene

1495 224 equemene
   __syncthreads();
1496 224 equemene

1497 224 equemene
   zImage[yi+2*bmaxi*xi]=zp;
1498 224 equemene
   fImage[yi+2*bmaxi*xi]=fp;
1499 224 equemene

1500 224 equemene
  }
1501 234 equemene

1502 224 equemene
}
1503 225 equemene

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

1512 225 equemene
   float Trajectory[TRACKPOINTS];
1513 225 equemene

1514 225 equemene
   // Perform trajectory for each pixel
1515 225 equemene

1516 225 equemene
   float m,rs,ri,re,tho;
1517 225 equemene
   int raie,q;
1518 225 equemene

1519 225 equemene
   m=Mass;
1520 234 equemene
   rs=2.e0f*m;
1521 225 equemene
   ri=InternalRadius;
1522 225 equemene
   re=ExternalRadius;
1523 225 equemene
   tho=Angle;
1524 225 equemene
   q=-2;
1525 225 equemene
   raie=Line;
1526 225 equemene

1527 225 equemene
   float bmx,db,b,h;
1528 225 equemene
   int nh;
1529 225 equemene

1530 225 equemene
   // Autosize for image
1531 225 equemene
   bmx=1.25e0f*re;
1532 225 equemene

1533 225 equemene
   // Angular step of integration
1534 225 equemene
   h=4.e0f*PI/(float)TRACKPOINTS;
1535 225 equemene

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

1543 225 equemene
      float up,vp,pp,us,vs,ps;
1544 225 equemene

1545 225 equemene
      up=0.;
1546 225 equemene
      vp=1.;
1547 225 equemene
      pp=0.;
1548 225 equemene
      nh=0;
1549 225 equemene

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

1552 225 equemene
      // b versus us
1553 225 equemene
      float bvus=fabs(b/us);
1554 225 equemene
      float bvus0=bvus;
1555 225 equemene
      Trajectory[nh]=bvus;
1556 225 equemene

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

1567 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
1568 225 equemene

1569 225 equemene
      for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
1570 225 equemene
         Trajectory[i]=0.e0f;
1571 225 equemene
      }
1572 225 equemene

1573 225 equemene
      int imx=(int)(16*bi);
1574 225 equemene

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

1583 225 equemene
         int HalfLap=0,ExitOnImpact=0,ni;
1584 225 equemene
         float php,nr,r;
1585 225 equemene

1586 225 equemene
         do
1587 225 equemene
         {
1588 225 equemene
            php=phd+(float)HalfLap*PI;
1589 225 equemene
            nr=php/h;
1590 225 equemene
            ni=(int)nr;
1591 225 equemene

1592 225 equemene
            if (ni<nh)
1593 225 equemene
            {
1594 225 equemene
               r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1595 225 equemene
            }
1596 225 equemene
            else
1597 225 equemene
            {
1598 225 equemene
               r=Trajectory[ni];
1599 225 equemene
            }
1600 234 equemene

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

1607 225 equemene
            HalfLap++;
1608 234 equemene

1609 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
1610 234 equemene

1611 225 equemene
         zImage[yi+2*bmaxi*xi]=zp;
1612 225 equemene
         fImage[yi+2*bmaxi*xi]=fp;
1613 234 equemene

1614 225 equemene
      }
1615 225 equemene

1616 234 equemene
   }
1617 234 equemene

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