Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 212

Historique | Voir | Annoter | Télécharger (23,66 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
import time,string
30 199 equemene
from numpy.random import randint as nprnd
31 199 equemene
import sys
32 199 equemene
import getopt
33 199 equemene
import matplotlib.pyplot as plt
34 211 equemene
from socket import gethostname
35 199 equemene
36 211 equemene
def DictionariesAPI():
37 211 equemene
    PhysicsList={'Einstein':0,'Newton':1}
38 211 equemene
    return(PhysicsList)
39 204 equemene
40 211 equemene
BlobOpenCL= """
41 204 equemene

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

45 211 equemene
#define EINSTEIN 0
46 211 equemene
#define NEWTON 1
47 211 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 211 equemene
#if PHYSICS == NEWTON
68 199 equemene
float g(float u,float m,float b)
69 199 equemene
{
70 211 equemene
  return (-u);
71 211 equemene
}
72 211 equemene
#else
73 211 equemene
float g(float u,float m,float b)
74 211 equemene
{
75 204 equemene
  return (3.e0f*m/b*pow(u,2)-u);
76 199 equemene
}
77 211 equemene
#endif
78 199 equemene

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

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

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

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

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

111 199 equemene
float spectre(float rf,int q,float b,float db,
112 199 equemene
             float h,float r,float m,float bss)
113 199 equemene
{
114 199 equemene
  float flx;
115 199 equemene

116 209 equemene
  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
117 199 equemene
  return(flx);
118 199 equemene
}
119 199 equemene

120 209 equemene
float spectre_cn(float rf32,float b32,float db32,
121 209 equemene
                 float h32,float r32,float m32,float bss32)
122 199 equemene
{
123 209 equemene

124 209 equemene
#define MYFLOAT double
125 209 equemene

126 209 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
127 209 equemene
  MYFLOAT b=(MYFLOAT)(b32);
128 209 equemene
  MYFLOAT db=(MYFLOAT)(db32);
129 209 equemene
  MYFLOAT h=(MYFLOAT)(h32);
130 209 equemene
  MYFLOAT r=(MYFLOAT)(r32);
131 209 equemene
  MYFLOAT m=(MYFLOAT)(m32);
132 209 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
133 209 equemene

134 209 equemene
  MYFLOAT flx;
135 209 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
136 199 equemene
  int fi,posfreq;
137 199 equemene

138 209 equemene
#define planck 6.62e-34
139 209 equemene
#define k 1.38e-23
140 209 equemene
#define c2 9.e16
141 209 equemene
#define temp 3.e7
142 209 equemene
#define m_point 1.
143 199 equemene

144 209 equemene
#define lplanck (log(6.62)-34.*log(10.))
145 209 equemene
#define lk (log(1.38)-23.*log(10.))
146 209 equemene
#define lc2 (log(9.)+16.*log(10.))
147 199 equemene

148 209 equemene
  MYFLOAT v=1.-3./r;
149 199 equemene

150 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 ));
151 199 equemene

152 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)));
153 209 equemene

154 209 equemene
  flux_int=0.;
155 209 equemene
  flx=0.;
156 209 equemene

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

172 199 equemene
          flx+=flux_int;
173 199 equemene
        }
174 199 equemene
    }
175 209 equemene

176 209 equemene
  return((float)(flx));
177 199 equemene
}
178 199 equemene

179 199 equemene
void impact(float phi,float r,float b,float tho,float m,
180 199 equemene
            float *zp,float *fp,
181 199 equemene
            int q,float db,
182 204 equemene
            float h,int raie)
183 199 equemene
{
184 204 equemene
  float flx,rf,bss;
185 199 equemene

186 199 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
187 199 equemene

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

199 199 equemene
  *zp=1./rf;
200 199 equemene
  *fp=flx;
201 199 equemene

202 199 equemene
}
203 199 equemene

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

214 204 equemene
   // Perform trajectory for each pixel, exit on hit
215 199 equemene

216 209 equemene
  float m,rs,ri,re,tho;
217 209 equemene
  int q,raie;
218 199 equemene

219 204 equemene
  m=Mass;
220 204 equemene
  rs=2.*m;
221 204 equemene
  ri=InternalRadius;
222 204 equemene
  re=ExternalRadius;
223 204 equemene
  tho=Angle;
224 204 equemene
  q=-2;
225 209 equemene
  raie=Line;
226 204 equemene

227 199 equemene
  float d,bmx,db,b,h;
228 204 equemene
  float rp[2048];
229 204 equemene
  float phi,thi,phd,php,nr,r;
230 199 equemene
  int nh;
231 199 equemene
  float zp,fp;
232 199 equemene

233 199 equemene
  // Autosize for image
234 199 equemene
  bmx=1.25*re;
235 199 equemene
  b=0.;
236 199 equemene

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

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

246 204 equemene
  float up,vp,pp,us,vs,ps;
247 204 equemene

248 204 equemene
  // impact parameter
249 204 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
250 204 equemene
  // step of impact parameter;
251 209 equemene
//  db=bmx/(float)(sizex/2);
252 209 equemene
  db=bmx/(float)(sizex);
253 204 equemene

254 209 equemene
  up=0.;
255 209 equemene
  vp=1.;
256 199 equemene

257 199 equemene
  pp=0.;
258 199 equemene
  nh=0;
259 199 equemene

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

262 199 equemene
  rp[nh]=fabs(b/us);
263 199 equemene

264 204 equemene
  int ExitOnImpact=0;
265 199 equemene

266 199 equemene
  do
267 199 equemene
  {
268 199 equemene
     nh++;
269 199 equemene
     pp=ps;
270 199 equemene
     up=us;
271 199 equemene
     vp=vs;
272 199 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
273 199 equemene
     rp[nh]=fabs(b/us);
274 200 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rp[nh]>ri)&&(rp[nh]<re)?1:0;
275 199 equemene

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

278 199 equemene
  if (ExitOnImpact==1) {
279 204 equemene
     impact(phi,rp[nh-1],b,tho,m,&zp,&fp,q,db,h,raie);
280 199 equemene
  }
281 199 equemene
  else
282 199 equemene
  {
283 199 equemene
     zp=0.;
284 201 equemene
     fp=0.;
285 199 equemene
  }
286 199 equemene

287 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
288 204 equemene

289 201 equemene
  zImage[yi+sizex*xi]=(float)zp;
290 204 equemene
  fImage[yi+sizex*xi]=(float)fp;
291 204 equemene
}
292 199 equemene

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

305 204 equemene
   // Perform trajectory for each pixel
306 204 equemene

307 209 equemene
  float m,rs,ri,re,tho;
308 209 equemene
  int q,raie;
309 204 equemene

310 204 equemene
  m=Mass;
311 204 equemene
  rs=2.*m;
312 204 equemene
  ri=InternalRadius;
313 204 equemene
  re=ExternalRadius;
314 204 equemene
  tho=Angle;
315 204 equemene
  q=-2;
316 209 equemene
  raie=Line;
317 204 equemene

318 204 equemene
  float d,bmx,db,b,h;
319 204 equemene
  float phi,thi,phd,php,nr,r;
320 204 equemene
  int nh;
321 204 equemene
  float zp=0,fp=0;
322 204 equemene

323 209 equemene
  // Autosize for image, 25% greater than external radius
324 204 equemene
  bmx=1.25*re;
325 204 equemene

326 204 equemene
  // Angular step of integration
327 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
328 204 equemene

329 204 equemene
  // Step of Impact Parameter
330 209 equemene
  db=bmx/(2.e0*(float)ImpactParameter);
331 204 equemene

332 204 equemene
  // set origin as center of image
333 204 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
334 204 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
335 204 equemene

336 204 equemene
  // angle extracted from cylindric symmetry
337 204 equemene
  phi=atanp(x,y);
338 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
339 204 equemene

340 204 equemene
  // Real Impact Parameter
341 204 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
342 204 equemene

343 204 equemene
  // Integer Impact Parameter
344 204 equemene
  uint bi=(uint)sqrt(x*x+y*y);
345 204 equemene

346 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
347 204 equemene

348 204 equemene
  if (bi<ImpactParameter)
349 204 equemene
  {
350 204 equemene
    do
351 204 equemene
    {
352 204 equemene
      php=phd+(float)HalfLap*PI;
353 204 equemene
      nr=php/h;
354 204 equemene
      ni=(int)nr;
355 204 equemene

356 204 equemene
      if (ni<IdLast[bi])
357 204 equemene
      {
358 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
359 204 equemene
      }
360 204 equemene
      else
361 204 equemene
      {
362 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
363 204 equemene
      }
364 204 equemene

365 204 equemene
      if ((r<=re)&&(r>=ri))
366 204 equemene
      {
367 204 equemene
        ExitOnImpact=1;
368 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
369 204 equemene
      }
370 204 equemene

371 204 equemene
      HalfLap++;
372 204 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
373 204 equemene

374 204 equemene
  }
375 204 equemene

376 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
377 204 equemene

378 204 equemene
  zImage[yi+sizex*xi]=zp;
379 204 equemene
  fImage[yi+sizex*xi]=fp;
380 204 equemene
}
381 204 equemene

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

398 204 equemene
   // Perform trajectory for each pixel
399 204 equemene

400 209 equemene
  float m,rs,ri,re,tho;
401 209 equemene
  int q,raie;
402 204 equemene

403 204 equemene
  m=Mass;
404 204 equemene
  rs=2.*m;
405 204 equemene
  ri=InternalRadius;
406 204 equemene
  re=ExternalRadius;
407 204 equemene
  tho=Angle;
408 209 equemene
  raie=Line;
409 204 equemene

410 204 equemene
  float bmx,db,b,h;
411 204 equemene
  float phi,thi,phd;
412 204 equemene
  int nh;
413 204 equemene
  float zp=0,fp=0;
414 204 equemene

415 204 equemene
  // Autosize for image
416 204 equemene
  bmx=1.25*re;
417 204 equemene

418 204 equemene
  // Angular step of integration
419 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
420 204 equemene

421 204 equemene
  // impact parameter
422 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
423 209 equemene
  db=bmx/(2.e0*(float)bmaxi);
424 204 equemene

425 204 equemene
  phi=2.*PI/(float)imx*(float)i;
426 204 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
427 204 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
428 204 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
429 204 equemene

430 204 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
431 204 equemene
  float php,nr,r;
432 204 equemene

433 204 equemene
  do
434 204 equemene
  {
435 204 equemene
     php=phd+(float)HalfLap*PI;
436 204 equemene
     nr=php/h;
437 204 equemene
     ni=(int)nr;
438 204 equemene

439 204 equemene
     if (ni<IdLast[bi])
440 204 equemene
     {
441 204 equemene
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
442 204 equemene
     }
443 204 equemene
     else
444 204 equemene
     {
445 204 equemene
        r=Trajectories[bi*TrackPoints+ni];
446 204 equemene
     }
447 204 equemene

448 204 equemene
     if ((r<=re)&&(r>=ri))
449 204 equemene
     {
450 204 equemene
        ExitOnImpact=1;
451 204 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
452 204 equemene
     }
453 204 equemene

454 204 equemene
     HalfLap++;
455 204 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
456 204 equemene

457 204 equemene
  zImage[yi+2*bmaxi*xi]=zp;
458 204 equemene
  fImage[yi+2*bmaxi*xi]=fp;
459 204 equemene

460 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
461 204 equemene

462 204 equemene
}
463 204 equemene

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

475 204 equemene
  // Perform trajectory for each pixel
476 204 equemene

477 209 equemene
  float m,rs,ri,re,tho;
478 209 equemene
  int raie,q;
479 204 equemene

480 204 equemene
  m=Mass;
481 204 equemene
  rs=2.*m;
482 204 equemene
  ri=InternalRadius;
483 204 equemene
  re=ExternalRadius;
484 204 equemene
  tho=Angle;
485 204 equemene
  q=-2;
486 209 equemene
  raie=Line;
487 204 equemene

488 204 equemene
  float d,bmx,db,b,h;
489 204 equemene
  float phi,thi,phd,php,nr,r;
490 204 equemene
  int nh;
491 204 equemene
  float zp,fp;
492 204 equemene

493 204 equemene
  // Autosize for image
494 204 equemene
  bmx=1.25*re;
495 204 equemene

496 204 equemene
  // Angular step of integration
497 204 equemene
  h=4.e0f*PI/(float)TrackPoints;
498 204 equemene

499 204 equemene
  // impact parameter
500 204 equemene
  b=(float)bi/(float)bmaxi*bmx;
501 204 equemene

502 204 equemene
  float up,vp,pp,us,vs,ps;
503 204 equemene

504 209 equemene
  up=0.;
505 209 equemene
  vp=1.;
506 204 equemene

507 204 equemene
  pp=0.;
508 204 equemene
  nh=0;
509 204 equemene

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

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

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

527 204 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
528 204 equemene

529 204 equemene
  IdLast[bi]=nh;
530 204 equemene

531 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
532 199 equemene

533 199 equemene
}
534 211 equemene
"""
535 199 equemene
536 211 equemene
# def ImageOutput(sigma,prefix):
537 211 equemene
#     from PIL import Image
538 211 equemene
#     Max=sigma.max()
539 211 equemene
#     Min=sigma.min()
540 199 equemene
541 211 equemene
#     # Normalize value as 8bits Integer
542 211 equemene
#     SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
543 211 equemene
#     image = Image.fromarray(SigmaInt)
544 211 equemene
#     image.save("%s.jpg" % prefix)
545 211 equemene
546 211 equemene
def ImageOutput(sigma,prefix,Colors):
547 211 equemene
    import matplotlib.pyplot as plt
548 211 equemene
    if Colors == 'Red2Yellow':
549 211 equemene
        plt.imsave("%s.png" % prefix, sigma, cmap='afmhot')
550 211 equemene
    else:
551 211 equemene
        plt.imsave("%s.png" % prefix, sigma, cmap='Greys_r')
552 211 equemene
553 204 equemene
def BlackHoleCL(zImage,fImage,InputCL):
554 199 equemene
555 199 equemene
    kernel_params = {}
556 199 equemene
557 204 equemene
    print(InputCL)
558 204 equemene
559 204 equemene
    Device=InputCL['Device']
560 204 equemene
    GpuStyle=InputCL['GpuStyle']
561 204 equemene
    VariableType=InputCL['VariableType']
562 204 equemene
    Size=InputCL['Size']
563 204 equemene
    Mass=InputCL['Mass']
564 204 equemene
    InternalRadius=InputCL['InternalRadius']
565 204 equemene
    ExternalRadius=InputCL['ExternalRadius']
566 204 equemene
    Angle=InputCL['Angle']
567 204 equemene
    Method=InputCL['Method']
568 204 equemene
    TrackPoints=InputCL['TrackPoints']
569 211 equemene
    Physics=InputCL['Physics']
570 204 equemene
571 211 equemene
    PhysicsList=DictionariesAPI()
572 211 equemene
573 204 equemene
    if InputCL['BlackBody']:
574 209 equemene
        # Spectrum is Black Body one
575 209 equemene
        Line=0
576 204 equemene
    else:
577 209 equemene
        # Spectrum is Monochromatic Line one
578 209 equemene
        Line=1
579 204 equemene
580 204 equemene
    Trajectories=numpy.zeros((InputCL['Size']/2,InputCL['TrackPoints']),
581 204 equemene
                              dtype=numpy.float32)
582 204 equemene
    IdLast=numpy.zeros(InputCL['Size']/2,dtype=numpy.int32)
583 204 equemene
584 199 equemene
    # Je detecte un peripherique GPU dans la liste des peripheriques
585 199 equemene
    Id=0
586 199 equemene
    HasXPU=False
587 199 equemene
    for platform in cl.get_platforms():
588 199 equemene
        for device in platform.get_devices():
589 199 equemene
            if Id==Device:
590 199 equemene
                XPU=device
591 199 equemene
                print "CPU/GPU selected: ",device.name.lstrip()
592 199 equemene
                HasXPU=True
593 199 equemene
            Id+=1
594 199 equemene
595 199 equemene
    if HasXPU==False:
596 199 equemene
        print "No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1)
597 199 equemene
        sys.exit()
598 199 equemene
599 199 equemene
    ctx = cl.Context([XPU])
600 199 equemene
    queue = cl.CommandQueue(ctx,
601 199 equemene
                            properties=cl.command_queue_properties.PROFILING_ENABLE)
602 199 equemene
603 199 equemene
604 211 equemene
    #    BlackHoleCL = cl.Program(ctx,KERNEL_CODE.substitute(kernel_params)).build()
605 211 equemene
606 211 equemene
    BuildOptions="-cl-mad-enable -DPHYSICS=%i " % (PhysicsList[Physics])
607 211 equemene
608 211 equemene
    BlackHoleCL = cl.Program(ctx,BlobOpenCL).build(options = BuildOptions)
609 211 equemene
610 199 equemene
    # Je recupere les flag possibles pour les buffers
611 199 equemene
    mf = cl.mem_flags
612 199 equemene
613 204 equemene
    TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
614 201 equemene
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
615 201 equemene
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
616 204 equemene
    IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
617 199 equemene
618 199 equemene
    start_time=time.time()
619 199 equemene
620 204 equemene
    if Method=='EachPixel':
621 204 equemene
        CLLaunch=BlackHoleCL.EachPixel(queue,(zImage.shape[0],zImage.shape[1]),
622 204 equemene
                                       None,zImageCL,fImageCL,
623 204 equemene
                                       numpy.float32(Mass),
624 204 equemene
                                       numpy.float32(InternalRadius),
625 204 equemene
                                       numpy.float32(ExternalRadius),
626 204 equemene
                                       numpy.float32(Angle),
627 209 equemene
                                       numpy.int32(Line))
628 204 equemene
        CLLaunch.wait()
629 204 equemene
    elif Method=='TrajectoCircle':
630 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
631 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
632 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
633 204 equemene
                                        numpy.float32(Mass),
634 204 equemene
                                        numpy.float32(InternalRadius),
635 204 equemene
                                        numpy.float32(ExternalRadius),
636 204 equemene
                                        numpy.float32(Angle),
637 209 equemene
                                        numpy.int32(Line))
