Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 205

Historique | Voir | Annoter | Télécharger (23,65 ko)

1 199 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 204 equemene
#
18 204 equemene
# Thanks to :
19 204 equemene
#
20 204 equemene
# - Herve Aussel for his part of code of black body spectrum
21 204 equemene
# - Didier Pelat for his help to perform this work
22 204 equemene
# - Jean-Pierre Luminet for his article published in 1979
23 204 equemene
# - Numerical Recipies for Runge Kutta recipies
24 204 equemene
# - Luc Blanchet for his disponibility about my questions in General Relativity
25 204 equemene
# - Pierre Lena for his passion about science and vulgarisation
26 199 equemene
27 199 equemene
import pyopencl as cl
28 199 equemene
import numpy
29 199 equemene
from PIL import Image
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 199 equemene
36 204 equemene
37 204 equemene
38 204 equemene
39 204 equemene
40 204 equemene
41 204 equemene
42 204 equemene
43 199 equemene
KERNEL_CODE=string.Template("""
44 199 equemene

45 199 equemene
#define PI (float)3.14159265359
46 199 equemene
#define nbr 200
47 199 equemene

48 199 equemene
float atanp(float x,float y)
49 199 equemene
{
50 199 equemene
  float angle;
51 199 equemene

52 199 equemene
  angle=atan2(y,x);
53 199 equemene

54 204 equemene
  if (angle<0.e0f)
55 199 equemene
    {
56 199 equemene
      angle+=(float)2.e0f*PI;
57 199 equemene
    }
58 199 equemene

59 199 equemene
  return angle;
60 199 equemene
}
61 199 equemene

62 199 equemene
float f(float v)
63 199 equemene
{
64 199 equemene
  return v;
65 199 equemene
}
66 199 equemene

67 199 equemene
float g(float u,float m,float b)
68 199 equemene
{
69 204 equemene
  return (3.e0f*m/b*pow(u,2)-u);
70 199 equemene
}
71 199 equemene

72 199 equemene

73 199 equemene
void calcul(float *us,float *vs,float up,float vp,
74 199 equemene
            float h,float m,float b)
75 199 equemene
{
76 199 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
77 199 equemene

78 199 equemene
  c0=h*f(vp);
79 199 equemene
  c1=h*f(vp+c0/2.);
80 199 equemene
  c2=h*f(vp+c1/2.);
81 199 equemene
  c3=h*f(vp+c2);
82 199 equemene
  d0=h*g(up,m,b);
83 199 equemene
  d1=h*g(up+d0/2.,m,b);
84 199 equemene
  d2=h*g(up+d1/2.,m,b);
85 199 equemene
  d3=h*g(up+d2,m,b);
86 199 equemene

87 199 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
88 199 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
89 199 equemene
}
90 199 equemene

91 199 equemene
void rungekutta(float *ps,float *us,float *vs,
92 199 equemene
                float pp,float up,float vp,
93 199 equemene
                float h,float m,float b)
94 199 equemene
{
95 199 equemene
  calcul(us,vs,up,vp,h,m,b);
96 199 equemene
  *ps=pp+h;
97 199 equemene
}
98 199 equemene

99 199 equemene
float decalage_spectral(float r,float b,float phi,
100 199 equemene
                         float tho,float m)
101 199 equemene
{
102 199 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
103 199 equemene
}
104 199 equemene

105 199 equemene
float spectre(float rf,int q,float b,float db,
106 199 equemene
             float h,float r,float m,float bss)
107 199 equemene
{
108 199 equemene
  float flx;
109 199 equemene

110 201 equemene
  flx=pow(r/m,q)*pow(rf,4)*b;
111 199 equemene
  return(flx);
112 199 equemene
}
113 199 equemene

114 204 equemene
float spectre_cn(float rf,float b,float db,float h,float r,float m,float bss)
115 199 equemene
{
116 201 equemene
  double flx;
117 201 equemene
  double nu_rec,nu_em,qu,v,temp,temp_em,flux_int,m_point,planck,c,k,psc2,psk;
118 199 equemene
  int fi,posfreq;
119 199 equemene

120 199 equemene
  planck=6.62e-34;
121 199 equemene
  k=1.38e-23;
122 201 equemene
  psk=5.38e-11;
123 201 equemene
  psc2=7.35e-51;
124 199 equemene
  temp=3.e7;
125 199 equemene
  m_point=1.e14;
126 199 equemene
  v=1.-3./r;
127 199 equemene

128 201 equemene
  qu=1./sqrt(1.-3./r)/sqrt(r)*(sqrt(r)-sqrt(6.)+sqrt(3.)/2.*log((sqrt(r)+sqrt(3.))/(sqrt(r)-sqrt(3.))*(sqrt(6.)-sqrt(3.))/(sqrt(6.)+sqrt(3.))));
129 199 equemene

130 201 equemene
  temp_em=temp*sqrt(m)*exp(0.25*log(m_point))*exp(-0.75*log(r))*exp(-0.125*log(v))*exp(0.25*log(qu));
131 199 equemene

132 199 equemene
  flux_int=0;
133 199 equemene
  flx=0;
134 199 equemene

135 201 equemene
  for (fi=0;fi<nbr;fi++)
136 199 equemene
    {
137 201 equemene
      nu_em=bss*(float)fi/(float)nbr;
138 199 equemene
      nu_rec=nu_em*rf;
139 201 equemene
      posfreq=(int)(1./bss*nu_rec*(float)nbr);
140 199 equemene
      if ((posfreq>0)&&(posfreq<nbr))
141 199 equemene
        {
142 201 equemene
          //flux_int=2*planck/9.e16f*pow(nu_em,3)/(exp(planck*nu_em/k/temp_em)-1.)*pow(rf,3)*b*db*h;
143 201 equemene
          //flux_int=pow(nu_em,3)/(exp(planck*nu_em/k/temp_em)-1.)*pow(rf,3)*b;
144 201 equemene
          flux_int=2.*psc2*pow(nu_em,3)/(exp(psk*nu_em/temp_em)-1.)*pow(rf,3)*b;
145 199 equemene
          flx+=flux_int;
146 199 equemene
        }
147 199 equemene
    }
148 201 equemene
  //return(pow(rf,3)*b*temp_em);
149 201 equemene
  return((float)flx);
150 199 equemene
  return(flx);
151 199 equemene
}
152 199 equemene

153 199 equemene
void impact(float phi,float r,float b,float tho,float m,
154 199 equemene
            float *zp,float *fp,
155 199 equemene
            int q,float db,
156 204 equemene
            float h,int raie)
157 199 equemene
{
158 204 equemene
  float flx,rf,bss;
159 199 equemene

160 199 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
161 199 equemene

162 199 equemene
  if (raie==0)
163 199 equemene
    {
164 204 equemene
      bss=2.;
165 199 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
166 199 equemene
    }
167 199 equemene
  else
168 199 equemene
    {
169 204 equemene
      bss=1.e6;
170 199 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
171 199 equemene
    }
172 199 equemene

173 199 equemene
  *zp=1./rf;
174 199 equemene
  *fp=flx;
175 199 equemene

176 199 equemene
}
177 199 equemene

178 204 equemene
__kernel void EachPixel(__global float *zImage,__global float *fImage,
179 204 equemene
                        float Mass,float InternalRadius,
180 204 equemene
                        float ExternalRadius,float Angle,
181 204 equemene
                        float ObserverDistance,
182 204 equemene
                        int BlackBody,int AngularCamera)
183 199 equemene
{
184 199 equemene
   uint xi=(uint)get_global_id(0);
185 199 equemene
   uint yi=(uint)get_global_id(1);
186 199 equemene
   uint sizex=(uint)get_global_size(0);
187 199 equemene
   uint sizey=(uint)get_global_size(1);
188 199 equemene

189 204 equemene
   // Perform trajectory for each pixel, exit on hit
190 199 equemene

191 199 equemene
  float m,rs,ri,re,tho,ro;
192 204 equemene
  int q,dist,raie;
193 199 equemene

194 204 equemene
  m=Mass;
195 204 equemene
  rs=2.*m;
196 204 equemene
  ri=InternalRadius;
197 204 equemene
  re=ExternalRadius;
198 204 equemene
  ro=ObserverDistance;
199 204 equemene
  tho=Angle;
200 204 equemene
  q=-2;
201 204 equemene
  dist=AngularCamera;
202 204 equemene
  raie=BlackBody;
203 204 equemene

204 199 equemene
  float d,bmx,db,b,h;
205 204 equemene
  float rp[2048];
206 204 equemene
  float phi,thi,phd,php,nr,r;
207 199 equemene
  int nh;
208 199 equemene
  float zp,fp;
209 199 equemene

210 199 equemene
  // Autosize for image
211 199 equemene
  bmx=1.25*re;
212 199 equemene
  b=0.;
213 199 equemene

214 204 equemene
  h=4.e0f*PI/(float)2048;
215 201 equemene

216 199 equemene
  // set origin as center of image
217 199 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
218 201 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
219 199 equemene
  // angle extracted from cylindric symmetry
220 199 equemene
  phi=atanp(x,y);
221 199 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
222 199 equemene

223 204 equemene
  float up,vp,pp,us,vs,ps;
224 204 equemene

225 204 equemene
  // impact parameter
226 204 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
227 204 equemene
  // step of impact parameter;
228 204 equemene
  db=bmx/(float)(sizex/2);
229 204 equemene

230 199 equemene
  if (dist==1)
231 199 equemene
  {
232 199 equemene
     up=0.;
233 199 equemene
     vp=1.;
234 199 equemene
  }
235 199 equemene
  else
236 199 equemene
  {
237 199 equemene
     up=sin(thi);
238 199 equemene
     vp=cos(thi);
239 199 equemene
  }
240 199 equemene

241 199 equemene
  pp=0.;
242 199 equemene
  nh=0;
243 199 equemene

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

246 199 equemene
  rp[nh]=fabs(b/us);
247 199 equemene

248 204 equemene
  int ExitOnImpact=0;
249 199 equemene

250 199 equemene
  do
251 199 equemene
  {
252 199 equemene
     nh++;
253 199 equemene
     pp=ps;
254 199 equemene
     up=us;
255 199 equemene
     vp=vs;
256 199 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
257 199 equemene
     rp[nh]=fabs(b/us);
258 200 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rp[nh]>ri)&&(rp[nh]<re)?1:0;
259 199 equemene

260 199 equemene
  } while ((rp[nh]>=rs)&&(rp[nh]<=rp[0])&&(ExitOnImpact==0));
261 199 equemene

262 199 equemene
  if (ExitOnImpact==1) {
263 204 equemene
     impact(phi,rp[nh-1],b,tho,m,&zp,&fp,q,db,h,raie);
264 199 equemene
  }
265 199 equemene
  else
266 199 equemene
  {
267 199 equemene
     zp=0.;
268 201 equemene
     fp=0.;
269 199 equemene
  }
270 199 equemene

271 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
272 204 equemene

273 201 equemene
  zImage[yi+sizex*xi]=(float)zp;
274 204 equemene
  fImage[yi+sizex*xi]=(float)fp;
275 204 equemene
}
276 199 equemene

277 204 equemene
__kernel void Pixel(__global float *zImage,__global float *fImage,
278 204 equemene
                    __global float *Trajectories,__global int *IdLast,
279 204 equemene
                    uint ImpactParameter,uint TrackPoints,
280 204 equemene
                    float Mass,float InternalRadius,
281 204 equemene
                    float ExternalRadius,float Angle,
282 204 equemene
                    float ObserverDistance,
283 204 equemene
                    int BlackBody,int AngularCamera)
284 204 equemene
{
285 204 equemene
   uint xi=(uint)get_global_id(0);
286 204 equemene
   uint yi=(uint)get_global_id(1);
287 204 equemene
   uint sizex=(uint)get_global_size(0);
288 204 equemene
   uint sizey=(uint)get_global_size(1);
289 204 equemene

290 204 equemene
   // Perform trajectory for each pixel
291 204 equemene

292 204 equemene
  float m,rs,ri,re,tho,ro;
293 204 equemene
  int q,dist,raie;
294 204 equemene

295 204 equemene
  m=Mass;
296 204 equemene
  rs=2.*m;
297 204 equemene
  ri=InternalRadius;
298 204 equemene
  re=ExternalRadius;
299 204 equemene
  ro=ObserverDistance;
300 204 equemene
  tho=Angle;
301 204 equemene
  q=-2;
302 204 equemene
  dist=AngularCamera;
303 204 equemene
  raie=BlackBody;
304 204 equemene

305 204 equemene
  float d,bmx,db,b,h;
306 204 equemene
  float phi,thi,phd,php,nr,r;
307 204 equemene
  int nh;
308 204 equemene
  float zp=0,fp=0;
309 204 equemene

310 204 equemene
  // Autosize for image, 25% greater than externa radius
311 204 equemene
  bmx=1.25*re;
312 204 equemene

313 204 equemene
  // Angular step of integration
314 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
315 204 equemene

316 204 equemene
  // Step of Impact Parameter
317 204 equemene
  db=bmx/(float)ImpactParameter;
318 204 equemene

319 204 equemene
  // set origin as center of image
320 204 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
321 204 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
322 204 equemene

323 204 equemene
  // angle extracted from cylindric symmetry
324 204 equemene
  phi=atanp(x,y);
325 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
326 204 equemene

327 204 equemene
  // Real Impact Parameter
328 204 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
329 204 equemene

330 204 equemene
  // Integer Impact Parameter
331 204 equemene
  uint bi=(uint)sqrt(x*x+y*y);
332 204 equemene

333 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
334 204 equemene

335 204 equemene
  if (bi<ImpactParameter)
336 204 equemene
  {
337 204 equemene
    do
338 204 equemene
    {
339 204 equemene
      php=phd+(float)HalfLap*PI;
340 204 equemene
      nr=php/h;
341 204 equemene
      ni=(int)nr;
342 204 equemene

343 204 equemene
      if (ni<IdLast[bi])
344 204 equemene
      {
345 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
346 204 equemene
      }
347 204 equemene
      else
348 204 equemene
      {
349 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
350 204 equemene
      }
351 204 equemene

352 204 equemene
      if ((r<=re)&&(r>=ri))
353 204 equemene
      {
354 204 equemene
        ExitOnImpact=1;
355 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
356 204 equemene
      }
357 204 equemene

358 204 equemene
      HalfLap++;
359 204 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
360 204 equemene

361 204 equemene
  }
362 204 equemene

363 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
364 204 equemene

365 204 equemene
  zImage[yi+sizex*xi]=zp;
366 204 equemene
  fImage[yi+sizex*xi]=fp;
367 204 equemene
}
368 204 equemene

369 204 equemene
__kernel void Circle(__global float *Trajectories,__global int *IdLast,
370 204 equemene
                     __global float *zImage,__global float *fImage,
371 204 equemene
                     int TrackPoints,
372 204 equemene
                     float Mass,float InternalRadius,
373 204 equemene
                     float ExternalRadius,float Angle,
374 204 equemene
                     float ObserverDistance,
375 204 equemene
                     int BlackBody,int AngularCamera)
376 204 equemene
{
377 204 equemene
   // Integer Impact Parameter ID
378 204 equemene
   int bi=get_global_id(0);
379 204 equemene
   // Integer points on circle
380 204 equemene
   int i=get_global_id(1);
381 204 equemene
   // Integer Impact Parameter Size (half of image)
382 204 equemene
   int bmaxi=get_global_size(0);
383 204 equemene
   // Integer Points on circle
384 204 equemene
   int imx=get_global_size(1);
385 204 equemene

386 204 equemene
   // Perform trajectory for each pixel
387 204 equemene

388 204 equemene
  float m,rs,ri,re,tho,ro;
389 204 equemene
  int q,dist,raie;
390 204 equemene

391 204 equemene
  m=Mass;
392 204 equemene
  rs=2.*m;
393 204 equemene
  ri=InternalRadius;
394 204 equemene
  re=ExternalRadius;
395 204 equemene
  ro=ObserverDistance;
396 204 equemene
  tho=Angle;
397 204 equemene
  q=-2;
398 204 equemene
  dist=AngularCamera;
399 204 equemene
  raie=BlackBody;
400 204 equemene

401 204 equemene
  float bmx,db,b,h;
402 204 equemene
  float phi,thi,phd;
403 204 equemene
  int nh;
404 204 equemene
  float zp=0,fp=0;
405 204 equemene

406 204 equemene
  // Autosize for image
407 204 equemene
  bmx=1.25*re;
408 204 equemene

409 204 equemene
  // Angular step of integration
410 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
411 204 equemene

412 204 equemene
  // impact parameter
413 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
414 204 equemene
  db=bmx/(float)bmaxi;
415 204 equemene

416 204 equemene
  phi=2.*PI/(float)imx*(float)i;
417 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
418 204 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
419 204 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
420 204 equemene

421 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
422 204 equemene
  float php,nr,r;
423 204 equemene

424 204 equemene
  do
425 204 equemene
  {
426 204 equemene
     php=phd+(float)HalfLap*PI;
427 204 equemene
     nr=php/h;
428 204 equemene
     ni=(int)nr;
429 204 equemene

430 204 equemene
     if (ni<IdLast[bi])
431 204 equemene
     {
432 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
433 204 equemene
     }
434 204 equemene
     else
435 204 equemene
     {
436 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
437 204 equemene
     }
438 204 equemene

439 204 equemene
     if ((r<=re)&&(r>=ri))
440 204 equemene
     {
441 204 equemene
        ExitOnImpact=1;
442 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
443 204 equemene
     }
444 204 equemene

445 204 equemene
     HalfLap++;
446 204 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
447 204 equemene

448 204 equemene
  zImage[yi+2*bmaxi*xi]=zp;
449 204 equemene
  fImage[yi+2*bmaxi*xi]=fp;
450 204 equemene

451 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
452 204 equemene

453 204 equemene
}
454 204 equemene

455 204 equemene
__kernel void Trajectory(__global float *Trajectories,
456 204 equemene
                         __global int *IdLast,int TrackPoints,
457 204 equemene
                         float Mass,float InternalRadius,
458 204 equemene
                         float ExternalRadius,float Angle,
459 204 equemene
                         float ObserverDistance,
460 204 equemene
                         int BlackBody,int AngularCamera)
461 204 equemene
{
462 204 equemene
  // Integer Impact Parameter ID
463 204 equemene
  int bi=get_global_id(0);
464 204 equemene
  // Integer Impact Parameter Size (half of image)
465 204 equemene
  int bmaxi=get_global_size(0);
466 204 equemene

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

469 204 equemene
  float m,rs,ri,re,tho,ro;
470 204 equemene
  int dist,raie,q;
471 204 equemene

472 204 equemene
  m=Mass;
473 204 equemene
  rs=2.*m;
474 204 equemene
  ri=InternalRadius;
475 204 equemene
  re=ExternalRadius;
476 204 equemene
  ro=ObserverDistance;
477 204 equemene
  tho=Angle;
478 204 equemene
  q=-2;
479 204 equemene
  dist=AngularCamera;
480 204 equemene
  raie=BlackBody;
481 204 equemene

482 204 equemene
  float d,bmx,db,b,h;
483 204 equemene
  float phi,thi,phd,php,nr,r;
484 204 equemene
  int nh;
485 204 equemene
  float zp,fp;
486 204 equemene

487 204 equemene
  // Autosize for image
488 204 equemene
  bmx=1.25*re;
489 204 equemene

490 204 equemene
  // Angular step of integration
491 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
492 204 equemene

493 204 equemene
  // impact parameter
494 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
495 204 equemene

496 204 equemene
  float up,vp,pp,us,vs,ps;
497 204 equemene

498 204 equemene
  if (dist==1)
499 204 equemene
  {
500 204 equemene
     up=0.;
501 204 equemene
     vp=1.;
502 204 equemene
  }
503 204 equemene
  else
504 204 equemene
  {
505 204 equemene
     thi=asin(b/ro);
506 204 equemene
     up=sin(thi);
507 204 equemene
     vp=cos(thi);
508 204 equemene
  }
509 204 equemene

510 204 equemene
  pp=0.;
511 204 equemene
  nh=0;
512 204 equemene

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

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

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

530 204 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
531 204 equemene

532 204 equemene
  IdLast[bi]=nh;
533 204 equemene

534 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
535 199 equemene

536 199 equemene
}
537 199 equemene
""")
538 199 equemene
539 199 equemene
def ImageOutput(sigma,prefix):
540 199 equemene
    Max=sigma.max()
