Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 222

Historique | Voir | Annoter | Télécharger (39,17 ko)

1 221 equemene
#!/usr/bin/env python
2 199 equemene
#
3 199 equemene
# TrouNoir model using PyOpenCL
4 199 equemene
#
5 204 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 199 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 204 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 199 equemene
import pyopencl as cl
29 199 equemene
import numpy
30 199 equemene
import time,string
31 199 equemene
from numpy.random import randint as nprnd
32 199 equemene
import sys
33 199 equemene
import getopt
34 199 equemene
import matplotlib.pyplot as plt
35 211 equemene
from socket import gethostname
36 199 equemene
37 211 equemene
def DictionariesAPI():
38 211 equemene
    PhysicsList={'Einstein':0,'Newton':1}
39 211 equemene
    return(PhysicsList)
40 204 equemene
41 211 equemene
BlobOpenCL= """
42 204 equemene

43 199 equemene
#define PI (float)3.14159265359
44 209 equemene
#define nbr 256
45 199 equemene

46 211 equemene
#define EINSTEIN 0
47 211 equemene
#define NEWTON 1
48 211 equemene

49 217 equemene
#define TRACKPOINTS 2048
50 217 equemene

51 199 equemene
float atanp(float x,float y)
52 199 equemene
{
53 199 equemene
  float angle;
54 199 equemene

55 199 equemene
  angle=atan2(y,x);
56 199 equemene

57 204 equemene
  if (angle<0.e0f)
58 199 equemene
    {
59 199 equemene
      angle+=(float)2.e0f*PI;
60 199 equemene
    }
61 199 equemene

62 199 equemene
  return angle;
63 199 equemene
}
64 199 equemene

65 199 equemene
float f(float v)
66 199 equemene
{
67 199 equemene
  return v;
68 199 equemene
}
69 199 equemene

70 211 equemene
#if PHYSICS == NEWTON
71 199 equemene
float g(float u,float m,float b)
72 199 equemene
{
73 211 equemene
  return (-u);
74 211 equemene
}
75 211 equemene
#else
76 211 equemene
float g(float u,float m,float b)
77 211 equemene
{
78 204 equemene
  return (3.e0f*m/b*pow(u,2)-u);
79 199 equemene
}
80 211 equemene
#endif
81 199 equemene

82 199 equemene
void calcul(float *us,float *vs,float up,float vp,
83 199 equemene
            float h,float m,float b)
84 199 equemene
{
85 199 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
86 199 equemene

87 199 equemene
  c0=h*f(vp);
88 199 equemene
  c1=h*f(vp+c0/2.);
89 199 equemene
  c2=h*f(vp+c1/2.);
90 199 equemene
  c3=h*f(vp+c2);
91 199 equemene
  d0=h*g(up,m,b);
92 199 equemene
  d1=h*g(up+d0/2.,m,b);
93 199 equemene
  d2=h*g(up+d1/2.,m,b);
94 199 equemene
  d3=h*g(up+d2,m,b);
95 199 equemene

96 199 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
97 199 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
98 199 equemene
}
99 199 equemene

100 199 equemene
void rungekutta(float *ps,float *us,float *vs,
101 199 equemene
                float pp,float up,float vp,
102 199 equemene
                float h,float m,float b)
103 199 equemene
{
104 199 equemene
  calcul(us,vs,up,vp,h,m,b);
105 199 equemene
  *ps=pp+h;
106 199 equemene
}
107 199 equemene

108 199 equemene
float decalage_spectral(float r,float b,float phi,
109 199 equemene
                         float tho,float m)
110 199 equemene
{
111 199 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
112 199 equemene
}
113 199 equemene

114 199 equemene
float spectre(float rf,int q,float b,float db,
115 199 equemene
             float h,float r,float m,float bss)
116 199 equemene
{
117 199 equemene
  float flx;
118 199 equemene

119 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
120 221 equemene
  flx=exp(q*log(r/m)+4.*log(rf))*b*db*h;
121 199 equemene
  return(flx);
122 199 equemene
}
123 199 equemene

124 209 equemene
float spectre_cn(float rf32,float b32,float db32,
125 209 equemene
                 float h32,float r32,float m32,float bss32)
126 199 equemene
{
127 209 equemene

128 213 equemene
#define MYFLOAT float
129 209 equemene

130 209 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
131 209 equemene
  MYFLOAT b=(MYFLOAT)(b32);
132 209 equemene
  MYFLOAT db=(MYFLOAT)(db32);
133 209 equemene
  MYFLOAT h=(MYFLOAT)(h32);
134 209 equemene
  MYFLOAT r=(MYFLOAT)(r32);
135 209 equemene
  MYFLOAT m=(MYFLOAT)(m32);
136 209 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
137 209 equemene

138 209 equemene
  MYFLOAT flx;
139 209 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
140 199 equemene
  int fi,posfreq;
141 199 equemene

142 209 equemene
#define planck 6.62e-34
143 209 equemene
#define k 1.38e-23
144 209 equemene
#define c2 9.e16
145 209 equemene
#define temp 3.e7
146 209 equemene
#define m_point 1.
147 199 equemene

148 209 equemene
#define lplanck (log(6.62)-34.*log(10.))
149 209 equemene
#define lk (log(1.38)-23.*log(10.))
150 209 equemene
#define lc2 (log(9.)+16.*log(10.))
151 199 equemene

152 209 equemene
  MYFLOAT v=1.-3./r;
153 199 equemene

154 209 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 ));
155 199 equemene

156 209 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)));
157 209 equemene

158 209 equemene
  flux_int=0.;
159 209 equemene
  flx=0.;
160 209 equemene

161 201 equemene
  for (fi=0;fi<nbr;fi++)
162 199 equemene
    {
163 209 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
164 209 equemene
      nu_rec=nu_em*rf;
165 209 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
166 199 equemene
      if ((posfreq>0)&&(posfreq<nbr))
167 199 equemene
        {
168 209 equemene
          // Initial version
169 211 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
170 209 equemene
          // Version with log used
171 211 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
172 211 equemene
          // flux_int*=pow(rf,3)*b*db*h;
173 211 equemene
          //flux_int*=exp(3.*log(rf))*b*db*h;
174 211 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;
175 211 equemene

176 199 equemene
          flx+=flux_int;
177 199 equemene
        }
178 199 equemene
    }
179 209 equemene

180 209 equemene
  return((float)(flx));
181 199 equemene
}
182 199 equemene

183 199 equemene
void impact(float phi,float r,float b,float tho,float m,
184 199 equemene
            float *zp,float *fp,
185 199 equemene
            int q,float db,
186 204 equemene
            float h,int raie)
187 199 equemene
{
188 204 equemene
  float flx,rf,bss;
189 199 equemene

190 199 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
191 199 equemene

192 199 equemene
  if (raie==0)
193 199 equemene
    {
194 209 equemene
      bss=1.e19;
195 209 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
196 209 equemene
    }
197 209 equemene
  else
198 209 equemene
    {
199 204 equemene
      bss=2.;
200 199 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
201 199 equemene
    }
202 199 equemene

203 199 equemene
  *zp=1./rf;
204 199 equemene
  *fp=flx;
205 199 equemene

206 199 equemene
}
207 199 equemene

208 204 equemene
__kernel void EachPixel(__global float *zImage,__global float *fImage,
209 204 equemene
                        float Mass,float InternalRadius,
210 204 equemene
                        float ExternalRadius,float Angle,
211 209 equemene
                        int Line)
212 199 equemene
{
213 199 equemene
   uint xi=(uint)get_global_id(0);
214 199 equemene
   uint yi=(uint)get_global_id(1);
215 199 equemene
   uint sizex=(uint)get_global_size(0);
216 199 equemene
   uint sizey=(uint)get_global_size(1);
217 199 equemene

218 204 equemene
   // Perform trajectory for each pixel, exit on hit
219 199 equemene

220 217 equemene
  private float m,rs,ri,re,tho;
221 217 equemene
  private int q,raie;
222 199 equemene

223 204 equemene
  m=Mass;
224 204 equemene
  rs=2.*m;
225 204 equemene
  ri=InternalRadius;
226 204 equemene
  re=ExternalRadius;
227 204 equemene
  tho=Angle;
228 204 equemene
  q=-2;
229 209 equemene
  raie=Line;
230 204 equemene

231 217 equemene
  private float d,bmx,db,b,h;
232 218 equemene
  private float rp0,rpp,rps;
233 217 equemene
  private float phi,thi,phd,php,nr,r;
234 217 equemene
  private int nh;
235 217 equemene
  private float zp,fp;
236 199 equemene

237 199 equemene
  // Autosize for image
238 199 equemene
  bmx=1.25*re;
239 199 equemene
  b=0.;
240 199 equemene

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

243 199 equemene
  // set origin as center of image
244 199 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
245 201 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
246 199 equemene
  // angle extracted from cylindric symmetry
247 199 equemene
  phi=atanp(x,y);
248 199 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
249 199 equemene

250 204 equemene
  float up,vp,pp,us,vs,ps;
251 204 equemene

252 204 equemene
  // impact parameter
253 204 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
254 204 equemene
  // step of impact parameter;
255 209 equemene
  db=bmx/(float)(sizex);
256 204 equemene

257 209 equemene
  up=0.;
258 209 equemene
  vp=1.;
259 199 equemene

260 199 equemene
  pp=0.;
261 199 equemene
  nh=0;
262 199 equemene

263 199 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
264 199 equemene

265 218 equemene
  rps=fabs(b/us);
266 218 equemene
  rp0=rps;
267 199 equemene

268 204 equemene
  int ExitOnImpact=0;
269 199 equemene

270 199 equemene
  do
271 199 equemene
  {
272 199 equemene
     nh++;
273 199 equemene
     pp=ps;
274 199 equemene
     up=us;
275 199 equemene
     vp=vs;
276 218 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
277 218 equemene
     rpp=rps;
278 218 equemene
     rps=fabs(b/us);
279 218 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>ri)&&(rps<re)?1:0;
280 199 equemene

281 218 equemene
  } while ((rps>=rs)&&(rps<=rp0)&&(ExitOnImpact==0));
282 199 equemene

283 199 equemene
  if (ExitOnImpact==1) {
284 218 equemene
     impact(phi,rpp,b,tho,m,&zp,&fp,q,db,h,raie);
285 199 equemene
  }
286 199 equemene
  else
287 199 equemene
  {
288 199 equemene
     zp=0.;
289 201 equemene
     fp=0.;
290 199 equemene
  }
291 199 equemene

292 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
293 204 equemene

294 201 equemene
  zImage[yi+sizex*xi]=(float)zp;
295 204 equemene
  fImage[yi+sizex*xi]=(float)fp;
296 204 equemene
}
297 199 equemene

298 204 equemene
__kernel void Pixel(__global float *zImage,__global float *fImage,
299 204 equemene
                    __global float *Trajectories,__global int *IdLast,
300 204 equemene
                    uint ImpactParameter,uint TrackPoints,
301 204 equemene
                    float Mass,float InternalRadius,
302 204 equemene
                    float ExternalRadius,float Angle,
303 209 equemene
                    int Line)
304 204 equemene
{
305 204 equemene
   uint xi=(uint)get_global_id(0);
306 204 equemene
   uint yi=(uint)get_global_id(1);
307 204 equemene
   uint sizex=(uint)get_global_size(0);
308 204 equemene
   uint sizey=(uint)get_global_size(1);
309 204 equemene

310 204 equemene
   // Perform trajectory for each pixel
311 204 equemene

312 209 equemene
  float m,rs,ri,re,tho;
313 209 equemene
  int q,raie;
314 204 equemene

315 204 equemene
  m=Mass;
316 204 equemene
  rs=2.*m;
317 204 equemene
  ri=InternalRadius;
318 204 equemene
  re=ExternalRadius;
319 204 equemene
  tho=Angle;
320 204 equemene
  q=-2;
321 209 equemene
  raie=Line;
322 204 equemene

323 204 equemene
  float d,bmx,db,b,h;
324 204 equemene
  float phi,thi,phd,php,nr,r;
325 204 equemene
  int nh;
326 204 equemene
  float zp=0,fp=0;
327 204 equemene

328 209 equemene
  // Autosize for image, 25% greater than external radius
329 204 equemene
  bmx=1.25*re;
330 204 equemene

331 204 equemene
  // Angular step of integration
332 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
333 204 equemene

334 204 equemene
  // Step of Impact Parameter
335 209 equemene
  db=bmx/(2.e0*(float)ImpactParameter);
336 204 equemene

337 204 equemene
  // set origin as center of image
338 204 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
339 204 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
340 204 equemene

341 204 equemene
  // angle extracted from cylindric symmetry
342 204 equemene
  phi=atanp(x,y);
343 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
344 204 equemene

345 204 equemene
  // Real Impact Parameter
346 204 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
347 204 equemene

348 204 equemene
  // Integer Impact Parameter
349 204 equemene
  uint bi=(uint)sqrt(x*x+y*y);
350 204 equemene

351 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
352 204 equemene

353 204 equemene
  if (bi<ImpactParameter)
354 204 equemene
  {
355 204 equemene
    do
356 204 equemene
    {
357 204 equemene
      php=phd+(float)HalfLap*PI;
358 204 equemene
      nr=php/h;
359 204 equemene
      ni=(int)nr;
360 204 equemene

361 204 equemene
      if (ni<IdLast[bi])
362 204 equemene
      {
363 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
364 204 equemene
      }
365 204 equemene
      else
366 204 equemene
      {
367 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
368 204 equemene
      }
369 204 equemene

370 204 equemene
      if ((r<=re)&&(r>=ri))
371 204 equemene
      {
372 204 equemene
        ExitOnImpact=1;
373 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
374 204 equemene
      }
375 204 equemene

376 204 equemene
      HalfLap++;
377 204 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
378 204 equemene

379 204 equemene
  }
380 204 equemene

381 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
382 204 equemene

383 204 equemene
  zImage[yi+sizex*xi]=zp;
384 204 equemene
  fImage[yi+sizex*xi]=fp;
385 204 equemene
}
386 204 equemene

387 204 equemene
__kernel void Circle(__global float *Trajectories,__global int *IdLast,
388 204 equemene
                     __global float *zImage,__global float *fImage,
389 204 equemene
                     int TrackPoints,
390 204 equemene
                     float Mass,float InternalRadius,
391 204 equemene
                     float ExternalRadius,float Angle,
392 209 equemene
                     int Line)
393 204 equemene
{
394 204 equemene
   // Integer Impact Parameter ID
395 204 equemene
   int bi=get_global_id(0);
396 204 equemene
   // Integer points on circle
397 204 equemene
   int i=get_global_id(1);
398 204 equemene
   // Integer Impact Parameter Size (half of image)
399 204 equemene
   int bmaxi=get_global_size(0);
400 204 equemene
   // Integer Points on circle
401 204 equemene
   int imx=get_global_size(1);
402 204 equemene

403 204 equemene
   // Perform trajectory for each pixel
404 204 equemene

405 209 equemene
  float m,rs,ri,re,tho;
406 209 equemene
  int q,raie;
407 204 equemene

408 204 equemene
  m=Mass;
409 204 equemene
  rs=2.*m;
410 204 equemene
  ri=InternalRadius;
411 204 equemene
  re=ExternalRadius;
412 204 equemene
  tho=Angle;
413 209 equemene
  raie=Line;
414 204 equemene

415 204 equemene
  float bmx,db,b,h;
416 204 equemene
  float phi,thi,phd;
417 204 equemene
  int nh;
418 204 equemene
  float zp=0,fp=0;
419 204 equemene

420 204 equemene
  // Autosize for image
421 204 equemene
  bmx=1.25*re;
422 204 equemene

423 204 equemene
  // Angular step of integration
424 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
425 204 equemene

426 204 equemene
  // impact parameter
427 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
428 209 equemene
  db=bmx/(2.e0*(float)bmaxi);
429 204 equemene

430 204 equemene
  phi=2.*PI/(float)imx*(float)i;
431 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
432 204 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
433 204 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
434 204 equemene

435 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
436 204 equemene
  float php,nr,r;
437 204 equemene

438 204 equemene
  do
439 204 equemene
  {
440 204 equemene
     php=phd+(float)HalfLap*PI;
441 204 equemene
     nr=php/h;
442 204 equemene
     ni=(int)nr;
443 204 equemene

444 204 equemene
     if (ni<IdLast[bi])
445 204 equemene
     {
446 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
447 204 equemene
     }
448 204 equemene
     else
449 204 equemene
     {
450 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
451 204 equemene
     }
452 204 equemene

453 204 equemene
     if ((r<=re)&&(r>=ri))
454 204 equemene
     {
455 204 equemene
        ExitOnImpact=1;
456 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
457 204 equemene
     }
458 204 equemene

459 204 equemene
     HalfLap++;
460 204 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
461 204 equemene

462 204 equemene
  zImage[yi+2*bmaxi*xi]=zp;
463 204 equemene
  fImage[yi+2*bmaxi*xi]=fp;
464 204 equemene

465 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
466 204 equemene

467 204 equemene
}
468 204 equemene

469 204 equemene
__kernel void Trajectory(__global float *Trajectories,
470 204 equemene
                         __global int *IdLast,int TrackPoints,
471 204 equemene
                         float Mass,float InternalRadius,
472 204 equemene
                         float ExternalRadius,float Angle,
473 209 equemene
                         int Line)
474 204 equemene
{
475 204 equemene
  // Integer Impact Parameter ID
476 204 equemene
  int bi=get_global_id(0);
477 204 equemene
  // Integer Impact Parameter Size (half of image)
478 204 equemene
  int bmaxi=get_global_size(0);
479 204 equemene

480 204 equemene
  // Perform trajectory for each pixel
481 204 equemene

482 209 equemene
  float m,rs,ri,re,tho;
483 209 equemene
  int raie,q;
484 204 equemene

485 204 equemene
  m=Mass;
486 204 equemene
  rs=2.*m;
487 204 equemene
  ri=InternalRadius;
488 204 equemene
  re=ExternalRadius;
489 204 equemene
  tho=Angle;
490 204 equemene
  q=-2;
491 209 equemene
  raie=Line;
492 204 equemene

493 204 equemene
  float d,bmx,db,b,h;
494 204 equemene
  float phi,thi,phd,php,nr,r;
495 204 equemene
  int nh;
496 204 equemene
  float zp,fp;
497 204 equemene

498 204 equemene
  // Autosize for image
499 204 equemene
  bmx=1.25*re;
500 204 equemene

501 204 equemene
  // Angular step of integration
502 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
503 204 equemene

504 204 equemene
  // impact parameter
505 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
506 204 equemene

507 204 equemene
  float up,vp,pp,us,vs,ps;
508 204 equemene

509 209 equemene
  up=0.;
510 209 equemene
  vp=1.;
511 204 equemene

512 204 equemene
  pp=0.;
513 204 equemene
  nh=0;
514 204 equemene

515 204 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
516 204 equemene

517 204 equemene
  // b versus us
518 204 equemene
  float bvus=fabs(b/us);
519 204 equemene
  float bvus0=bvus;
520 204 equemene
  Trajectories[bi*TrackPoints+nh]=bvus;
521 204 equemene

522 204 equemene
  do
523 204 equemene
  {
524 204 equemene
     nh++;
525 204 equemene
     pp=ps;
526 204 equemene
     up=us;
527 204 equemene
     vp=vs;
528 204 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
529 204 equemene
     bvus=fabs(b/us);
530 204 equemene
     Trajectories[bi*TrackPoints+nh]=bvus;
531 204 equemene

532 204 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
533 204 equemene

534 204 equemene
  IdLast[bi]=nh;
535 204 equemene

536 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
537 199 equemene

538 199 equemene
}
539 211 equemene
"""
540 199 equemene
541 217 equemene
def KernelCodeCuda():
542 217 equemene
    BlobCUDA= """
543 217 equemene

544 217 equemene
#define PI (float)3.14159265359
545 217 equemene
#define nbr 256
546 217 equemene

547 217 equemene
#define EINSTEIN 0
548 217 equemene
#define NEWTON 1
549 217 equemene

550 217 equemene
#define TRACKPOINTS 2048
551 217 equemene

552 217 equemene
__device__ float nothing(float x)
553 217 equemene
{
554 217 equemene
  return(x);
555 217 equemene
}
556 217 equemene

557 217 equemene
__device__ float atanp(float x,float y)
558 217 equemene
{
559 217 equemene
  float angle;
560 217 equemene

561 217 equemene
  angle=atan2(y,x);
562 217 equemene

563 217 equemene
  if (angle<0.e0f)
564 217 equemene
    {
565 217 equemene
      angle+=(float)2.e0f*PI;
566 217 equemene
    }
567 217 equemene

568 217 equemene
  return(angle);
569 217 equemene
}
570 217 equemene

571 217 equemene
__device__ float f(float v)
572 217 equemene
{
573 217 equemene
  return(v);
574 217 equemene
}
575 217 equemene

576 217 equemene
#if PHYSICS == NEWTON
577 217 equemene
__device__ float g(float u,float m,float b)
578 217 equemene
{
579 217 equemene
  return (-u);
580 217 equemene
}
581 217 equemene
#else
582 217 equemene
__device__ float g(float u,float m,float b)
583 217 equemene
{
584 217 equemene
  return (3.e0f*m/b*pow(u,2)-u);
585 217 equemene
}
586 217 equemene
#endif
587 217 equemene

588 217 equemene
__device__ void calcul(float *us,float *vs,float up,float vp,
589 217 equemene
                       float h,float m,float b)
590 217 equemene
{
591 217 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
592 217 equemene

593 217 equemene
  c0=h*f(vp);
594 217 equemene
  c1=h*f(vp+c0/2.);
595 217 equemene
  c2=h*f(vp+c1/2.);
596 217 equemene
  c3=h*f(vp+c2);
597 217 equemene
  d0=h*g(up,m,b);
598 217 equemene
  d1=h*g(up+d0/2.,m,b);
599 217 equemene
  d2=h*g(up+d1/2.,m,b);
600 217 equemene
  d3=h*g(up+d2,m,b);
601 217 equemene

602 217 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
603 217 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
604 217 equemene
}
605 217 equemene

606 217 equemene
__device__ void rungekutta(float *ps,float *us,float *vs,
607 217 equemene
                           float pp,float up,float vp,
608 217 equemene
                           float h,float m,float b)
609 217 equemene
{
610 217 equemene
  calcul(us,vs,up,vp,h,m,b);
611 217 equemene
  *ps=pp+h;
612 217 equemene
}
613 217 equemene

614 217 equemene
__device__ float decalage_spectral(float r,float b,float phi,
615 217 equemene
                                   float tho,float m)
616 217 equemene
{
617 217 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
618 217 equemene
}
619 217 equemene

620 217 equemene
__device__ float spectre(float rf,int q,float b,float db,
621 217 equemene
                         float h,float r,float m,float bss)
622 217 equemene
{
623 217 equemene
  float flx;
624 217 equemene

625 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
626 221 equemene
  flx=exp(q*log(r/m)+4.*log(rf))*b*db*h;
627 217 equemene
  return(flx);
628 217 equemene
}
629 217 equemene

630 217 equemene
__device__ float spectre_cn(float rf32,float b32,float db32,
631 217 equemene
                            float h32,float r32,float m32,float bss32)
632 217 equemene
{
633 217 equemene

634 217 equemene
#define MYFLOAT float
635 217 equemene

636 217 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
637 217 equemene
  MYFLOAT b=(MYFLOAT)(b32);
638 217 equemene
  MYFLOAT db=(MYFLOAT)(db32);
639 217 equemene
  MYFLOAT h=(MYFLOAT)(h32);
640 217 equemene
  MYFLOAT r=(MYFLOAT)(r32);
641 217 equemene
  MYFLOAT m=(MYFLOAT)(m32);
642 217 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
643 217 equemene

644 217 equemene
  MYFLOAT flx;
645 217 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
646 217 equemene
  int fi,posfreq;
647 217 equemene

648 217 equemene
#define planck 6.62e-34
649 217 equemene
#define k 1.38e-23
650 217 equemene
#define c2 9.e16
651 217 equemene
#define temp 3.e7
652 217 equemene
#define m_point 1.
653 217 equemene

654 217 equemene
#define lplanck (log(6.62)-34.*log(10.))
655 217 equemene
#define lk (log(1.38)-23.*log(10.))
656 217 equemene
#define lc2 (log(9.)+16.*log(10.))
657 217 equemene

658 217 equemene
  MYFLOAT v=1.-3./r;
659 217 equemene

660 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 ));
661 217 equemene

662 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)));
663 217 equemene

664 217 equemene
  flux_int=0.;
665 217 equemene
  flx=0.;
666 217 equemene

667 217 equemene
  for (fi=0;fi<nbr;fi++)
668 217 equemene
    {
669 217 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
670 217 equemene
      nu_rec=nu_em*rf;
671 217 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
672 217 equemene
      if ((posfreq>0)&&(posfreq<nbr))
673 217 equemene
        {
674 217 equemene
          // Initial version
675 217 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
676 217 equemene
          // Version with log used
677 217 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
678 217 equemene
          // flux_int*=pow(rf,3)*b*db*h;
679 217 equemene
          //flux_int*=exp(3.*log(rf))*b*db*h;
680 217 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;
681 217 equemene

682 217 equemene
          flx+=flux_int;
683 217 equemene
        }
684 217 equemene
    }
685 217 equemene

686 217 equemene
  return((float)(flx));
687 217 equemene
}
688 217 equemene

689 217 equemene
__device__ void impact(float phi,float r,float b,float tho,float m,
690 217 equemene
                       float *zp,float *fp,
691 217 equemene
                       int q,float db,
692 217 equemene
                       float h,int raie)
693 217 equemene
{
694 217 equemene
  float flx,rf,bss;
695 217 equemene

696 217 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
697 217 equemene

698 217 equemene
  if (raie==0)
699 217 equemene
    {
700 217 equemene
      bss=1.e19;
701 217 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
702 217 equemene
    }
703 217 equemene
  else
704 217 equemene
    {
705 217 equemene
      bss=2.;
706 217 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
707 217 equemene
    }
708 217 equemene

709 217 equemene
  *zp=1./rf;
710 217 equemene
  *fp=flx;
711 217 equemene

712 217 equemene
}
713 217 equemene

714 217 equemene
__global__ void EachPixel(float *zImage,float *fImage,
715 217 equemene
                          float Mass,float InternalRadius,
716 217 equemene
                          float ExternalRadius,float Angle,
717 217 equemene
                          int Line)
718 217 equemene
{
719 218 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
720 218 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
721 217 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
722 217 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
723 217 equemene

724 217 equemene
   // Perform trajectory for each pixel, exit on hit
725 217 equemene

726 217 equemene
  float m,rs,ri,re,tho;
727 217 equemene
  int q,raie;
728 217 equemene

729 217 equemene
  m=Mass;
730 217 equemene
  rs=2.*m;
731 217 equemene
  ri=InternalRadius;
732 217 equemene
  re=ExternalRadius;
733 217 equemene
  tho=Angle;
734 217 equemene
  q=-2;
735 217 equemene
  raie=Line;
736 217 equemene

737 217 equemene
  float d,bmx,db,b,h;
738 218 equemene
  float rp0,rpp,rps;
739 217 equemene
  float phi,thi,phd,php,nr,r;
740 217 equemene
  int nh;
741 217 equemene
  float zp,fp;
742 217 equemene

743 217 equemene
  // Autosize for image
744 217 equemene
  bmx=1.25*re;
745 217 equemene
  b=0.;
746 217 equemene

747 217 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
748 217 equemene

749 217 equemene
  // set origin as center of image
750 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
751 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
752 217 equemene
  // angle extracted from cylindric symmetry
753 217 equemene
  phi=atanp(x,y);
754 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
755 217 equemene

756 217 equemene
  float up,vp,pp,us,vs,ps;
757 217 equemene

758 217 equemene
  // impact parameter
759 217 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
760 217 equemene
  // step of impact parameter;
761 217 equemene
//  db=bmx/(float)(sizex/2);
762 217 equemene
  db=bmx/(float)(sizex);
763 217 equemene

764 217 equemene
  up=0.;
765 217 equemene
  vp=1.;
766 217 equemene

767 217 equemene
  pp=0.;
768 217 equemene
  nh=0;
769 217 equemene

770 217 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
771 217 equemene

772 218 equemene
  rps=fabs(b/us);
773 218 equemene
  rp0=rps;
774 217 equemene

775 217 equemene
  int ExitOnImpact=0;
776 217 equemene

777 217 equemene
  do
778 217 equemene
  {
779 217 equemene
     nh++;
780 217 equemene
     pp=ps;
781 217 equemene
     up=us;
782 217 equemene
     vp=vs;
783 218 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
784 218 equemene
     rpp=rps;
785 218 equemene
     rps=fabs(b/us);
786 218 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>ri)&&(rps<re)?1:0;
787 217 equemene

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

790 217 equemene
  if (ExitOnImpact==1) {
791 218 equemene
     impact(phi,rpp,b,tho,m,&zp,&fp,q,db,h,raie);
792 217 equemene
  }
793 217 equemene
  else
794 217 equemene
  {
795 217 equemene
     zp=0.;
796 217 equemene
     fp=0.;
797 217 equemene
  }
798 217 equemene

799 218 equemene
  __syncthreads();
800 218 equemene

801 217 equemene
  zImage[yi+sizex*xi]=(float)zp;
802 217 equemene
  fImage[yi+sizex*xi]=(float)fp;
803 217 equemene
}
804 217 equemene

805 217 equemene
__global__ void Pixel(float *zImage,float *fImage,
806 217 equemene
                      float *Trajectories,int *IdLast,
807 217 equemene
                      uint ImpactParameter,uint TrackPoints,
808 217 equemene
                      float Mass,float InternalRadius,
809 217 equemene
                      float ExternalRadius,float Angle,
810 217 equemene
                      int Line)
811 217 equemene
{
812 219 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
813 219 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
814 219 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
815 219 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
816 217 equemene

817 217 equemene
  // Perform trajectory for each pixel
818 217 equemene

819 217 equemene
  float m,rs,ri,re,tho;
820 217 equemene
  int q,raie;
821 217 equemene

822 217 equemene
  m=Mass;
823 217 equemene
  rs=2.*m;
824 217 equemene
  ri=InternalRadius;
825 217 equemene
  re=ExternalRadius;
826 217 equemene
  tho=Angle;
827 217 equemene
  q=-2;
828 217 equemene
  raie=Line;
829 217 equemene

830 217 equemene
  float d,bmx,db,b,h;
831 217 equemene
  float phi,thi,phd,php,nr,r;
832 217 equemene
  int nh;
833 217 equemene
  float zp=0,fp=0;
834 217 equemene
  // Autosize for image, 25% greater than external radius
835 217 equemene
  bmx=1.25*re;
836 217 equemene

837 217 equemene
  // Angular step of integration
838 217 equemene
  h=4.e0f*PI/(float)TrackPoints;
839 217 equemene

840 217 equemene
  // Step of Impact Parameter
841 217 equemene
  db=bmx/(2.e0*(float)ImpactParameter);
842 217 equemene

843 217 equemene
  // set origin as center of image
844 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
845 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
846 217 equemene
  // angle extracted from cylindric symmetry
847 217 equemene
  phi=atanp(x,y);
848 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
849 217 equemene

850 217 equemene
  // Real Impact Parameter
851 217 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
852 217 equemene

853 217 equemene
  // Integer Impact Parameter
854 217 equemene
  uint bi=(uint)sqrt(x*x+y*y);
855 217 equemene

856 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
857 217 equemene

858 217 equemene
  if (bi<ImpactParameter)
859 217 equemene
  {
860 217 equemene
    do
861 217 equemene
    {
862 217 equemene
      php=phd+(float)HalfLap*PI;
863 217 equemene
      nr=php/h;
864 217 equemene
      ni=(int)nr;
865 217 equemene

866 217 equemene
      if (ni<IdLast[bi])
867 217 equemene
      {
868 217 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
869 217 equemene
      }
870 217 equemene
      else
871 217 equemene
      {
872 217 equemene
        r=Trajectories[bi*TrackPoints+ni];
873 217 equemene
      }
874 217 equemene

875 217 equemene
      if ((r<=re)&&(r>=ri))
876 217 equemene
      {
877 217 equemene
        ExitOnImpact=1;
878 217 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
879 217 equemene
      }
880 217 equemene

881 217 equemene
      HalfLap++;
882 217 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
883 217 equemene

884 217 equemene
  }
885 217 equemene

886 217 equemene
  zImage[yi+sizex*xi]=zp;
887 217 equemene
  fImage[yi+sizex*xi]=fp;
888 217 equemene
}
889 217 equemene

890 217 equemene
__global__ void Circle(float *Trajectories,int *IdLast,
891 217 equemene
                       float *zImage,float *fImage,
892 217 equemene
                       int TrackPoints,
893 217 equemene
                       float Mass,float InternalRadius,
894 217 equemene
                       float ExternalRadius,float Angle,
895 217 equemene
                       int Line)
896 217 equemene
{
897 217 equemene
   // Integer Impact Parameter ID
898 219 equemene
   int bi=blockIdx.x*blockDim.x+threadIdx.x;
899 217 equemene
   // Integer points on circle
900 219 equemene
   int i=blockIdx.y*blockDim.y+threadIdx.y;
901 217 equemene
   // Integer Impact Parameter Size (half of image)
902 217 equemene
   int bmaxi=gridDim.x*blockDim.x;
903 217 equemene
   // Integer Points on circle
904 217 equemene
   int imx=gridDim.y*blockDim.y;
905 217 equemene

906 217 equemene
   // Perform trajectory for each pixel
907 217 equemene

908 217 equemene
  float m,rs,ri,re,tho;
909 217 equemene
  int q,raie;
910 217 equemene

911 217 equemene
  m=Mass;
912 217 equemene
  rs=2.*m;
913 217 equemene
  ri=InternalRadius;
914 217 equemene
  re=ExternalRadius;
915 217 equemene
  tho=Angle;
916 217 equemene
  raie=Line;
917 217 equemene

918 217 equemene
  float bmx,db,b,h;
919 217 equemene
  float phi,thi,phd;
920 217 equemene
  int nh;
921 217 equemene
  float zp=0,fp=0;
922 217 equemene

923 217 equemene
  // Autosize for image
924 217 equemene
  bmx=1.25*re;
925 217 equemene

926 217 equemene
  // Angular step of integration
927 217 equemene
  h=4.e0f*PI/(float)TrackPoints;
928 217 equemene

929 217 equemene
  // impact parameter
930 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
931 217 equemene
  db=bmx/(2.e0*(float)bmaxi);
932 217 equemene

933 217 equemene
  phi=2.*PI/(float)imx*(float)i;
934 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
935 217 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
936 217 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
937 217 equemene

938 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
939 217 equemene
  float php,nr,r;
940 217 equemene

941 217 equemene
  do
942 217 equemene
  {
943 217 equemene
     php=phd+(float)HalfLap*PI;
944 217 equemene
     nr=php/h;
945 217 equemene
     ni=(int)nr;
946 217 equemene

947 217 equemene
     if (ni<IdLast[bi])
948 217 equemene
     {
949 217 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
950 217 equemene
     }
951 217 equemene
     else
952 217 equemene
     {
953 217 equemene
        r=Trajectories[bi*TrackPoints+ni];
954 217 equemene
     }
955 217 equemene

956 217 equemene
     if ((r<=re)&&(r>=ri))
957 217 equemene
     {
958 217 equemene
        ExitOnImpact=1;
959 217 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
960 217 equemene
     }
961 217 equemene

962 217 equemene
     HalfLap++;
963 217 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
964 217 equemene

965 217 equemene
  zImage[yi+2*bmaxi*xi]=zp;
966 217 equemene
  fImage[yi+2*bmaxi*xi]=fp;
967 217 equemene

968 217 equemene
}
969 217 equemene

970 217 equemene
__global__ void Trajectory(float *Trajectories,
971 217 equemene
                           int *IdLast,int TrackPoints,
972 217 equemene
                           float Mass,float InternalRadius,
973 217 equemene
                           float ExternalRadius,float Angle,
974 217 equemene
                           int Line)
975 217 equemene
{
976 217 equemene
  // Integer Impact Parameter ID
977 219 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
978 217 equemene
  // Integer Impact Parameter Size (half of image)
979 217 equemene
  int bmaxi=gridDim.x*blockDim.x;
980 217 equemene

981 217 equemene
  // Perform trajectory for each pixel
982 217 equemene

983 217 equemene
  float m,rs,ri,re,tho;
984 217 equemene
  int raie,q;
985 217 equemene

986 217 equemene
  m=Mass;
987 217 equemene
  rs=2.*m;
988 217 equemene
  ri=InternalRadius;
989 217 equemene
  re=ExternalRadius;
990 217 equemene
  tho=Angle;
991 217 equemene
  q=-2;
992 217 equemene
  raie=Line;
993 217 equemene

994 217 equemene
  float d,bmx,db,b,h;
995 217 equemene
  float phi,thi,phd,php,nr,r;
996 217 equemene
  int nh;
997 217 equemene
  float zp,fp;
998 217 equemene

999 217 equemene
  // Autosize for image
1000 217 equemene
  bmx=1.25*re;
1001 217 equemene

1002 217 equemene
  // Angular step of integration
1003 217 equemene
  h=4.e0f*PI/(float)TrackPoints;
1004 217 equemene

1005 217 equemene
  // impact parameter
1006 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1007 217 equemene

1008 217 equemene
  float up,vp,pp,us,vs,ps;
1009 217 equemene

1010 217 equemene
  up=0.;
1011 217 equemene
  vp=1.;
1012 217 equemene

1013 217 equemene
  pp=0.;
1014 217 equemene
  nh=0;
1015 217 equemene

1016 217 equemene
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1017 217 equemene

1018 217 equemene
  // b versus us
1019 217 equemene
  float bvus=fabs(b/us);
1020 217 equemene
  float bvus0=bvus;
1021 217 equemene
  Trajectories[bi*TrackPoints+nh]=bvus;
1022 217 equemene

1023 217 equemene
  do
1024 217 equemene
  {
1025 217 equemene
     nh++;
1026 217 equemene
     pp=ps;
1027 217 equemene
     up=us;
1028 217 equemene
     vp=vs;
1029 217 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1030 217 equemene
     bvus=fabs(b/us);
1031 217 equemene
     Trajectories[bi*TrackPoints+nh]=bvus;
1032 217 equemene

1033 217 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1034 217 equemene

1035 217 equemene
  IdLast[bi]=nh;
1036 217 equemene

1037 217 equemene
}
1038 217 equemene
"""
1039 217 equemene
    return(BlobCUDA)