638 204 equemene
639 204 equemene
        CLLaunch=BlackHoleCL.Circle(queue,(Trajectories.shape[0],
640 204 equemene
                                           zImage.shape[0]*4),None,
641 204 equemene
                                    TrajectoriesCL,IdLastCL,
642 204 equemene
                                    zImageCL,fImageCL,
643 204 equemene
                                    numpy.uint32(Trajectories.shape[1]),
644 204 equemene
                                    numpy.float32(Mass),
645 204 equemene
                                    numpy.float32(InternalRadius),
646 204 equemene
                                    numpy.float32(ExternalRadius),
647 204 equemene
                                    numpy.float32(Angle),
648 209 equemene
                                    numpy.int32(Line))
649 204 equemene
        CLLaunch.wait()
650 204 equemene
    else:
651 204 equemene
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
652 204 equemene
                                        None,TrajectoriesCL,IdLastCL,
653 204 equemene
                                        numpy.uint32(Trajectories.shape[1]),
654 204 equemene
                                        numpy.float32(Mass),
655 204 equemene
                                        numpy.float32(InternalRadius),
656 204 equemene
                                        numpy.float32(ExternalRadius),
657 204 equemene
                                        numpy.float32(Angle),
658 209 equemene
                                        numpy.int32(Line))
659 204 equemene
660 204 equemene
        CLLaunch=BlackHoleCL.Pixel(queue,(zImage.shape[0],
661 204 equemene
                                                  zImage.shape[1]),None,
662 204 equemene
                                   zImageCL,fImageCL,TrajectoriesCL,IdLastCL,
663 204 equemene
                                   numpy.uint32(Trajectories.shape[0]),
664 204 equemene
                                   numpy.uint32(Trajectories.shape[1]),
665 204 equemene
                                        numpy.float32(Mass),
666 204 equemene
                                        numpy.float32(InternalRadius),
667 204 equemene
                                        numpy.float32(ExternalRadius),
668 204 equemene
                                        numpy.float32(Angle),
669 209 equemene
                                        numpy.int32(Line))