541 199 equemene
    Min=sigma.min()
542 199 equemene
543 199 equemene
    # Normalize value as 8bits Integer
544 199 equemene
    SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
545 199 equemene
    image = Image.fromarray(SigmaInt)
546 199 equemene
    image.save("%s.jpg" % prefix)
547 199 equemene
548 204 equemene
def BlackHoleCL(zImage,fImage,InputCL):
549 199 equemene
550 199 equemene
    kernel_params = {}
551 199 equemene
552 204 equemene
    print(InputCL)
553 204 equemene
554 204 equemene
    Device=InputCL['Device']
555 204 equemene
    GpuStyle=InputCL['GpuStyle']
556 204 equemene
    VariableType=InputCL['VariableType']
557 204 equemene
    Size=InputCL['Size']
558 204 equemene
    Mass=InputCL['Mass']
559 204 equemene
    InternalRadius=InputCL['InternalRadius']
560 204 equemene
    ExternalRadius=InputCL['ExternalRadius']
561 204 equemene
    Angle=InputCL['Angle']
562 204 equemene
    ObserverDistance=InputCL['ObserverDistance']
563 204 equemene
    Method=InputCL['Method']
564 204 equemene
    TrackPoints=InputCL['TrackPoints']
565 204 equemene
566 204 equemene
    if InputCL['BlackBody']:
567 204 equemene
        BlackBody=0
568 204 equemene
    else:
569 204 equemene
        BlackBody=1
570 204 equemene
571 204 equemene
    if InputCL['AngularCamera']:
572 204 equemene
        AngularCamera=1
573 204 equemene
    else:
574 204 equemene
        AngularCamera=0
575 204 equemene
576 204 equemene
    Trajectories=numpy.zeros((InputCL['Size']/2,InputCL['TrackPoints']),
577 204 equemene
                              dtype=numpy.float32)
578 204 equemene
    IdLast=numpy.zeros(InputCL['Size']/2,dtype=numpy.int32)
579 204 equemene
580 199 equemene
    # Je detecte un peripherique GPU dans la liste des peripheriques
581 199 equemene
    Id=0
582 199 equemene
    HasXPU=False
583 199 equemene
    for platform in cl.get_platforms():
584 199 equemene
        for device in platform.get_devices():
585 199 equemene
            if Id==Device:
586 199 equemene
                XPU=device
587 199 equemene
                print "CPU/GPU selected: ",device.name.lstrip()
588 199 equemene
                HasXPU=True
589 199 equemene
            Id+=1
590 199 equemene
591 199 equemene
    if HasXPU==False:
592 199 equemene
        print "No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1)
593 199 equemene
        sys.exit()