1040 217 equemene
1041 211 equemene
# def ImageOutput(sigma,prefix):
1042 211 equemene
#     from PIL import Image
1043 211 equemene
#     Max=sigma.max()
1044 211 equemene
#     Min=sigma.min()
1045 199 equemene
1046 211 equemene
#     # Normalize value as 8bits Integer
1047 211 equemene
#     SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
1048 211 equemene
#     image = Image.fromarray(SigmaInt)
1049 211 equemene
#     image.save("%s.jpg" % prefix)
1050 211 equemene
1051 211 equemene
def ImageOutput(sigma,prefix,Colors):
1052 211 equemene
    import matplotlib.pyplot as plt
1053 222 equemene
    start_time=time.time()
1054 211 equemene
    if Colors == 'Red2Yellow':
1055 211 equemene
        plt.imsave("%s.png" % prefix, sigma, cmap='afmhot')
1056 211 equemene
    else:
1057 211 equemene
        plt.imsave("%s.png" % prefix, sigma, cmap='Greys_r')
1058 222 equemene
    save_time = time.time()-start_time
1059 222 equemene
    print("Save Time : %f" % save_time)
1060 211 equemene
1061 204 equemene
def BlackHoleCL(zImage,fImage,InputCL):
1062 199 equemene
1063 199 equemene
    kernel_params = {}
