Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 238

Historique | Voir | Annoter | Télécharger (52,88 ko)

1 221 equemene
#!/usr/bin/env python
2 199 equemene
#
3 234 equemene
# TrouNoir model using PyOpenCL
4 199 equemene
#
5 234 equemene
# CC BY-NC-SA 2019 : <emmanuel.quemener@ens-lyon.fr>
6 199 equemene
#
7 199 equemene
# Thanks to Andreas Klockner for PyOpenCL:
8 199 equemene
# http://mathema.tician.de/software/pyopencl
9 234 equemene
#
10 204 equemene
# Original code programmed in Fortran 77 in mars 1994
11 204 equemene
# for Practical Work of Numerical Simulation
12 204 equemene
# DEA (old Master2) in astrophysics and spatial techniques in Meudon
13 204 equemene
# by Herve Aussel & Emmanuel Quemener
14 204 equemene
#
15 204 equemene
# Conversion in C done by Emmanuel Quemener in august 1997
16 204 equemene
# GPUfication in OpenCL under Python in july 2019
17 221 equemene
# GPUfication in CUDA under Python in august 2019
18 204 equemene
#
19 204 equemene
# Thanks to :
20 234 equemene
#
21 204 equemene
# - Herve Aussel for his part of code of black body spectrum
22 204 equemene
# - Didier Pelat for his help to perform this work
23 204 equemene
# - Jean-Pierre Luminet for his article published in 1979
24 204 equemene
# - Numerical Recipies for Runge Kutta recipies
25 204 equemene
# - Luc Blanchet for his disponibility about my questions in General Relativity
26 204 equemene
# - Pierre Lena for his passion about science and vulgarisation
27 199 equemene
28 229 equemene
# If crash on OpenCL Intel implementation, add following options and force
29 229 equemene
#export PYOPENCL_COMPILER_OUTPUT=1
30 229 equemene
#export CL_CONFIG_USE_VECTORIZER=True
31 229 equemene
#export CL_CONFIG_CPU_VECTORIZER_MODE=16
32 226 equemene
33 199 equemene
import pyopencl as cl
34 199 equemene
import numpy
35 199 equemene
import time,string
36 199 equemene
from numpy.random import randint as nprnd
37 199 equemene
import sys
38 199 equemene
import getopt
39 199 equemene
import matplotlib.pyplot as plt
40 211 equemene
from socket import gethostname
41 199 equemene
42 211 equemene
def DictionariesAPI():
43 211 equemene
    PhysicsList={'Einstein':0,'Newton':1}
44 211 equemene
    return(PhysicsList)