670 204 equemene
        CLLaunch.wait()
671 204 equemene
672 199 equemene
    elapsed = time.time()-start_time
673 211 equemene
    print("\nElapsed Time : %f" % elapsed)
674 199 equemene
675 201 equemene
    cl.enqueue_copy(queue,zImage,zImageCL).wait()
676 201 equemene
    cl.enqueue_copy(queue,fImage,fImageCL).wait()
677 204 equemene
    cl.enqueue_copy(queue,Trajectories,TrajectoriesCL).wait()
678 204 equemene
    cl.enqueue_copy(queue,IdLast,IdLastCL).wait()
679 211 equemene
680 211 equemene
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
681 211 equemene
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
682 211 equemene
    print("Z max @(%i,%i) : %f" % (zMaxPosition[0],zMaxPosition[1],zImage.max()))
683 211 equemene
    print("Flux max @(%i,%i) : %f\n" % (fMaxPosition[0],fMaxPosition[1],fImage.max()))
684 201 equemene
    zImageCL.release()
685 201 equemene
    fImageCL.release()
686 204 equemene
687 204 equemene
    TrajectoriesCL.release()
688 204 equemene
    IdLastCL.release()
689 204 equemene
690 199 equemene
    return(elapsed)
691 199 equemene
692 199 equemene
if __name__=='__main__':
693 199 equemene
694 199 equemene
    GpuStyle = 'OpenCL'