594 199 equemene
595 199 equemene
    ctx = cl.Context([XPU])
596 199 equemene
    queue = cl.CommandQueue(ctx,
597 199 equemene
                            properties=cl.command_queue_properties.PROFILING_ENABLE)
598 199 equemene
599 199 equemene
    BlackHoleCL = cl.Program(ctx,KERNEL_CODE.substitute(kernel_params)).build()
600 199 equemene
601 199 equemene
    # Je recupere les flag possibles pour les buffers
602 199 equemene
    mf = cl.mem_flags
603 199 equemene
604 201 equemene
    print(zImage)
605 199 equemene
606 204 equemene
    TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
607 201 equemene
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
608 201 equemene
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
609 204 equemene
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
610 204 equemene
    IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
611 199 equemene
612 199 equemene
    start_time=time.time()
613 199 equemene
614 204 equemene
    print(Trajectories.shape)
615 204 equemene
    if Method=='EachPixel':
616 204 equemene
        CLLaunch=BlackHoleCL.EachPixel(queue,(zImage.shape[0],zImage.shape[1]),
617 204 equemene
                                       None,zImageCL,fImageCL,
618 204 equemene
                                       numpy.float32(Mass),
619 204 equemene
                                       numpy.float32(InternalRadius),
620 204 equemene
                                       numpy.float32(ExternalRadius),
621 204 equemene
                                       numpy.float32(Angle),
622 204 equemene
                                       numpy.float32(ObserverDistance),
623 204 equemene
                                       numpy.int32(BlackBody),
624 204 equemene
                                       numpy.int32(AngularCamera))