45 204 equemene
46 226 equemene
#
47 226 equemene
# Blank space below to simplify debugging on OpenCL code
48 226 equemene
#
49 226 equemene
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 211 equemene
BlobOpenCL= """
104 204 equemene

105 234 equemene
#define PI (float)3.14159265359e0f
106 209 equemene
#define nbr 256
107 199 equemene

108 211 equemene
#define EINSTEIN 0
109 211 equemene
#define NEWTON 1
110 211 equemene

111 224 equemene
#ifdef SETTRACKPOINTS
112 224 equemene
#define TRACKPOINTS SETTRACKPOINTS
113 224 equemene
#else
114 217 equemene
#define TRACKPOINTS 2048
115 224 equemene
#endif
116 217 equemene

117 199 equemene
float atanp(float x,float y)
118 199 equemene
{
119 199 equemene
  float angle;
120 199 equemene

121 199 equemene
  angle=atan2(y,x);
122 199 equemene

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

128 199 equemene
  return angle;
129 199 equemene
}
130 199 equemene

131 199 equemene
float f(float v)
132 199 equemene
{
133 199 equemene
  return v;
134 199 equemene
}
135 199 equemene

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

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

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

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

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

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

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

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

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

194 213 equemene
#define MYFLOAT float
195 209 equemene

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

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

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

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

218 234 equemene
  MYFLOAT v=1.e0f-3.e0f/r;
219 199 equemene

220 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 ));
221 199 equemene

222 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)));
223 209 equemene

224 234 equemene
  flux_int=0.e0f;
225 234 equemene
  flx=0.e0f;
226 209 equemene

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

242 234 equemene
          flx+=flux_int;
243 234 equemene
        }
244 199 equemene
    }
245 209 equemene

246 209 equemene
  return((float)(flx));
247 199 equemene
}
248 199 equemene

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

256 199 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
257 199 equemene

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

269 234 equemene
  *zp=1.e0f/rf;
270 199 equemene
  *fp=flx;
271 199 equemene

272 199 equemene
}
273 199 equemene

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

284 204 equemene
   // Perform trajectory for each pixel, exit on hit
285 199 equemene

286 226 equemene
  float m,rs,ri,re,tho;
287 226 equemene
  int q,raie;
288 199 equemene

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

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

303 199 equemene
  // Autosize for image
304 228 equemene
  bmx=1.25e0f*re;
305 199 equemene

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

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

315 228 equemene

316 204 equemene
  float up,vp,pp,us,vs,ps;
317 204 equemene

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

323 228 equemene
  up=0.e0f;
324 228 equemene
  vp=1.e0f;
325 228 equemene
  pp=0.e0f;
326 199 equemene

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

329 218 equemene
  rps=fabs(b/us);
330 218 equemene
  rp0=rps;
331 199 equemene

332 204 equemene
  int ExitOnImpact=0;
333 199 equemene

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

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

346 228 equemene

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

356 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
357 204 equemene

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

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

374 204 equemene
   // Perform trajectory for each pixel
375 204 equemene

376 226 equemene
  float m,ri,re,tho;
377 209 equemene
  int q,raie;
378 204 equemene

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

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

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

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

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

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

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

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

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

413 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
414 204 equemene

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

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

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

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

441 204 equemene
  }
442 204 equemene

443 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
444 204 equemene

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

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

464 204 equemene
   // Perform trajectory for each pixel
465 204 equemene

466 226 equemene
  float m,ri,re,tho;
467 209 equemene
  int q,raie;
468 204 equemene

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

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

479 204 equemene
  // Autosize for image
480 234 equemene
  bmx=1.25e0f*re;
481 204 equemene

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

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

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

494 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
495 204 equemene
  float php,nr,r;
496 204 equemene

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

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

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

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

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

524 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
525 204 equemene

526 204 equemene
}
527 204 equemene

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

538 204 equemene
  // Perform trajectory for each pixel
539 204 equemene

540 224 equemene
  float m,rs,re;
541 224 equemene

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

546 224 equemene
  float bmx,b,h;
547 224 equemene
  int nh;
548 224 equemene

549 224 equemene
  // Autosize for image
550 234 equemene
  bmx=1.25e0f*re;
551 224 equemene

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

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

558 224 equemene
  float up,vp,pp,us,vs,ps;
559 224 equemene

560 234 equemene
  up=0.e0f;
561 234 equemene
  vp=1.e0f;
562 234 equemene

563 234 equemene
  pp=0.e0f;
564 224 equemene
  nh=0;
565 224 equemene

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

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

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

583 224 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
584 224 equemene

585 224 equemene
  IdLast[bi]=nh;
586 224 equemene

587 224 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
588 234 equemene

589 224 equemene
}
590 224 equemene

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

601 234 equemene
  private float Trajectory[TRACKPOINTS];
602 224 equemene

603 209 equemene
  float m,rs,ri,re,tho;
604 209 equemene
  int raie,q;
605 204 equemene

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

614 224 equemene
  float bmx,db,b,h;
615 234 equemene
  uint nh;
616 204 equemene

617 234 equemene

618 204 equemene
  // Autosize for image
619 224 equemene
  bmx=1.25e0f*re;
620 204 equemene

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

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

628 204 equemene
  float up,vp,pp,us,vs,ps;
629 204 equemene

630 234 equemene
  up=0.e0f;
631 234 equemene
  vp=1.e0f;
632 234 equemene

633 234 equemene
  pp=0.e0f;
634 204 equemene
  nh=0;
635 204 equemene

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

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

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

653 204 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
654 204 equemene

655 234 equemene

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

660 204 equemene

661 234 equemene
  uint imx=(uint)(16*bi);
662 234 equemene

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

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

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

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

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

695 224 equemene
        HalfLap++;
696 224 equemene

697 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
698 234 equemene

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

702 224 equemene
  }
703 224 equemene

704 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
705 234 equemene

706 199 equemene
}
707 225 equemene

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

716 225 equemene
   float Trajectory[TRACKPOINTS];
717 225 equemene

718 225 equemene
   // Perform trajectory for each pixel
719 225 equemene

720 225 equemene
   float m,rs,ri,re,tho;
721 225 equemene
   int raie,q;
722 225 equemene

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

731 225 equemene
   float bmx,db,b,h;
732 234 equemene
   uint nh;
733 225 equemene

734 225 equemene
   // Autosize for image
735 225 equemene
   bmx=1.25e0f*re;
736 225 equemene

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

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

747 225 equemene
      float up,vp,pp,us,vs,ps;
748 225 equemene

749 234 equemene
      up=0.e0f;
750 234 equemene
      vp=1.e0f;
751 234 equemene

752 234 equemene
      pp=0.e0f;
753 225 equemene
      nh=0;
754 225 equemene

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

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

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

772 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
773 225 equemene

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

778 225 equemene
      int imx=(int)(16*bi);
779 225 equemene

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

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

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

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

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

812 225 equemene
            HalfLap++;
813 234 equemene

814 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
815 234 equemene

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

819 225 equemene
      }
820 225 equemene

821 234 equemene
   }
822 234 equemene

823 225 equemene
   barrier(CLK_GLOBAL_MEM_FENCE);
824 234 equemene

825 225 equemene
}
826 211 equemene
"""
827 199 equemene
828 217 equemene
def KernelCodeCuda():
829 217 equemene
    BlobCUDA= """
830 217 equemene

831 217 equemene
#define PI (float)3.14159265359
832 217 equemene
#define nbr 256
833 217 equemene

834 217 equemene
#define EINSTEIN 0
835 217 equemene
#define NEWTON 1
836 217 equemene

837 224 equemene
#ifdef SETTRACKPOINTS
838 224 equemene
#define TRACKPOINTS SETTRACKPOINTS
839 224 equemene
#else
840 224 equemene
#define TRACKPOINTS
841 224 equemene
#endif
842 217 equemene

843 217 equemene
__device__ float nothing(float x)
844 217 equemene
{
845 217 equemene
  return(x);
846 217 equemene
}
847 217 equemene

848 217 equemene
__device__ float atanp(float x,float y)
849 217 equemene
{
850 217 equemene
  float angle;
851 217 equemene

852 217 equemene
  angle=atan2(y,x);
853 217 equemene

854 217 equemene
  if (angle<0.e0f)
855 217 equemene
    {
856 217 equemene
      angle+=(float)2.e0f*PI;
857 217 equemene
    }
858 217 equemene

859 217 equemene
  return(angle);
860 217 equemene
}
861 217 equemene

862 217 equemene
__device__ float f(float v)
863 217 equemene
{
864 217 equemene
  return(v);
865 217 equemene
}
866 217 equemene

867 217 equemene
#if PHYSICS == NEWTON
868 217 equemene
__device__ float g(float u,float m,float b)
869 217 equemene
{
870 217 equemene
  return (-u);
871 217 equemene
}
872 217 equemene
#else
873 217 equemene
__device__ float g(float u,float m,float b)
874 217 equemene
{
875 217 equemene
  return (3.e0f*m/b*pow(u,2)-u);
876 217 equemene
}
877 217 equemene
#endif
878 217 equemene

879 217 equemene
__device__ void calcul(float *us,float *vs,float up,float vp,
880 234 equemene
                       float h,float m,float b)
881 217 equemene
{
882 217 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
883 217 equemene

884 217 equemene
  c0=h*f(vp);
885 217 equemene
  c1=h*f(vp+c0/2.);
886 217 equemene
  c2=h*f(vp+c1/2.);
887 217 equemene
  c3=h*f(vp+c2);
888 217 equemene
  d0=h*g(up,m,b);
889 217 equemene
  d1=h*g(up+d0/2.,m,b);
890 217 equemene
  d2=h*g(up+d1/2.,m,b);
891 217 equemene
  d3=h*g(up+d2,m,b);
892 217 equemene

893 217 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
894 217 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
895 217 equemene
}
896 217 equemene

897 217 equemene
__device__ void rungekutta(float *ps,float *us,float *vs,
898 234 equemene
                           float pp,float up,float vp,
899 234 equemene
                           float h,float m,float b)
900 217 equemene
{
901 217 equemene
  calcul(us,vs,up,vp,h,m,b);
902 217 equemene
  *ps=pp+h;
903 217 equemene
}
904 217 equemene

905 217 equemene
__device__ float decalage_spectral(float r,float b,float phi,
906 234 equemene
                                   float tho,float m)
907 217 equemene
{
908 217 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
909 217 equemene
}
910 217 equemene

911 217 equemene
__device__ float spectre(float rf,int q,float b,float db,
912 234 equemene
                         float h,float r,float m,float bss)
913 217 equemene
{
914 217 equemene
  float flx;
915 217 equemene

916 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
917 221 equemene
  flx=exp(q*log(r/m)+4.*log(rf))*b*db*h;
918 217 equemene
  return(flx);
919 217 equemene
}
920 217 equemene

921 217 equemene
__device__ float spectre_cn(float rf32,float b32,float db32,
922 234 equemene
                            float h32,float r32,float m32,float bss32)
923 217 equemene
{
924 234 equemene

925 217 equemene
#define MYFLOAT float
926 217 equemene

927 217 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
928 217 equemene
  MYFLOAT b=(MYFLOAT)(b32);
929 217 equemene
  MYFLOAT db=(MYFLOAT)(db32);
930 217 equemene
  MYFLOAT h=(MYFLOAT)(h32);
931 217 equemene
  MYFLOAT r=(MYFLOAT)(r32);
932 217 equemene
  MYFLOAT m=(MYFLOAT)(m32);
933 217 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
934 217 equemene

935 217 equemene
  MYFLOAT flx;
936 217 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
937 217 equemene
  int fi,posfreq;
938 217 equemene

939 217 equemene
#define planck 6.62e-34
940 217 equemene
#define k 1.38e-23
941 217 equemene
#define c2 9.e16
942 217 equemene
#define temp 3.e7
943 217 equemene
#define m_point 1.
944 217 equemene

945 217 equemene
#define lplanck (log(6.62)-34.*log(10.))
946 217 equemene
#define lk (log(1.38)-23.*log(10.))
947 217 equemene
#define lc2 (log(9.)+16.*log(10.))
948 217 equemene

949 217 equemene
  MYFLOAT v=1.-3./r;
950 217 equemene

951 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 ));
952 217 equemene

953 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)));
954 217 equemene

955 217 equemene
  flux_int=0.;
956 217 equemene
  flx=0.;
957 217 equemene

958 217 equemene
  for (fi=0;fi<nbr;fi++)
959 217 equemene
    {
960 217 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
961 217 equemene
      nu_rec=nu_em*rf;
962 217 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
963 217 equemene
      if ((posfreq>0)&&(posfreq<nbr))
964 234 equemene
        {
965 217 equemene
          // Initial version
966 234 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
967 217 equemene
          // Version with log used
968 234 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
969 234 equemene
          // flux_int*=pow(rf,3)*b*db*h;
970 234 equemene
          //flux_int*=exp(3.*log(rf))*b*db*h;
971 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;
972 217 equemene

973 234 equemene
          flx+=flux_int;
974 234 equemene
        }
975 217 equemene
    }
976 217 equemene

977 217 equemene
  return((float)(flx));
978 217 equemene
}
979 217 equemene

980 217 equemene
__device__ void impact(float phi,float r,float b,float tho,float m,
981 234 equemene
                       float *zp,float *fp,
982 234 equemene
                       int q,float db,
983 234 equemene
                       float h,int raie)
984 217 equemene
{
985 217 equemene
  float flx,rf,bss;
986 217 equemene

987 217 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
988 217 equemene

989 217 equemene
  if (raie==0)
990 217 equemene
    {
991 217 equemene
      bss=1.e19;
992 217 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
993 217 equemene
    }
994 217 equemene
  else
995 234 equemene
    {
996 217 equemene
      bss=2.;
997 217 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
998 217 equemene
    }
999 234 equemene

1000 217 equemene
  *zp=1./rf;
1001 217 equemene
  *fp=flx;
1002 217 equemene

1003 217 equemene
}
1004 217 equemene

1005 217 equemene
__global__ void EachPixel(float *zImage,float *fImage,
1006 217 equemene
                          float Mass,float InternalRadius,
1007 217 equemene
                          float ExternalRadius,float Angle,
1008 217 equemene
                          int Line)
1009 217 equemene
{
1010 218 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1011 218 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1012 217 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1013 217 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1014 217 equemene

1015 217 equemene
   // Perform trajectory for each pixel, exit on hit
1016 217 equemene

1017 217 equemene
  float m,rs,ri,re,tho;
1018 217 equemene
  int q,raie;
1019 217 equemene

1020 217 equemene
  m=Mass;
1021 217 equemene
  rs=2.*m;
1022 217 equemene
  ri=InternalRadius;
1023 217 equemene
  re=ExternalRadius;
1024 217 equemene
  tho=Angle;
1025 217 equemene
  q=-2;
1026 217 equemene
  raie=Line;
1027 217 equemene

1028 217 equemene
  float d,bmx,db,b,h;
1029 218 equemene
  float rp0,rpp,rps;
1030 217 equemene
  float phi,thi,phd,php,nr,r;
1031 217 equemene
  int nh;
1032 217 equemene
  float zp,fp;
1033 217 equemene

1034 217 equemene
  // Autosize for image
1035 217 equemene
  bmx=1.25*re;
1036 217 equemene
  b=0.;
1037 217 equemene

1038 217 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1039 217 equemene

1040 217 equemene
  // set origin as center of image
1041 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1042 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1043 217 equemene
  // angle extracted from cylindric symmetry
1044 217 equemene
  phi=atanp(x,y);
1045 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1046 217 equemene

1047 217 equemene
  float up,vp,pp,us,vs,ps;
1048 217 equemene

1049 217 equemene
  // impact parameter
1050 217 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
1051 217 equemene
  // step of impact parameter;
1052 217 equemene
//  db=bmx/(float)(sizex/2);
1053 217 equemene
  db=bmx/(float)(sizex);
1054 217 equemene

1055 217 equemene
  up=0.;
1056 217 equemene
  vp=1.;
1057 217 equemene
  pp=0.;
1058 217 equemene
  nh=0;
1059 217 equemene

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

1062 218 equemene
  rps=fabs(b/us);
1063 218 equemene
  rp0=rps;
1064 217 equemene

1065 217 equemene
  int ExitOnImpact=0;
1066 217 equemene

1067 217 equemene
  do
1068 217 equemene
  {
1069 217 equemene
     nh++;
1070 217 equemene
     pp=ps;
1071 217 equemene
     up=us;
1072 217 equemene
     vp=vs;
1073 218 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1074 234 equemene
     rpp=rps;
1075 218 equemene
     rps=fabs(b/us);
1076 218 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>ri)&&(rps<re)?1:0;
1077 217 equemene

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

1080 217 equemene
  if (ExitOnImpact==1) {
1081 218 equemene
     impact(phi,rpp,b,tho,m,&zp,&fp,q,db,h,raie);
1082 217 equemene
  }
1083 217 equemene
  else
1084 217 equemene
  {
1085 234 equemene
     zp=0.e0f;
1086 234 equemene
     fp=0.e0f;
1087 217 equemene
  }
1088 217 equemene

1089 218 equemene
  __syncthreads();
1090 218 equemene

1091 217 equemene
  zImage[yi+sizex*xi]=(float)zp;
1092 217 equemene
  fImage[yi+sizex*xi]=(float)fp;
1093 217 equemene
}
1094 217 equemene

1095 217 equemene
__global__ void Pixel(float *zImage,float *fImage,
1096 217 equemene
                      float *Trajectories,int *IdLast,
1097 224 equemene
                      uint ImpactParameter,
1098 217 equemene
                      float Mass,float InternalRadius,
1099 217 equemene
                      float ExternalRadius,float Angle,
1100 217 equemene
                      int Line)
1101 217 equemene
{
1102 219 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1103 219 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1104 219 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1105 219 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1106 217 equemene

1107 217 equemene
  // Perform trajectory for each pixel
1108 217 equemene

1109 217 equemene
  float m,rs,ri,re,tho;
1110 217 equemene
  int q,raie;
1111 217 equemene

1112 217 equemene
  m=Mass;
1113 234 equemene
  rs=2.e0f*m;
1114 217 equemene
  ri=InternalRadius;
1115 217 equemene
  re=ExternalRadius;
1116 217 equemene
  tho=Angle;
1117 217 equemene
  q=-2;
1118 217 equemene
  raie=Line;
1119 217 equemene

1120 217 equemene
  float d,bmx,db,b,h;
1121 217 equemene
  float phi,thi,phd,php,nr,r;
1122 217 equemene
  int nh;
1123 217 equemene
  float zp=0,fp=0;
1124 217 equemene
  // Autosize for image, 25% greater than external radius
1125 234 equemene
  bmx=1.25e0f*re;
1126 217 equemene

1127 217 equemene
  // Angular step of integration
1128 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1129 217 equemene

1130 217 equemene
  // Step of Impact Parameter
1131 234 equemene
  db=bmx/(2.e0f*(float)ImpactParameter);
1132 217 equemene

1133 217 equemene
  // set origin as center of image
1134 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1135 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1136 217 equemene
  // angle extracted from cylindric symmetry
1137 217 equemene
  phi=atanp(x,y);
1138 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1139 217 equemene

1140 217 equemene
  // Real Impact Parameter
1141 217 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
1142 217 equemene

1143 217 equemene
  // Integer Impact Parameter
1144 217 equemene
  uint bi=(uint)sqrt(x*x+y*y);
1145 217 equemene

1146 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1147 217 equemene

1148 217 equemene
  if (bi<ImpactParameter)
1149 217 equemene
  {
1150 217 equemene
    do
1151 217 equemene
    {
1152 217 equemene
      php=phd+(float)HalfLap*PI;
1153 217 equemene
      nr=php/h;
1154 217 equemene
      ni=(int)nr;
1155 217 equemene

1156 217 equemene
      if (ni<IdLast[bi])
1157 217 equemene
      {
1158 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1159 217 equemene
      }
1160 217 equemene
      else
1161 217 equemene
      {
1162 224 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1163 217 equemene
      }
1164 234 equemene

1165 217 equemene
      if ((r<=re)&&(r>=ri))
1166 217 equemene
      {
1167 217 equemene
        ExitOnImpact=1;
1168 217 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1169 217 equemene
      }
1170 234 equemene

1171 217 equemene
      HalfLap++;
1172 217 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
1173 217 equemene

1174 217 equemene
  }
1175 217 equemene

1176 217 equemene
  zImage[yi+sizex*xi]=zp;
1177 217 equemene
  fImage[yi+sizex*xi]=fp;
1178 217 equemene
}
1179 217 equemene

1180 217 equemene
__global__ void Circle(float *Trajectories,int *IdLast,
1181 217 equemene
                       float *zImage,float *fImage,
1182 217 equemene
                       float Mass,float InternalRadius,
1183 217 equemene
                       float ExternalRadius,float Angle,
1184 217 equemene
                       int Line)
1185 217 equemene
{
1186 234 equemene
   // Integer Impact Parameter ID
1187 219 equemene
   int bi=blockIdx.x*blockDim.x+threadIdx.x;
1188 217 equemene
   // Integer points on circle
1189 219 equemene
   int i=blockIdx.y*blockDim.y+threadIdx.y;
1190 217 equemene
   // Integer Impact Parameter Size (half of image)
1191 217 equemene
   int bmaxi=gridDim.x*blockDim.x;
1192 217 equemene
   // Integer Points on circle
1193 217 equemene
   int imx=gridDim.y*blockDim.y;
1194 217 equemene

1195 217 equemene
   // Perform trajectory for each pixel
1196 217 equemene

1197 217 equemene
  float m,rs,ri,re,tho;
1198 217 equemene
  int q,raie;
1199 217 equemene

1200 217 equemene
  m=Mass;
1201 234 equemene
  rs=2.e0f*m;
1202 217 equemene
  ri=InternalRadius;
1203 217 equemene
  re=ExternalRadius;
1204 217 equemene
  tho=Angle;
1205 217 equemene
  raie=Line;
1206 217 equemene

1207 217 equemene
  float bmx,db,b,h;
1208 217 equemene
  float phi,thi,phd;
1209 217 equemene
  int nh;
1210 217 equemene
  float zp=0,fp=0;
1211 217 equemene

1212 217 equemene
  // Autosize for image
1213 234 equemene
  bmx=1.25e0f*re;
1214 217 equemene

1215 217 equemene
  // Angular step of integration
1216 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1217 217 equemene

1218 217 equemene
  // impact parameter
1219 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1220 234 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1221 217 equemene

1222 234 equemene
  phi=2.e0f*PI/(float)imx*(float)i;
1223 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1224 217 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
1225 217 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
1226 217 equemene

1227 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1228 217 equemene
  float php,nr,r;
1229 217 equemene

1230 217 equemene
  do
1231 217 equemene
  {
1232 217 equemene
     php=phd+(float)HalfLap*PI;
1233 217 equemene
     nr=php/h;
1234 217 equemene
     ni=(int)nr;
1235 217 equemene

1236 217 equemene
     if (ni<IdLast[bi])
1237 217 equemene
     {
1238 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1239 217 equemene
     }
1240 217 equemene
     else
1241 217 equemene
     {
1242 234 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1243 217 equemene
     }
1244 234 equemene

1245 217 equemene
     if ((r<=re)&&(r>=ri))
1246 217 equemene
     {
1247 234 equemene
        ExitOnImpact=1;
1248 234 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1249 217 equemene
     }
1250 234 equemene

1251 217 equemene
     HalfLap++;
1252 217 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
1253 234 equemene

1254 217 equemene
  zImage[yi+2*bmaxi*xi]=zp;
1255 234 equemene
  fImage[yi+2*bmaxi*xi]=fp;
1256 217 equemene

1257 217 equemene
}
1258 217 equemene

1259 224 equemene
__global__ void Trajectory(float *Trajectories,int *IdLast,
1260 217 equemene
                           float Mass,float InternalRadius,
1261 217 equemene
                           float ExternalRadius,float Angle,
1262 217 equemene
                           int Line)
1263 217 equemene
{
1264 234 equemene
  // Integer Impact Parameter ID
1265 219 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1266 217 equemene
  // Integer Impact Parameter Size (half of image)
1267 217 equemene
  int bmaxi=gridDim.x*blockDim.x;
1268 217 equemene

1269 217 equemene
  // Perform trajectory for each pixel
1270 217 equemene

1271 217 equemene
  float m,rs,ri,re,tho;
1272 217 equemene
  int raie,q;
1273 217 equemene

1274 217 equemene
  m=Mass;
1275 234 equemene
  rs=2.e0f*m;
1276 217 equemene
  ri=InternalRadius;
1277 217 equemene
  re=ExternalRadius;
1278 217 equemene
  tho=Angle;
1279 217 equemene
  q=-2;
1280 217 equemene
  raie=Line;
1281 217 equemene

1282 217 equemene
  float d,bmx,db,b,h;
1283 217 equemene
  float phi,thi,phd,php,nr,r;
1284 217 equemene
  int nh;
1285 217 equemene
  float zp,fp;
1286 217 equemene

1287 217 equemene
  // Autosize for image
1288 234 equemene
  bmx=1.25e0f*re;
1289 217 equemene

1290 217 equemene
  // Angular step of integration
1291 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1292 217 equemene

1293 217 equemene
  // impact parameter
1294 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1295 217 equemene

1296 217 equemene
  float up,vp,pp,us,vs,ps;
1297 217 equemene

1298 234 equemene
  up=0.e0f;
1299 234 equemene
  vp=1.e0f;
1300 234 equemene
  pp=0.e0f;
1301 217 equemene
  nh=0;
1302 217 equemene

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

1305 217 equemene
  // b versus us
1306 217 equemene
  float bvus=fabs(b/us);
1307 217 equemene
  float bvus0=bvus;
1308 224 equemene
  Trajectories[bi*TRACKPOINTS+nh]=bvus;
1309 217 equemene

1310 217 equemene
  do
1311 217 equemene
  {
1312 217 equemene
     nh++;
1313 217 equemene
     pp=ps;
1314 217 equemene
     up=us;
1315 217 equemene
     vp=vs;
1316 217 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1317 217 equemene
     bvus=fabs(b/us);
1318 224 equemene
     Trajectories[bi*TRACKPOINTS+nh]=bvus;
1319 217 equemene

1320 217 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1321 217 equemene

1322 217 equemene
  IdLast[bi]=nh;
1323 217 equemene

1324 217 equemene
}
1325 224 equemene

1326 225 equemene
__global__ void EachCircle(float *zImage,float *fImage,
1327 225 equemene
                           float Mass,float InternalRadius,
1328 225 equemene
                           float ExternalRadius,float Angle,
1329 225 equemene
                           int Line)
1330 224 equemene
{
1331 234 equemene
  // Integer Impact Parameter ID
1332 224 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1333 224 equemene

1334 224 equemene
  // Integer Impact Parameter Size (half of image)
1335 224 equemene
  int bmaxi=gridDim.x*blockDim.x;
1336 224 equemene

1337 225 equemene
  float Trajectory[2048];
1338 224 equemene

1339 224 equemene
  // Perform trajectory for each pixel
1340 224 equemene

1341 224 equemene
  float m,rs,ri,re,tho;
1342 224 equemene
  int raie,q;
1343 224 equemene

1344 224 equemene
  m=Mass;
1345 224 equemene
  rs=2.*m;
1346 224 equemene
  ri=InternalRadius;
1347 224 equemene
  re=ExternalRadius;
1348 224 equemene
  tho=Angle;
1349 224 equemene
  q=-2;
1350 224 equemene
  raie=Line;
1351 224 equemene

1352 224 equemene
  float bmx,db,b,h;
1353 224 equemene
  int nh;
1354 224 equemene

1355 224 equemene
  // Autosize for image
1356 224 equemene
  bmx=1.25e0f*re;
1357 224 equemene

1358 224 equemene
  // Angular step of integration
1359 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1360 224 equemene

1361 224 equemene
  // impact parameter
1362 224 equemene
  b=(float)bi/(float)bmaxi*bmx;
1363 224 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1364 224 equemene

1365 224 equemene
  float up,vp,pp,us,vs,ps;
1366 224 equemene

1367 224 equemene
  up=0.;
1368 224 equemene
  vp=1.;
1369 224 equemene
  pp=0.;
1370 224 equemene
  nh=0;
1371 224 equemene

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

1374 224 equemene
  // b versus us
1375 224 equemene
  float bvus=fabs(b/us);
1376 224 equemene
  float bvus0=bvus;
1377 225 equemene
  Trajectory[nh]=bvus;
1378 224 equemene

1379 224 equemene
  do
1380 224 equemene
  {
1381 224 equemene
     nh++;
1382 224 equemene
     pp=ps;
1383 224 equemene
     up=us;
1384 224 equemene
     vp=vs;
1385 224 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1386 224 equemene
     bvus=fabs(b/us);
1387 225 equemene
     Trajectory[nh]=bvus;
1388 224 equemene

1389 224 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1390 224 equemene

1391 224 equemene
  int imx=(int)(16*bi);
1392 224 equemene

1393 224 equemene
  for (int i=0;i<imx;i++)
1394 224 equemene
  {
1395 224 equemene
     float zp=0,fp=0;
1396 224 equemene
     float phi=2.*PI/(float)imx*(float)i;
1397 224 equemene
     float phd=atanp(cos(phi)*sin(tho),cos(tho));
1398 224 equemene
     uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1399 224 equemene
     uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1400 224 equemene

1401 224 equemene
     int HalfLap=0,ExitOnImpact=0,ni;
1402 224 equemene
     float php,nr,r;
1403 224 equemene

1404 224 equemene
     do
1405 224 equemene
     {
1406 224 equemene
        php=phd+(float)HalfLap*PI;
1407 224 equemene
        nr=php/h;
1408 224 equemene
        ni=(int)nr;
1409 224 equemene

1410 224 equemene
        if (ni<nh)
1411 224 equemene
        {
1412 225 equemene
           r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1413 224 equemene
        }
1414 224 equemene
        else
1415 224 equemene
        {
1416 225 equemene
           r=Trajectory[ni];
1417 224 equemene
        }
1418 234 equemene

1419 224 equemene
        if ((r<=re)&&(r>=ri))
1420 224 equemene
        {
1421 224 equemene
           ExitOnImpact=1;
1422 224 equemene
           impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1423 224 equemene
        }
1424 234 equemene

1425 224 equemene
        HalfLap++;
1426 224 equemene

1427 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
1428 224 equemene

1429 224 equemene
   __syncthreads();
1430 224 equemene

1431 224 equemene
   zImage[yi+2*bmaxi*xi]=zp;
1432 224 equemene
   fImage[yi+2*bmaxi*xi]=fp;
1433 224 equemene

1434 224 equemene
  }
1435 234 equemene

1436 224 equemene
}
1437 225 equemene

1438 225 equemene
__global__ void Original(float *zImage,float *fImage,
1439 225 equemene
                         uint Size,float Mass,float InternalRadius,
1440 225 equemene
                         float ExternalRadius,float Angle,
1441 225 equemene
                         int Line)
1442 225 equemene
{
1443 225 equemene
   // Integer Impact Parameter Size (half of image)
1444 225 equemene
   uint bmaxi=(uint)Size;
1445 225 equemene

1446 225 equemene
   float Trajectory[TRACKPOINTS];
1447 225 equemene

1448 225 equemene
   // Perform trajectory for each pixel
1449 225 equemene

1450 225 equemene
   float m,rs,ri,re,tho;
1451 225 equemene
   int raie,q;
1452 225 equemene

1453 225 equemene
   m=Mass;
1454 234 equemene
   rs=2.e0f*m;
1455 225 equemene
   ri=InternalRadius;
1456 225 equemene
   re=ExternalRadius;
1457 225 equemene
   tho=Angle;
1458 225 equemene
   q=-2;
1459 225 equemene
   raie=Line;
1460 225 equemene

1461 225 equemene
   float bmx,db,b,h;
1462 225 equemene
   int nh;
1463 225 equemene

1464 225 equemene
   // Autosize for image
1465 225 equemene
   bmx=1.25e0f*re;
1466 225 equemene

1467 225 equemene
   // Angular step of integration
1468 225 equemene
   h=4.e0f*PI/(float)TRACKPOINTS;
1469 225 equemene

1470 234 equemene
   // Integer Impact Parameter ID
1471 225 equemene
   for (int bi=0;bi<bmaxi;bi++)
1472 225 equemene
   {
1473 225 equemene
      // impact parameter
1474 225 equemene
      b=(float)bi/(float)bmaxi*bmx;
1475 225 equemene
      db=bmx/(2.e0f*(float)bmaxi);
1476 225 equemene

1477 225 equemene
      float up,vp,pp,us,vs,ps;
1478 225 equemene

1479 225 equemene
      up=0.;
1480 225 equemene
      vp=1.;
1481 225 equemene
      pp=0.;
1482 225 equemene
      nh=0;
1483 225 equemene

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

1486 225 equemene
      // b versus us
1487 225 equemene
      float bvus=fabs(b/us);
1488 225 equemene
      float bvus0=bvus;
1489 225 equemene
      Trajectory[nh]=bvus;
1490 225 equemene

1491 225 equemene
      do
1492 225 equemene
      {
1493 225 equemene
         nh++;
1494 225 equemene
         pp=ps;
1495 225 equemene
         up=us;
1496 225 equemene
         vp=vs;
1497 225 equemene
         rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1498 225 equemene
         bvus=fabs(b/us);
1499 225 equemene
         Trajectory[nh]=bvus;
1500 225 equemene

1501 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
1502 225 equemene

1503 225 equemene
      for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
1504 225 equemene
         Trajectory[i]=0.e0f;
1505 225 equemene
      }
1506 225 equemene

1507 225 equemene
      int imx=(int)(16*bi);
1508 225 equemene

1509 225 equemene
      for (int i=0;i<imx;i++)
1510 225 equemene
      {
1511 225 equemene
         float zp=0,fp=0;
1512 225 equemene
         float phi=2.e0f*PI/(float)imx*(float)i;
1513 225 equemene
         float phd=atanp(cos(phi)*sin(tho),cos(tho));
1514 225 equemene
         uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1515 225 equemene
         uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1516 225 equemene

1517 225 equemene
         int HalfLap=0,ExitOnImpact=0,ni;
1518 225 equemene
         float php,nr,r;
1519 225 equemene

1520 225 equemene
         do
1521 225 equemene
         {
1522 225 equemene
            php=phd+(float)HalfLap*PI;
1523 225 equemene
            nr=php/h;
1524 225 equemene
            ni=(int)nr;
1525 225 equemene

1526 225 equemene
            if (ni<nh)
1527 225 equemene
            {
1528 225 equemene
               r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1529 225 equemene
            }
1530 225 equemene
            else
1531 225 equemene
            {
1532 225 equemene
               r=Trajectory[ni];
1533 225 equemene
            }
1534 234 equemene

1535 225 equemene
            if ((r<=re)&&(r>=ri))
1536 225 equemene
            {
1537 225 equemene
               ExitOnImpact=1;
1538 225 equemene
               impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1539 225 equemene
            }
1540 234 equemene

1541 225 equemene
            HalfLap++;
1542 234 equemene

1543 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
1544 234 equemene

1545 225 equemene
         zImage[yi+2*bmaxi*xi]=zp;
1546 225 equemene
         fImage[yi+2*bmaxi*xi]=fp;
1547 234 equemene

1548 225 equemene
      }
1549 225 equemene

1550 234 equemene
   }
1551 234 equemene

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