695 199 equemene
    Mass = 1.
696 199 equemene
    # Internal Radius 3 times de Schwarzschild Radius
697 199 equemene
    InternalRadius=6.*Mass
698 199 equemene
    #
699 199 equemene
    ExternalRadius=12.
700 199 equemene
    #
701 199 equemene
    # Angle with normal to disc 10 degrees
702 199 equemene
    Angle = numpy.pi/180.*(90.-10.)
703 199 equemene
    # Radiation of disc : BlackBody or Monochromatic
704 209 equemene
    BlackBody = False
705 199 equemene
    # Size of image
706 199 equemene
    Size=256
707 199 equemene
    # Variable Type
708 199 equemene
    VariableType='FP32'
709 199 equemene
    # ?
710 199 equemene
    q=-2
711 204 equemene
    # Method of resolution
712 209 equemene
    Method='TrajectoPixel'
713 211 equemene
    # Colors for output image
714 211 equemene
    Colors='Greyscale'
715 211 equemene
    # Physics
716 211 equemene
    Physics='Einstein'
717 211 equemene
    # No output as image
718 211 equemene
    NoImage = False
719 211 equemene
720 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>'
721 199 equemene
722 199 equemene
    try:
723 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="])
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 ("-a", "--angle"):
781 199 equemene
            Angle = numpy.pi/180.*(90.-float(arg))