1064 199 equemene
1065 204 equemene
    print(InputCL)
1066 204 equemene
1067 204 equemene
    Device=InputCL['Device']
1068 204 equemene
    GpuStyle=InputCL['GpuStyle']
1069 204 equemene
    VariableType=InputCL['VariableType']
1070 204 equemene
    Size=InputCL['Size']
1071 204 equemene
    Mass=InputCL['Mass']
1072 204 equemene
    InternalRadius=InputCL['InternalRadius']
1073 204 equemene
    ExternalRadius=InputCL['ExternalRadius']
1074 204 equemene
    Angle=InputCL['Angle']
1075 204 equemene
    Method=InputCL['Method']
1076 204 equemene
    TrackPoints=InputCL['TrackPoints']
1077 211 equemene
    Physics=InputCL['Physics']
1078 204 equemene
1079 211 equemene
    PhysicsList=DictionariesAPI()
1080 211 equemene
1081 204 equemene
    if InputCL['BlackBody']:
1082 209 equemene
        # Spectrum is Black Body one
1083 209 equemene
        Line=0
1084 204 equemene
    else:
1085 209 equemene
        # Spectrum is Monochromatic Line one
1086 209 equemene
        Line=1
1087 204 equemene
1088 217 equemene
    Trajectories=numpy.zeros((int(InputCL['Size']/2),InputCL['TrackPoints']),dtype=numpy.float32)