625 204 equemene
        CLLaunch.wait()
626 204 equemene
    elif Method=='TrajectoCircle':
627 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
628 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
629 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
630 204 equemene
                                        numpy.float32(Mass),
631 204 equemene
                                        numpy.float32(InternalRadius),
632 204 equemene
                                        numpy.float32(ExternalRadius),
633 204 equemene
                                        numpy.float32(Angle),
634 204 equemene
                                        numpy.float32(ObserverDistance),
635 204 equemene
                                        numpy.int32(BlackBody),
636 204 equemene
                                        numpy.int32(AngularCamera))
637 204 equemene
638 204 equemene
        CLLaunch=BlackHoleCL.Circle(queue,(Trajectories.shape[0],
639 204 equemene
                                           zImage.shape[0]*4),None,
640 204 equemene
                                    TrajectoriesCL,IdLastCL,
641 204 equemene
                                    zImageCL,fImageCL,
642 204 equemene
                                    numpy.uint32(Trajectories.shape[1]),
643 204 equemene
                                    numpy.float32(Mass),
644 204 equemene
                                    numpy.float32(InternalRadius),
645 204 equemene
                                    numpy.float32(ExternalRadius),
646 204 equemene
                                    numpy.float32(Angle),
647 204 equemene
                                    numpy.float32(ObserverDistance),
648 204 equemene
                                    numpy.int32(BlackBody),
649 204 equemene
                                    numpy.int32(AngularCamera))