782 199 equemene
        elif opt in ("-b", "--blackbody"):
783 199 equemene
            BlackBody = True
784 211 equemene
        elif opt in ("-n", "--noimage"):
785 211 equemene
            NoImage = True
786 204 equemene
        elif opt in ("-t", "--method"):
787 204 equemene
            Method = arg
788 211 equemene
        elif opt in ("-c", "--colors"):
789 211 equemene
            Colors = arg
790 211 equemene
        elif opt in ("-p", "--physics"):
791 211 equemene
            Physics = arg
792 199 equemene
793 199 equemene
    print("Device Identification selected : %s" % Device)
794 199 equemene
    print("GpuStyle used : %s" % GpuStyle)
795 199 equemene
    print("VariableType : %s" % VariableType)
796 199 equemene
    print("Size : %i" % Size)
797 199 equemene
    print("Mass : %f" % Mass)
798 199 equemene
    print("Internal Radius : %f" % InternalRadius)
799 199 equemene
    print("External Radius : %f" % ExternalRadius)
800 199 equemene
    print("Angle with normal of (in radians) : %f" % Angle)
801 199 equemene
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
802 204 equemene
    print("Method of resolution : %s" % Method)
803 211 equemene
    print("Colors for output images : %s" % Colors)
804 211 equemene
    print("Physics used for Trajectories : %s" % Physics)