1089 217 equemene
    IdLast=numpy.zeros(int(InputCL['Size']/2),dtype=numpy.int32)
1090 204 equemene
1091 199 equemene
    # Je detecte un peripherique GPU dans la liste des peripheriques
1092 199 equemene
    Id=0
1093 199 equemene
    HasXPU=False
1094 199 equemene
    for platform in cl.get_platforms():
1095 199 equemene
        for device in platform.get_devices():
1096 199 equemene
            if Id==Device:
1097 199 equemene
                XPU=device
1098 217 equemene
                print("CPU/GPU selected: ",device.name.lstrip())
1099 199 equemene
                HasXPU=True
1100 199 equemene
            Id+=1
1101 199 equemene
1102 199 equemene
    if HasXPU==False:
1103 217 equemene
        print("No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1))
1104 199 equemene
        sys.exit()
1105 199 equemene
1106 199 equemene
    ctx = cl.Context([XPU])
1107 199 equemene
    queue = cl.CommandQueue(ctx,
1108 199 equemene
                            properties=cl.command_queue_properties.PROFILING_ENABLE)
1109 199 equemene
1110 199 equemene
1111 211 equemene
    #    BlackHoleCL = cl.Program(ctx,KERNEL_CODE.substitute(kernel_params)).build()
1112 211 equemene
1113 211 equemene
    BuildOptions="-cl-mad-enable -DPHYSICS=%i " % (PhysicsList[Physics])
1114 211 equemene
1115 211 equemene
    BlackHoleCL = cl.Program(ctx,BlobOpenCL).build(options = BuildOptions)
1116 211 equemene
1117 199 equemene
    # Je recupere les flag possibles pour les buffers
1118 199 equemene
    mf = cl.mem_flags
1119 199 equemene
1120 204 equemene
    TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
1121 201 equemene
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
1122 201 equemene
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
1123 204 equemene
    IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
1124 199 equemene
1125 199 equemene
    start_time=time.time()
1126 199 equemene
1127 204 equemene
    if Method=='EachPixel':
1128 204 equemene
        CLLaunch=BlackHoleCL.EachPixel(queue,(zImage.shape[0],zImage.shape[1]),
1129 204 equemene
                                       None,zImageCL,fImageCL,
1130 204 equemene
                                       numpy.float32(Mass),
1131 204 equemene
                                       numpy.float32(InternalRadius),
1132 204 equemene
                                       numpy.float32(ExternalRadius),
1133 204 equemene
                                       numpy.float32(Angle),
1134 209 equemene
                                       numpy.int32(Line))
1135 204 equemene
        CLLaunch.wait()
1136 204 equemene
    elif Method=='TrajectoCircle':
1137 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
1138 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
1139 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
1140 204 equemene
                                        numpy.float32(Mass),
1141 204 equemene
                                        numpy.float32(InternalRadius),
1142 204 equemene
                                        numpy.float32(ExternalRadius),
1143 204 equemene
                                        numpy.float32(Angle),
1144 209 equemene
                                        numpy.int32(Line))