650 204 equemene
        CLLaunch.wait()
651 204 equemene
    else:
652 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
653 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
654 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
655 204 equemene
                                        numpy.float32(Mass),
656 204 equemene
                                        numpy.float32(InternalRadius),
657 204 equemene
                                        numpy.float32(ExternalRadius),
658 204 equemene
                                        numpy.float32(Angle),
659 204 equemene
                                        numpy.float32(ObserverDistance),
660 204 equemene
                                        numpy.int32(BlackBody),
661 204 equemene
                                        numpy.int32(AngularCamera))
662 204 equemene
663 204 equemene
        CLLaunch=BlackHoleCL.Pixel(queue,(zImage.shape[0],
664 204 equemene
                                                  zImage.shape[1]),None,
665 204 equemene
                                   zImageCL,fImageCL,TrajectoriesCL,IdLastCL,
666 204 equemene
                                   numpy.uint32(Trajectories.shape[0]),
667 204 equemene
                                   numpy.uint32(Trajectories.shape[1]),
668 204 equemene
                                        numpy.float32(Mass),
669 204 equemene
                                        numpy.float32(InternalRadius),
670 204 equemene
                                        numpy.float32(ExternalRadius),
671 204 equemene
                                        numpy.float32(Angle),
672 204 equemene
                                        numpy.float32(ObserverDistance),
673 204 equemene
                                        numpy.int32(BlackBody),
674 204 equemene
                                        numpy.int32(AngularCamera))
675 204 equemene
        CLLaunch.wait()
676 204 equemene
677 199 equemene
    elapsed = time.time()-start_time
678 199 equemene
    print("Elapsed %f: " % elapsed)
679 199 equemene
680 201 equemene
    cl.enqueue_copy(queue,zImage,zImageCL).wait()
681 201 equemene
    cl.enqueue_copy(queue,fImage,fImageCL).wait()
682 204 equemene
    cl.enqueue_copy(queue,Trajectories,TrajectoriesCL).wait()
683 204 equemene
    cl.enqueue_copy(queue,IdLast,IdLastCL).wait()
684 199 equemene
685 201 equemene
    print(zImage.max())
686 201 equemene
    print(fImage.max())
687 201 equemene
    zImageCL.release()
688 201 equemene
    fImageCL.release()
689 204 equemene
690 204 equemene
    TrajectoriesCL.release()
691 204 equemene
    IdLastCL.release()