805 199 equemene
806 199 equemene
    if GpuStyle=='CUDA':
807 199 equemene
        print("\nSelection of CUDA device")
808 199 equemene
        try:
809 199 equemene
            # For PyCUDA import
810 199 equemene
            import pycuda.driver as cuda
811 199 equemene
812 199 equemene
            cuda.init()
813 199 equemene
            for Id in range(cuda.Device.count()):
814 199 equemene
                device=cuda.Device(Id)
815 199 equemene
                print("Device #%i of type GPU : %s" % (Id,device.name()))
816 199 equemene
                if Id in Devices:
817 199 equemene
                    Alu[Id]='GPU'
818 199 equemene
819 199 equemene
        except ImportError:
820 199 equemene
            print("Platform does not seem to support CUDA")
821 199 equemene
822 199 equemene
    if GpuStyle=='OpenCL':
823 199 equemene
        print("\nSelection of OpenCL device")
824 199 equemene
        try:
825 199 equemene
            # For PyOpenCL import
826 199 equemene
            import pyopencl as cl
827 199 equemene
            Id=0
828 199 equemene
            for platform in cl.get_platforms():
829 199 equemene
                for device in platform.get_devices():
830 199 equemene
                    #deviceType=cl.device_type.to_string(device.type)
831 199 equemene
                    deviceType="xPU"