1145 204 equemene
1146 204 equemene
        CLLaunch=BlackHoleCL.Circle(queue,(Trajectories.shape[0],
1147 204 equemene
                                           zImage.shape[0]*4),None,
1148 204 equemene
                                    TrajectoriesCL,IdLastCL,
1149 204 equemene
                                    zImageCL,fImageCL,
1150 204 equemene
                                    numpy.uint32(Trajectories.shape[1]),
1151 204 equemene
                                    numpy.float32(Mass),
1152 204 equemene
                                    numpy.float32(InternalRadius),
1153 204 equemene
                                    numpy.float32(ExternalRadius),
1154 204 equemene
                                    numpy.float32(Angle),
1155 209 equemene
                                    numpy.int32(Line))
1156 204 equemene
        CLLaunch.wait()
1157 204 equemene
    else:
1158 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
1159 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
1160 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
1161 204 equemene
                                        numpy.float32(Mass),
1162 204 equemene
                                        numpy.float32(InternalRadius),
1163 204 equemene
                                        numpy.float32(ExternalRadius),
1164 204 equemene
                                        numpy.float32(Angle),
1165 209 equemene
                                        numpy.int32(Line))
1166 204 equemene
1167 204 equemene
        CLLaunch=BlackHoleCL.Pixel(queue,(zImage.shape[0],
1168 217 equemene
                                          zImage.shape[1]),None,
1169 204 equemene
                                   zImageCL,fImageCL,TrajectoriesCL,IdLastCL,
1170 204 equemene
                                   numpy.uint32(Trajectories.shape[0]),
1171 204 equemene
                                   numpy.uint32(Trajectories.shape[1]),
1172 204 equemene
                                        numpy.float32(Mass),
1173 204 equemene
                                        numpy.float32(InternalRadius),
1174 204 equemene
                                        numpy.float32(ExternalRadius),
1175 204 equemene
                                        numpy.float32(Angle),
1176 209 equemene
                                        numpy.int32(Line))