692 204 equemene
693 199 equemene
    return(elapsed)
694 199 equemene
695 199 equemene
if __name__=='__main__':
696 199 equemene
697 199 equemene
    GpuStyle = 'OpenCL'
698 199 equemene
    Mass = 1.
699 199 equemene
    # Internal Radius 3 times de Schwarzschild Radius
700 199 equemene
    InternalRadius=6.*Mass
701 199 equemene
    #
702 199 equemene
    ExternalRadius=12.
703 199 equemene
    #
704 199 equemene
    ObserverDistance=100.
705 199 equemene
    # Angle with normal to disc 10 degrees
706 199 equemene
    Angle = numpy.pi/180.*(90.-10.)
707 199 equemene
    # Radiation of disc : BlackBody or Monochromatic
708 199 equemene
    BlackBody = True
709 199 equemene
    # Camera : Angular Camera or plate with the size of camera
710 199 equemene
    AngularCamera = True
711 199 equemene
    # Size of image
712 199 equemene
    Size=256
713 199 equemene
    # Variable Type
714 199 equemene
    VariableType='FP32'
715 199 equemene
    # ?
716 199 equemene
    q=-2
717 204 equemene
    # Method of resolution
718 204 equemene
    Method='Trajecto'
719 199 equemene
720 204 equemene
    HowToUse='%s -h [Help] -b [BlackBodyEmission] -c [AngularCamera] -s <SizeInPixels> -m <Mass> -i <DiscInternalRadius> -x <DiscExternalRadius> -o <ObservatorDistance> -a <AngleAboveDisc> -d <DeviceId> -g <CUDA/OpenCL> -t <EachPixel/TrajectoCircle/TrajectoPixel> -v <FP32/FP64>'
721 199 equemene
722 199 equemene
    try:
723 204 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hbcs:m:i:x:o:a:d:g:v:t:",["blackbody","camera","size=","mass=","internal=","external=","observer=","angle=","device=","gpustyle=","variabletype=","method="])
724 199 equemene
    except getopt.GetoptError:
725 199 equemene
        print(HowToUse % sys.argv[0])
726 199 equemene
        sys.exit(2)
727 199 equemene
728 199 equemene
    # List of Devices
729 199 equemene
    Devices=[]
730 199 equemene
    Alu={}
731 199 equemene
732 199 equemene
    for opt, arg in opts:
733 199 equemene
        if opt == '-h':
734 199 equemene
            print(HowToUse % sys.argv[0])
735 199 equemene
736 199 equemene
            print("\nInformations about devices detected under OpenCL API:")
737 199 equemene
            # For PyOpenCL import
738 199 equemene
            try:
739 199 equemene
                import pyopencl as cl
740 199 equemene
                Id=0
741 199 equemene
                for platform in cl.get_platforms():
742 199 equemene
                    for device in platform.get_devices():
743 199 equemene
                        #deviceType=cl.device_type.to_string(device.type)
744 199 equemene
                        deviceType="xPU"
745 199 equemene
                        print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip(),deviceType,device.name.lstrip()))
746 199 equemene
                        Id=Id+1
747 199 equemene
748 199 equemene
            except:
749 199 equemene
                print("Your platform does not seem to support OpenCL")
750 199 equemene
751 199 equemene
            print("\nInformations about devices detected under CUDA API:")
752 199 equemene
                # For PyCUDA import
753 199 equemene
            try:
754 199 equemene
                import pycuda.driver as cuda
755 199 equemene
                cuda.init()
756 199 equemene
                for Id in range(cuda.Device.count()):
757 199 equemene
                    device=cuda.Device(Id)
758 199 equemene
                    print("Device #%i of type GPU : %s" % (Id,device.name()))
759 199 equemene
                print
760 199 equemene
            except:
761 199 equemene
                print("Your platform does not seem to support CUDA")
762 199 equemene
763 199 equemene
            sys.exit()
764 199 equemene
765 199 equemene
        elif opt in ("-d", "--device"):
766 199 equemene
#            Devices.append(int(arg))
767 199 equemene
            Device=int(arg)
768 199 equemene
        elif opt in ("-g", "--gpustyle"):
769 199 equemene
            GpuStyle = arg
770 204 equemene
        elif opt in ("-v", "--variabletype"):
771 199 equemene
            VariableType = arg
772 199 equemene
        elif opt in ("-s", "--size"):
773 199 equemene
            Size = int(arg)
774 199 equemene
        elif opt in ("-m", "--mass"):
775 199 equemene
            Mass = float(arg)
776 199 equemene
        elif opt in ("-i", "--internal"):
777 199 equemene
            InternalRadius = float(arg)
778 199 equemene
        elif opt in ("-e", "--external"):
779 199 equemene
            ExternalRadius = float(arg)
780 199 equemene
        elif opt in ("-o", "--observer"):