832 199 equemene
                    print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip().rstrip(),deviceType,device.name.lstrip().rstrip()))
833 199 equemene
834 199 equemene
                    if Id in Devices:
835 199 equemene
                    # Set the Alu as detected Device Type
836 199 equemene
                        Alu[Id]=deviceType
837 199 equemene
                    Id=Id+1
838 199 equemene
        except ImportError:
839 199 equemene
            print("Platform does not seem to support OpenCL")
840 199 equemene
841 199 equemene
#    print(Devices,Alu)
842 199 equemene
843 199 equemene
#    MyImage=numpy.where(numpy.random.zeros(Size,Size)>0,1,-1).astype(numpy.float32)
844 204 equemene
    TrackPoints=2048
845 201 equemene
    zImage=numpy.zeros((Size,Size),dtype=numpy.float32)
846 201 equemene
    fImage=numpy.zeros((Size,Size),dtype=numpy.float32)
847 199 equemene
848 204 equemene
    InputCL={}
849 204 equemene
    InputCL['Device']=Device
850 204 equemene
    InputCL['GpuStyle']=GpuStyle
851 204 equemene
    InputCL['VariableType']=VariableType
852 204 equemene
    InputCL['Size']=Size
853 204 equemene
    InputCL['Mass']=Mass
854 204 equemene
    InputCL['InternalRadius']=InternalRadius
855 204 equemene
    InputCL['ExternalRadius']=ExternalRadius
856 204 equemene
    InputCL['Angle']=Angle
857 204 equemene
    InputCL['BlackBody']=BlackBody
858 204 equemene
    InputCL['Method']=Method
859 204 equemene
    InputCL['TrackPoints']=TrackPoints
860 211 equemene
    InputCL['Physics']=Physics
861 204 equemene
862 204 equemene
    duration=BlackHoleCL(zImage,fImage,InputCL)
863 199 equemene
864 211 equemene
    Hostname=gethostname()
865 211 equemene
    Date=time.strftime("%Y%m%d_%H%M%S")
866 211 equemene
    ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
867 211 equemene
868 211 equemene
869 211 equemene
    if not NoImage:
870 211 equemene
        ImageOutput(zImage,"TrouNoirZ_%s" % ImageInfo,Colors)
871 211 equemene
        ImageOutput(fImage,"TrouNoirF_%s" % ImageInfo,Colors)