1177 204 equemene
        CLLaunch.wait()
1178 204 equemene
1179 218 equemene
    compute = time.time()-start_time
1180 199 equemene
1181 201 equemene
    cl.enqueue_copy(queue,zImage,zImageCL).wait()
1182 201 equemene
    cl.enqueue_copy(queue,fImage,fImageCL).wait()
1183 204 equemene
    cl.enqueue_copy(queue,Trajectories,TrajectoriesCL).wait()
1184 204 equemene
    cl.enqueue_copy(queue,IdLast,IdLastCL).wait()
1185 218 equemene
    elapsed = time.time()-start_time
1186 218 equemene
    print("\nCompute Time : %f" % compute)
1187 218 equemene
    print("Elapsed Time : %f\n" % elapsed)
1188 211 equemene
1189 211 equemene
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
1190 211 equemene
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
1191 219 equemene
    print("Z max @(%i,%i) : %f" % (zMaxPosition[1][0],zMaxPosition[0][0],zImage.max()))
1192 219 equemene
    print("Flux max @(%i,%i) : %f\n" % (fMaxPosition[1][0],fMaxPosition[0][0],fImage.max()))
1193 201 equemene
    zImageCL.release()
1194 201 equemene
    fImageCL.release()
1195 204 equemene
1196 204 equemene
    TrajectoriesCL.release()
1197 204 equemene
    IdLastCL.release()
1198 204 equemene
1199 199 equemene
    return(elapsed)
1200 199 equemene
1201 217 equemene
def BlackHoleCUDA(zImage,fImage,InputCL):
1202 217 equemene
1203 217 equemene
    kernel_params = {}
1204 217 equemene
1205 217 equemene
    print(InputCL)
1206 217 equemene
1207 217 equemene
    Device=InputCL['Device']
1208 217 equemene
    GpuStyle=InputCL['GpuStyle']
1209 217 equemene
    VariableType=InputCL['VariableType']
1210 217 equemene
    Size=InputCL['Size']
1211 217 equemene
    Mass=InputCL['Mass']
1212 217 equemene
    InternalRadius=InputCL['InternalRadius']
1213 217 equemene
    ExternalRadius=InputCL['ExternalRadius']
1214 217 equemene
    Angle=InputCL['Angle']
1215 217 equemene
    Method=InputCL['Method']
1216 217 equemene
    TrackPoints=InputCL['TrackPoints']
1217 217 equemene
    Physics=InputCL['Physics']
1218 217 equemene
1219 217 equemene
    PhysicsList=DictionariesAPI()
1220 217 equemene
1221 217 equemene
    if InputCL['BlackBody']:
1222 217 equemene
        # Spectrum is Black Body one
1223 217 equemene
        Line=0
1224 217 equemene
    else:
1225 217 equemene
        # Spectrum is Monochromatic Line one
1226 217 equemene
        Line=1
1227 217 equemene
1228 217 equemene
    Trajectories=numpy.zeros((int(InputCL['Size']/2),InputCL['TrackPoints']),dtype=numpy.float32)
1229 217 equemene
    IdLast=numpy.zeros(int(InputCL['Size']/2),dtype=numpy.int32)
1230 217 equemene
1231 217 equemene
    try:
1232 217 equemene
        # For PyCUDA import
1233 217 equemene
        import pycuda.driver as cuda
1234 217 equemene
        from pycuda.compiler import SourceModule