781 199 equemene
            ObserverDistance = float(arg)
782 199 equemene
        elif opt in ("-a", "--angle"):
783 199 equemene
            Angle = numpy.pi/180.*(90.-float(arg))
784 199 equemene
        elif opt in ("-b", "--blackbody"):
785 199 equemene
            BlackBody = True
786 199 equemene
        elif opt in ("-c", "--camera"):
787 199 equemene
            AngularCamera = True
788 204 equemene
        elif opt in ("-t", "--method"):
789 204 equemene
            Method = arg
790 199 equemene
791 199 equemene
    print("Device Identification selected : %s" % Device)
792 199 equemene
    print("GpuStyle used : %s" % GpuStyle)
793 199 equemene
    print("VariableType : %s" % VariableType)
794 199 equemene
    print("Size : %i" % Size)
795 199 equemene
    print("Mass : %f" % Mass)
796 199 equemene
    print("Internal Radius : %f" % InternalRadius)
797 199 equemene
    print("External Radius : %f" % ExternalRadius)
798 199 equemene
    print("Observer Distance : %f" % ObserverDistance)
799 199 equemene
    print("Angle with normal of (in radians) : %f" % Angle)
800 199 equemene
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
801 199 equemene
    print("Angular Camera (dimension of object instead) : %s" % AngularCamera)
802 204 equemene
    print("Method of resolution : %s" % Method)
803 199 equemene
804 199 equemene
    if GpuStyle=='CUDA':
805 199 equemene
        print("\nSelection of CUDA device")
806 199 equemene
        try:
807 199 equemene
            # For PyCUDA import
808 199 equemene
            import pycuda.driver as cuda
809 199 equemene
810 199 equemene
            cuda.init()
811 199 equemene
            for Id in range(cuda.Device.count()):
812 199 equemene
                device=cuda.Device(Id)
813 199 equemene
                print("Device #%i of type GPU : %s" % (Id,device.name()))
814 199 equemene
                if Id in Devices:
815 199 equemene
                    Alu[Id]='GPU'
816 199 equemene
817 199 equemene
        except ImportError:
818 199 equemene
            print("Platform does not seem to support CUDA")
819 199 equemene
820 199 equemene
    if GpuStyle=='OpenCL':
821 199 equemene
        print("\nSelection of OpenCL device")
822 199 equemene
        try:
823 199 equemene
            # For PyOpenCL import
824 199 equemene
            import pyopencl as cl
825 199 equemene
            Id=0
826 199 equemene
            for platform in cl.get_platforms():
827 199 equemene
                for device in platform.get_devices():
828 199 equemene
                    #deviceType=cl.device_type.to_string(device.type)
829 199 equemene
                    deviceType="xPU"
830 199 equemene
                    print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip().rstrip(),deviceType,device.name.lstrip().rstrip()))
831 199 equemene
832 199 equemene
                    if Id in Devices:
833 199 equemene
                    # Set the Alu as detected Device Type
834 199 equemene
                        Alu[Id]=deviceType
835 199 equemene
                    Id=Id+1
836 199 equemene
        except ImportError:
837 199 equemene
            print("Platform does not seem to support OpenCL")
838 199 equemene
839 199 equemene
#    print(Devices,Alu)
840 199 equemene
841 199 equemene
#    MyImage=numpy.where(numpy.random.zeros(Size,Size)>0,1,-1).astype(numpy.float32)
842 204 equemene
    TrackPoints=2048
843 201 equemene
    zImage=numpy.zeros((Size,Size),dtype=numpy.float32)
844 201 equemene
    fImage=numpy.zeros((Size,Size),dtype=numpy.float32)
845 199 equemene
846 204 equemene
    InputCL={}
847 204 equemene
    InputCL['Device']=Device
848 204 equemene
    InputCL['GpuStyle']=GpuStyle
849 204 equemene
    InputCL['VariableType']=VariableType
850 204 equemene
    InputCL['Size']=Size
851 204 equemene
    InputCL['Mass']=Mass
852 204 equemene
    InputCL['InternalRadius']=InternalRadius
853 204 equemene
    InputCL['ExternalRadius']=ExternalRadius
854 204 equemene
    InputCL['ObserverDistance']=ObserverDistance
855 204 equemene
    InputCL['Angle']=Angle
856 204 equemene
    InputCL['BlackBody']=BlackBody
857 204 equemene
    InputCL['AngularCamera']=AngularCamera
858 204 equemene
    InputCL['Method']=Method
859 204 equemene
    InputCL['TrackPoints']=TrackPoints
860 204 equemene
861 204 equemene
    duration=BlackHoleCL(zImage,fImage,InputCL)
862 199 equemene
863 204 equemene
    ImageOutput(zImage,"TrouNoirZ_%s" % Method)
864 204 equemene
    ImageOutput(fImage,"TrouNoirF_%s" % Method)