1235 217 equemene
1236 217 equemene
        cuda.init()
1237 217 equemene
        for Id in range(cuda.Device.count()):
1238 217 equemene
            if Id==Device:
1239 217 equemene
                XPU=cuda.Device(Id)
1240 217 equemene
                print("GPU selected %s" % XPU.name())
1241 217 equemene
        print
1242 217 equemene
1243 217 equemene
    except ImportError:
1244 217 equemene
        print("Platform does not seem to support CUDA")
1245 217 equemene
1246 217 equemene
    Context=XPU.make_context()
1247 217 equemene
1248 217 equemene
    try:
1249 217 equemene
        mod = SourceModule(KernelCodeCuda(),options=['--compiler-options','-DPHYSICS=%i' % (PhysicsList[Physics])])
1250 217 equemene
        print("Compilation seems to be OK")
1251 217 equemene
    except:
1252 217 equemene
        print("Compilation seems to break")
1253 217 equemene
1254 217 equemene
    EachPixelCU=mod.get_function("EachPixel")
1255 217 equemene
    TrajectoryCU=mod.get_function("Trajectory")
1256 217 equemene
    PixelCU=mod.get_function("Pixel")
1257 217 equemene
    CircleCU=mod.get_function("Circle")
1258 217 equemene
1259 217 equemene
    TrajectoriesCU = cuda.mem_alloc(Trajectories.size*Trajectories.dtype.itemsize)
1260 217 equemene
    cuda.memcpy_htod(TrajectoriesCU, Trajectories)
1261 217 equemene
    zImageCU = cuda.mem_alloc(zImage.size*zImage.dtype.itemsize)
1262 217 equemene
    cuda.memcpy_htod(zImageCU, zImage)
1263 217 equemene
    fImageCU = cuda.mem_alloc(fImage.size*fImage.dtype.itemsize)
1264 217 equemene
    cuda.memcpy_htod(zImageCU, fImage)
1265 217 equemene
    IdLastCU = cuda.mem_alloc(IdLast.size*IdLast.dtype.itemsize)
1266 217 equemene
    cuda.memcpy_htod(IdLastCU, IdLast)
1267 217 equemene
1268 217 equemene
    start_time=time.time()
1269 217 equemene
1270 217 equemene
    if Method=='EachPixel':
1271 217 equemene
        EachPixelCU(zImageCU,fImageCU,
1272 217 equemene
                    numpy.float32(Mass),
1273 217 equemene
                    numpy.float32(InternalRadius),
1274 217 equemene
                    numpy.float32(ExternalRadius),
1275 217 equemene
                    numpy.float32(Angle),
1276 217 equemene
                    numpy.int32(Line),
1277 219 equemene
                    grid=(zImage.shape[0]/32,zImage.shape[1]/32),
1278 219 equemene
                    block=(32,32,1))
1279 217 equemene
    elif Method=='TrajectoCircle':
1280 217 equemene
        TrajectoryCU(TrajectoriesCU,IdLastCU,
1281 217 equemene
                     numpy.uint32(Trajectories.shape[1]),
1282 217 equemene
                     numpy.float32(Mass),
1283 217 equemene
                     numpy.float32(InternalRadius),
1284 217 equemene
                     numpy.float32(ExternalRadius),
1285 217 equemene
                     numpy.float32(Angle),
1286 217 equemene
                     numpy.int32(Line),
1287 219 equemene
                     grid=(Trajectories.shape[0]/32,1),
1288 219 equemene
                     block=(32,1,1))
1289 217 equemene
1290 217 equemene
        CircleCU(TrajectoriesCU,IdLastCU,zImageCU,fImageCU,
1291 217 equemene
                 numpy.uint32(Trajectories.shape[1]),
1292 217 equemene
                 numpy.float32(Mass),
1293 217 equemene
                 numpy.float32(InternalRadius),
1294 217 equemene
                 numpy.float32(ExternalRadius),
1295 217 equemene
                 numpy.float32(Angle),
1296 217 equemene
                 numpy.int32(Line),
1297 219 equemene
                 grid=(Trajectories.shape[0]/32,zImage.shape[0]*4/32),
1298 219 equemene
                 block=(32,32,1))
1299 217 equemene
    else:
1300 217 equemene
        TrajectoryCU(TrajectoriesCU,IdLastCU,
1301 217 equemene
                     numpy.uint32(Trajectories.shape[1]),
1302 217 equemene
                     numpy.float32(Mass),
1303 217 equemene
                     numpy.float32(InternalRadius),
1304 217 equemene
                     numpy.float32(ExternalRadius),
1305 217 equemene
                     numpy.float32(Angle),
1306 217 equemene
                     numpy.int32(Line),
1307 219 equemene
                     grid=(Trajectories.shape[0]/32,1),
1308 219 equemene
                     block=(32,1,1))
1309 217 equemene
1310 217 equemene
        PixelCU(zImageCU,fImageCU,TrajectoriesCU,IdLastCU,
1311 217 equemene
                numpy.uint32(Trajectories.shape[0]),
1312 217 equemene
                numpy.uint32(Trajectories.shape[1]),
1313 217 equemene
                numpy.float32(Mass),
1314 217 equemene
                numpy.float32(InternalRadius),
1315 217 equemene
                numpy.float32(ExternalRadius),
1316 217 equemene
                numpy.float32(Angle),
1317 217 equemene
                numpy.int32(Line),
1318 219 equemene
                grid=(zImage.shape[0]/32,zImage.shape[1]/32,1),
1319 219 equemene
                block=(32,32,1))
1320 217 equemene
1321 220 equemene
    Context.synchronize()
1322 220 equemene
1323 218 equemene
    compute = time.time()-start_time
1324 217 equemene
1325 217 equemene
    cuda.memcpy_dtoh(zImage,zImageCU)
1326 217 equemene
    cuda.memcpy_dtoh(fImage,fImageCU)
1327 218 equemene
    elapsed = time.time()-start_time
1328 218 equemene
    print("\nCompute Time : %f" % compute)
1329 218 equemene
    print("Elapsed Time : %f\n" % elapsed)
1330 217 equemene
1331 217 equemene
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
1332 217 equemene
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
1333 219 equemene
    print("Z max @(%i,%i) : %f" % (zMaxPosition[1][0],zMaxPosition[0][0],zImage.max()))
1334 219 equemene
    print("Flux max @(%i,%i) : %f\n" % (fMaxPosition[1][0],fMaxPosition[0][0],fImage.max()))
1335 217 equemene
1336 220 equemene
1337 218 equemene
    Context.pop()
1338 220 equemene
1339 217 equemene
    Context.detach()
1340 217 equemene
1341 217 equemene
    return(elapsed)
1342 217 equemene
1343 199 equemene
if __name__=='__main__':
1344 199 equemene
1345 199 equemene
    GpuStyle = 'OpenCL'
1346 199 equemene
    Mass = 1.
1347 199 equemene
    # Internal Radius 3 times de Schwarzschild Radius
1348 199 equemene
    InternalRadius=6.*Mass
1349 199 equemene
    #
1350 199 equemene
    ExternalRadius=12.
1351 199 equemene
    #
1352 199 equemene
    # Angle with normal to disc 10 degrees
1353 199 equemene
    Angle = numpy.pi/180.*(90.-10.)
1354 199 equemene
    # Radiation of disc : BlackBody or Monochromatic
1355 209 equemene
    BlackBody = False
1356 199 equemene
    # Size of image
1357 199 equemene
    Size=256
1358 199 equemene
    # Variable Type
1359 199 equemene
    VariableType='FP32'
1360 199 equemene
    # ?
1361 199 equemene
    q=-2
1362 204 equemene
    # Method of resolution
1363 209 equemene
    Method='TrajectoPixel'
1364 211 equemene
    # Colors for output image
1365 211 equemene
    Colors='Greyscale'
1366 211 equemene
    # Physics
1367 211 equemene
    Physics='Einstein'
1368 211 equemene
    # No output as image
1369 211 equemene
    NoImage = False
1370 211 equemene
1371 211 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> -t <EachPixel/TrajectoCircle/TrajectoPixel> -v <FP32/FP64>'
1372 199 equemene
1373 199 equemene
    try:
1374 211 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hbns:m:i:x:a:d:g:v:t:c:p:",["blackbody","noimage","camera","size=","mass=","internal=","external=","angle=","device=","gpustyle=","variabletype=","method=","colors=","physics="])
1375 199 equemene
    except getopt.GetoptError:
1376 199 equemene
        print(HowToUse % sys.argv[0])
1377 199 equemene
        sys.exit(2)
1378 199 equemene
1379 199 equemene
    # List of Devices
1380 199 equemene
    Devices=[]
1381 199 equemene
    Alu={}
1382 199 equemene
1383 199 equemene
    for opt, arg in opts:
1384 199 equemene
        if opt == '-h':
1385 199 equemene
            print(HowToUse % sys.argv[0])
1386 199 equemene
1387 199 equemene
            print("\nInformations about devices detected under OpenCL API:")
1388 199 equemene
            # For PyOpenCL import
1389 199 equemene
            try:
1390 199 equemene
                import pyopencl as cl
1391 199 equemene
                Id=0
1392 199 equemene
                for platform in cl.get_platforms():
1393 199 equemene
                    for device in platform.get_devices():
1394 199 equemene
                        #deviceType=cl.device_type.to_string(device.type)
1395 199 equemene
                        deviceType="xPU"
1396 199 equemene
                        print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip(),deviceType,device.name.lstrip()))
1397 199 equemene
                        Id=Id+1
1398 199 equemene
1399 199 equemene
            except:
1400 199 equemene
                print("Your platform does not seem to support OpenCL")
1401 199 equemene
1402 199 equemene
            print("\nInformations about devices detected under CUDA API:")
1403 199 equemene
                # For PyCUDA import
1404 199 equemene
            try:
1405 199 equemene
                import pycuda.driver as cuda
1406 199 equemene
                cuda.init()
1407 199 equemene
                for Id in range(cuda.Device.count()):
1408 199 equemene
                    device=cuda.Device(Id)
1409 199 equemene
                    print("Device #%i of type GPU : %s" % (Id,device.name()))
1410 199 equemene
                print
1411 199 equemene
            except:
1412 199 equemene
                print("Your platform does not seem to support CUDA")
1413 199 equemene
1414 199 equemene
            sys.exit()
1415 199 equemene
1416 199 equemene
        elif opt in ("-d", "--device"):
1417 199 equemene
#            Devices.append(int(arg))
1418 199 equemene
            Device=int(arg)
1419 199 equemene
        elif opt in ("-g", "--gpustyle"):
1420 199 equemene
            GpuStyle = arg
1421 204 equemene
        elif opt in ("-v", "--variabletype"):
1422 199 equemene
            VariableType = arg
1423 199 equemene
        elif opt in ("-s", "--size"):
1424 199 equemene
            Size = int(arg)
1425 199 equemene
        elif opt in ("-m", "--mass"):
1426 199 equemene
            Mass = float(arg)
1427 199 equemene
        elif opt in ("-i", "--internal"):
1428 199 equemene
            InternalRadius = float(arg)
1429 199 equemene
        elif opt in ("-e", "--external"):
1430 199 equemene
            ExternalRadius = float(arg)
1431 199 equemene
        elif opt in ("-a", "--angle"):
1432 199 equemene
            Angle = numpy.pi/180.*(90.-float(arg))
1433 199 equemene
        elif opt in ("-b", "--blackbody"):
1434 199 equemene
            BlackBody = True
1435 211 equemene
        elif opt in ("-n", "--noimage"):
1436 211 equemene
            NoImage = True
1437 204 equemene
        elif opt in ("-t", "--method"):
1438 204 equemene
            Method = arg
1439 211 equemene
        elif opt in ("-c", "--colors"):
1440 211 equemene
            Colors = arg
1441 211 equemene
        elif opt in ("-p", "--physics"):
1442 211 equemene
            Physics = arg
1443 199 equemene
1444 199 equemene
    print("Device Identification selected : %s" % Device)
1445 199 equemene
    print("GpuStyle used : %s" % GpuStyle)
1446 199 equemene
    print("VariableType : %s" % VariableType)
1447 199 equemene
    print("Size : %i" % Size)
1448 199 equemene
    print("Mass : %f" % Mass)
1449 199 equemene
    print("Internal Radius : %f" % InternalRadius)
1450 199 equemene
    print("External Radius : %f" % ExternalRadius)
1451 199 equemene
    print("Angle with normal of (in radians) : %f" % Angle)
1452 199 equemene
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
1453 204 equemene
    print("Method of resolution : %s" % Method)
1454 211 equemene
    print("Colors for output images : %s" % Colors)
1455 211 equemene
    print("Physics used for Trajectories : %s" % Physics)
1456 199 equemene
1457 199 equemene
    if GpuStyle=='CUDA':
1458 199 equemene
        print("\nSelection of CUDA device")
1459 199 equemene
        try:
1460 199 equemene
            # For PyCUDA import
1461 199 equemene
            import pycuda.driver as cuda
1462 199 equemene
1463 199 equemene
            cuda.init()
1464 199 equemene
            for Id in range(cuda.Device.count()):
1465 199 equemene
                device=cuda.Device(Id)
1466 199 equemene
                print("Device #%i of type GPU : %s" % (Id,device.name()))
1467 199 equemene
                if Id in Devices:
1468 199 equemene
                    Alu[Id]='GPU'
1469 199 equemene
1470 199 equemene
        except ImportError:
1471 199 equemene
            print("Platform does not seem to support CUDA")
1472 199 equemene
1473 199 equemene
    if GpuStyle=='OpenCL':
1474 199 equemene
        print("\nSelection of OpenCL device")
1475 199 equemene
        try:
1476 199 equemene
            # For PyOpenCL import
1477 199 equemene
            import pyopencl as cl
1478 199 equemene
            Id=0
1479 199 equemene
            for platform in cl.get_platforms():
1480 199 equemene
                for device in platform.get_devices():
1481 199 equemene
                    #deviceType=cl.device_type.to_string(device.type)
1482 199 equemene
                    deviceType="xPU"
1483 199 equemene
                    print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip().rstrip(),deviceType,device.name.lstrip().rstrip()))
1484 199 equemene
1485 199 equemene
                    if Id in Devices:
1486 199 equemene
                    # Set the Alu as detected Device Type
1487 199 equemene
                        Alu[Id]=deviceType
1488 199 equemene
                    Id=Id+1
1489 199 equemene
        except ImportError:
1490 199 equemene
            print("Platform does not seem to support OpenCL")
1491 199 equemene
1492 199 equemene
#    print(Devices,Alu)
1493 199 equemene
1494 199 equemene
#    MyImage=numpy.where(numpy.random.zeros(Size,Size)>0,1,-1).astype(numpy.float32)
1495 204 equemene
    TrackPoints=2048
1496 201 equemene
    zImage=numpy.zeros((Size,Size),dtype=numpy.float32)
1497 201 equemene
    fImage=numpy.zeros((Size,Size),dtype=numpy.float32)
1498 199 equemene
1499 204 equemene
    InputCL={}
1500 204 equemene
    InputCL['Device']=Device
1501 204 equemene
    InputCL['GpuStyle']=GpuStyle
1502 204 equemene
    InputCL['VariableType']=VariableType
1503 204 equemene
    InputCL['Size']=Size
1504 204 equemene
    InputCL['Mass']=Mass
1505 204 equemene
    InputCL['InternalRadius']=InternalRadius
1506 204 equemene
    InputCL['ExternalRadius']=ExternalRadius
1507 204 equemene
    InputCL['Angle']=Angle
1508 204 equemene
    InputCL['BlackBody']=BlackBody
1509 204 equemene
    InputCL['Method']=Method
1510 204 equemene
    InputCL['TrackPoints']=TrackPoints
1511 211 equemene
    InputCL['Physics']=Physics
1512 199 equemene
1513 217 equemene
    if GpuStyle=='OpenCL':
1514 217 equemene
        duration=BlackHoleCL(zImage,fImage,InputCL)
1515 217 equemene
    else:
1516 217 equemene
        duration=BlackHoleCUDA(zImage,fImage,InputCL)
1517 217 equemene
1518 211 equemene
    Hostname=gethostname()
1519 211 equemene
    Date=time.strftime("%Y%m%d_%H%M%S")
1520 211 equemene
    ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
1521 211 equemene
1522 211 equemene
1523 211 equemene
    if not NoImage:
1524 211 equemene
        ImageOutput(zImage,"TrouNoirZ_%s" % ImageInfo,Colors)
1525 211 equemene
        ImageOutput(fImage,"TrouNoirF_%s" % ImageInfo,Colors)