Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 244

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

1 242 equemene
#!/usr/bin/env python3
2 199 equemene
#
3 242 equemene
# TrouNoir model using PyOpenCL or PyCUDA
4 199 equemene
#
5 234 equemene
# CC BY-NC-SA 2019 : <emmanuel.quemener@ens-lyon.fr>
6 199 equemene
#
7 242 equemene
# Thanks to Andreas Klockner for PyOpenCL and PyCUDA:
8 199 equemene
# http://mathema.tician.de/software/pyopencl
9 234 equemene
#
10 204 equemene
# Original code programmed in Fortran 77 in mars 1994
11 204 equemene
# for Practical Work of Numerical Simulation
12 204 equemene
# DEA (old Master2) in astrophysics and spatial techniques in Meudon
13 204 equemene
# by Herve Aussel & Emmanuel Quemener
14 204 equemene
#
15 204 equemene
# Conversion in C done by Emmanuel Quemener in august 1997
16 204 equemene
# GPUfication in OpenCL under Python in july 2019
17 221 equemene
# GPUfication in CUDA under Python in august 2019
18 204 equemene
#
19 204 equemene
# Thanks to :
20 234 equemene
#
21 204 equemene
# - Herve Aussel for his part of code of black body spectrum
22 204 equemene
# - Didier Pelat for his help to perform this work
23 204 equemene
# - Jean-Pierre Luminet for his article published in 1979
24 204 equemene
# - Numerical Recipies for Runge Kutta recipies
25 204 equemene
# - Luc Blanchet for his disponibility about my questions in General Relativity
26 204 equemene
# - Pierre Lena for his passion about science and vulgarisation
27 199 equemene
28 229 equemene
# If crash on OpenCL Intel implementation, add following options and force
29 229 equemene
#export PYOPENCL_COMPILER_OUTPUT=1
30 229 equemene
#export CL_CONFIG_USE_VECTORIZER=True
31 229 equemene
#export CL_CONFIG_CPU_VECTORIZER_MODE=16
32 226 equemene
33 199 equemene
import pyopencl as cl
34 199 equemene
import numpy
35 199 equemene
import time,string
36 199 equemene
from numpy.random import randint as nprnd
37 199 equemene
import sys
38 199 equemene
import getopt
39 199 equemene
import matplotlib.pyplot as plt
40 211 equemene
from socket import gethostname
41 199 equemene
42 211 equemene
def DictionariesAPI():
43 211 equemene
    PhysicsList={'Einstein':0,'Newton':1}
44 211 equemene
    return(PhysicsList)
45 204 equemene
46 226 equemene
#
47 226 equemene
# Blank space below to simplify debugging on OpenCL code
48 226 equemene
#
49 226 equemene
50 226 equemene
51 226 equemene
52 226 equemene
53 226 equemene
54 226 equemene
55 226 equemene
56 226 equemene
57 226 equemene
58 226 equemene
59 226 equemene
60 226 equemene
61 226 equemene
62 226 equemene
63 226 equemene
64 226 equemene
65 226 equemene
66 226 equemene
67 226 equemene
68 226 equemene
69 226 equemene
70 226 equemene
71 226 equemene
72 226 equemene
73 226 equemene
74 226 equemene
75 226 equemene
76 226 equemene
77 226 equemene
78 226 equemene
79 226 equemene
80 226 equemene
81 226 equemene
82 226 equemene
83 226 equemene
84 226 equemene
85 226 equemene
86 226 equemene
87 226 equemene
88 226 equemene
89 226 equemene
90 226 equemene
91 226 equemene
92 226 equemene
93 226 equemene
94 226 equemene
95 226 equemene
96 226 equemene
97 226 equemene
98 226 equemene
99 226 equemene
100 226 equemene
101 226 equemene
102 226 equemene
103 211 equemene
BlobOpenCL= """
104 204 equemene

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

194 213 equemene
#define MYFLOAT float
195 209 equemene

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

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

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

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

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

220 234 equemene
  qu=1.e0f/sqrt((1.e0f-3.e0f/r)*r)*(sqrt(r)-sqrt(6.e0f)+sqrt(3.e0f)/2.e0f*log((sqrt(r)+sqrt(3.e0f))/(sqrt(r)-sqrt(3.e0f))* 0.17157287525380988e0f ));
221 199 equemene

222 234 equemene
  temp_em=temp*sqrt(m)*exp(0.25e0f*log(m_point)-0.75e0f*log(r)-0.125e0f*log(v)+0.25e0f*log(fabs(qu)));
223 209 equemene

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

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

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

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

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

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

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

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

272 199 equemene
}
273 199 equemene

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

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

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

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

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

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

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

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

315 228 equemene

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

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

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

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

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

332 204 equemene
  int ExitOnImpact=0;
333 199 equemene

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

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

346 228 equemene

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

356 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
357 204 equemene

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

441 204 equemene
  }
442 204 equemene

443 201 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
444 204 equemene

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

524 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
525 204 equemene

526 204 equemene
}
527 204 equemene

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

587 224 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
588 234 equemene

589 224 equemene
}
590 224 equemene

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

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

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

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

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

617 234 equemene

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

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

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

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

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

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

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

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

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

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

655 234 equemene

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

660 204 equemene

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

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

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

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

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

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

695 224 equemene
        HalfLap++;
696 224 equemene

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

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

702 224 equemene
  }
703 224 equemene

704 204 equemene
  barrier(CLK_GLOBAL_MEM_FENCE);
705 234 equemene

706 199 equemene
}
707 225 equemene

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

812 225 equemene
            HalfLap++;
813 234 equemene

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

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

819 225 equemene
      }
820 225 equemene

821 234 equemene
   }
822 234 equemene

823 225 equemene
   barrier(CLK_GLOBAL_MEM_FENCE);
824 234 equemene

825 225 equemene
}
826 211 equemene
"""
827 199 equemene
828 243 equemene
829 243 equemene
830 243 equemene
831 243 equemene
832 243 equemene
833 243 equemene
834 243 equemene
835 243 equemene
836 243 equemene
837 243 equemene
838 243 equemene
839 243 equemene
840 243 equemene
841 243 equemene
842 243 equemene
843 243 equemene
844 243 equemene
845 243 equemene
846 243 equemene
847 243 equemene
848 243 equemene
849 243 equemene
850 243 equemene
851 243 equemene
852 243 equemene
853 243 equemene
854 243 equemene
855 243 equemene
856 243 equemene
857 243 equemene
858 243 equemene
859 243 equemene
860 243 equemene
861 243 equemene
862 243 equemene
863 243 equemene
864 243 equemene
865 243 equemene
866 243 equemene
867 243 equemene
868 243 equemene
869 243 equemene
870 243 equemene
871 243 equemene
872 243 equemene
873 243 equemene
874 243 equemene
875 243 equemene
876 243 equemene
877 243 equemene
878 243 equemene
879 243 equemene
880 243 equemene
881 243 equemene
882 243 equemene
883 243 equemene
884 243 equemene
885 243 equemene
886 243 equemene
887 243 equemene
888 243 equemene
889 243 equemene
890 243 equemene
891 243 equemene
892 243 equemene
893 243 equemene
894 243 equemene
895 243 equemene
896 243 equemene
897 243 equemene
898 243 equemene
899 217 equemene
def KernelCodeCuda():
900 217 equemene
    BlobCUDA= """
901 217 equemene

902 217 equemene
#define PI (float)3.14159265359
903 217 equemene
#define nbr 256
904 217 equemene

905 217 equemene
#define EINSTEIN 0
906 217 equemene
#define NEWTON 1
907 217 equemene

908 224 equemene
#ifdef SETTRACKPOINTS
909 224 equemene
#define TRACKPOINTS SETTRACKPOINTS
910 224 equemene
#else
911 224 equemene
#define TRACKPOINTS
912 224 equemene
#endif
913 217 equemene
__device__ float nothing(float x)
914 217 equemene
{
915 217 equemene
  return(x);
916 217 equemene
}
917 217 equemene

918 217 equemene
__device__ float atanp(float x,float y)
919 217 equemene
{
920 217 equemene
  float angle;
921 217 equemene

922 217 equemene
  angle=atan2(y,x);
923 217 equemene

924 217 equemene
  if (angle<0.e0f)
925 217 equemene
    {
926 217 equemene
      angle+=(float)2.e0f*PI;
927 217 equemene
    }
928 217 equemene

929 217 equemene
  return(angle);
930 217 equemene
}
931 217 equemene

932 217 equemene
__device__ float f(float v)
933 217 equemene
{
934 217 equemene
  return(v);
935 217 equemene
}
936 217 equemene

937 217 equemene
#if PHYSICS == NEWTON
938 217 equemene
__device__ float g(float u,float m,float b)
939 217 equemene
{
940 217 equemene
  return (-u);
941 217 equemene
}
942 217 equemene
#else
943 217 equemene
__device__ float g(float u,float m,float b)
944 217 equemene
{
945 217 equemene
  return (3.e0f*m/b*pow(u,2)-u);
946 217 equemene
}
947 217 equemene
#endif
948 217 equemene

949 217 equemene
__device__ void calcul(float *us,float *vs,float up,float vp,
950 234 equemene
                       float h,float m,float b)
951 217 equemene
{
952 217 equemene
  float c0,c1,c2,c3,d0,d1,d2,d3;
953 217 equemene

954 217 equemene
  c0=h*f(vp);
955 217 equemene
  c1=h*f(vp+c0/2.);
956 217 equemene
  c2=h*f(vp+c1/2.);
957 217 equemene
  c3=h*f(vp+c2);
958 217 equemene
  d0=h*g(up,m,b);
959 217 equemene
  d1=h*g(up+d0/2.,m,b);
960 217 equemene
  d2=h*g(up+d1/2.,m,b);
961 217 equemene
  d3=h*g(up+d2,m,b);
962 217 equemene

963 217 equemene
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
964 217 equemene
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
965 217 equemene
}
966 217 equemene

967 217 equemene
__device__ void rungekutta(float *ps,float *us,float *vs,
968 234 equemene
                           float pp,float up,float vp,
969 234 equemene
                           float h,float m,float b)
970 217 equemene
{
971 217 equemene
  calcul(us,vs,up,vp,h,m,b);
972 217 equemene
  *ps=pp+h;
973 217 equemene
}
974 217 equemene

975 217 equemene
__device__ float decalage_spectral(float r,float b,float phi,
976 234 equemene
                                   float tho,float m)
977 217 equemene
{
978 217 equemene
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
979 217 equemene
}
980 217 equemene

981 217 equemene
__device__ float spectre(float rf,int q,float b,float db,
982 234 equemene
                         float h,float r,float m,float bss)
983 217 equemene
{
984 217 equemene
  float flx;
985 217 equemene

986 221 equemene
//  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
987 221 equemene
  flx=exp(q*log(r/m)+4.*log(rf))*b*db*h;
988 217 equemene
  return(flx);
989 217 equemene
}
990 217 equemene

991 217 equemene
__device__ float spectre_cn(float rf32,float b32,float db32,
992 234 equemene
                            float h32,float r32,float m32,float bss32)
993 217 equemene
{
994 234 equemene

995 217 equemene
#define MYFLOAT float
996 217 equemene

997 217 equemene
  MYFLOAT rf=(MYFLOAT)(rf32);
998 217 equemene
  MYFLOAT b=(MYFLOAT)(b32);
999 217 equemene
  MYFLOAT db=(MYFLOAT)(db32);
1000 217 equemene
  MYFLOAT h=(MYFLOAT)(h32);
1001 217 equemene
  MYFLOAT r=(MYFLOAT)(r32);
1002 217 equemene
  MYFLOAT m=(MYFLOAT)(m32);
1003 217 equemene
  MYFLOAT bss=(MYFLOAT)(bss32);
1004 217 equemene

1005 217 equemene
  MYFLOAT flx;
1006 217 equemene
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
1007 217 equemene
  int fi,posfreq;
1008 217 equemene

1009 217 equemene
#define planck 6.62e-34
1010 217 equemene
#define k 1.38e-23
1011 217 equemene
#define c2 9.e16
1012 217 equemene
#define temp 3.e7
1013 217 equemene
#define m_point 1.
1014 217 equemene

1015 217 equemene
#define lplanck (log(6.62)-34.*log(10.))
1016 217 equemene
#define lk (log(1.38)-23.*log(10.))
1017 217 equemene
#define lc2 (log(9.)+16.*log(10.))
1018 217 equemene

1019 217 equemene
  MYFLOAT v=1.-3./r;
1020 217 equemene

1021 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 ));
1022 217 equemene

1023 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)));
1024 217 equemene

1025 217 equemene
  flux_int=0.;
1026 217 equemene
  flx=0.;
1027 217 equemene

1028 217 equemene
  for (fi=0;fi<nbr;fi++)
1029 217 equemene
    {
1030 217 equemene
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
1031 217 equemene
      nu_rec=nu_em*rf;
1032 217 equemene
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
1033 217 equemene
      if ((posfreq>0)&&(posfreq<nbr))
1034 234 equemene
        {
1035 217 equemene
          // Initial version
1036 234 equemene
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
1037 217 equemene
          // Version with log used
1038 234 equemene
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
1039 234 equemene
          // flux_int*=pow(rf,3)*b*db*h;
1040 234 equemene
          //flux_int*=exp(3.*log(rf))*b*db*h;
1041 234 equemene
          flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.)*exp(3.*log(rf))*b*db*h;
1042 217 equemene

1043 234 equemene
          flx+=flux_int;
1044 234 equemene
        }
1045 217 equemene
    }
1046 217 equemene

1047 217 equemene
  return((float)(flx));
1048 217 equemene
}
1049 217 equemene

1050 217 equemene
__device__ void impact(float phi,float r,float b,float tho,float m,
1051 234 equemene
                       float *zp,float *fp,
1052 234 equemene
                       int q,float db,
1053 234 equemene
                       float h,int raie)
1054 217 equemene
{
1055 217 equemene
  float flx,rf,bss;
1056 217 equemene

1057 217 equemene
  rf=decalage_spectral(r,b,phi,tho,m);
1058 217 equemene

1059 217 equemene
  if (raie==0)
1060 217 equemene
    {
1061 217 equemene
      bss=1.e19;
1062 217 equemene
      flx=spectre_cn(rf,b,db,h,r,m,bss);
1063 217 equemene
    }
1064 217 equemene
  else
1065 234 equemene
    {
1066 217 equemene
      bss=2.;
1067 217 equemene
      flx=spectre(rf,q,b,db,h,r,m,bss);
1068 217 equemene
    }
1069 234 equemene

1070 217 equemene
  *zp=1./rf;
1071 217 equemene
  *fp=flx;
1072 217 equemene

1073 217 equemene
}
1074 217 equemene

1075 217 equemene
__global__ void EachPixel(float *zImage,float *fImage,
1076 217 equemene
                          float Mass,float InternalRadius,
1077 217 equemene
                          float ExternalRadius,float Angle,
1078 217 equemene
                          int Line)
1079 217 equemene
{
1080 218 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1081 218 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1082 217 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1083 217 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1084 217 equemene

1085 243 equemene

1086 217 equemene
   // Perform trajectory for each pixel, exit on hit
1087 217 equemene

1088 217 equemene
  float m,rs,ri,re,tho;
1089 217 equemene
  int q,raie;
1090 217 equemene

1091 217 equemene
  m=Mass;
1092 217 equemene
  rs=2.*m;
1093 217 equemene
  ri=InternalRadius;
1094 217 equemene
  re=ExternalRadius;
1095 217 equemene
  tho=Angle;
1096 217 equemene
  q=-2;
1097 217 equemene
  raie=Line;
1098 217 equemene

1099 243 equemene
  float bmx,db,b,h;
1100 218 equemene
  float rp0,rpp,rps;
1101 243 equemene
  float phi,phd;
1102 217 equemene
  int nh;
1103 217 equemene
  float zp,fp;
1104 217 equemene

1105 217 equemene
  // Autosize for image
1106 217 equemene
  bmx=1.25*re;
1107 217 equemene
  b=0.;
1108 217 equemene

1109 217 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1110 217 equemene

1111 217 equemene
  // set origin as center of image
1112 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1113 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1114 217 equemene
  // angle extracted from cylindric symmetry
1115 217 equemene
  phi=atanp(x,y);
1116 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1117 217 equemene

1118 217 equemene
  float up,vp,pp,us,vs,ps;
1119 217 equemene

1120 217 equemene
  // impact parameter
1121 217 equemene
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
1122 217 equemene
  // step of impact parameter;
1123 217 equemene
//  db=bmx/(float)(sizex/2);
1124 217 equemene
  db=bmx/(float)(sizex);
1125 217 equemene

1126 217 equemene
  up=0.;
1127 217 equemene
  vp=1.;
1128 217 equemene
  pp=0.;
1129 217 equemene
  nh=0;
1130 217 equemene

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

1133 218 equemene
  rps=fabs(b/us);
1134 218 equemene
  rp0=rps;
1135 217 equemene

1136 217 equemene
  int ExitOnImpact=0;
1137 217 equemene

1138 217 equemene
  do
1139 217 equemene
  {
1140 217 equemene
     nh++;
1141 217 equemene
     pp=ps;
1142 217 equemene
     up=us;
1143 217 equemene
     vp=vs;
1144 218 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1145 234 equemene
     rpp=rps;
1146 218 equemene
     rps=fabs(b/us);
1147 218 equemene
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rps>ri)&&(rps<re)?1:0;
1148 217 equemene

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

1151 217 equemene
  if (ExitOnImpact==1) {
1152 218 equemene
     impact(phi,rpp,b,tho,m,&zp,&fp,q,db,h,raie);
1153 217 equemene
  }
1154 217 equemene
  else
1155 217 equemene
  {
1156 234 equemene
     zp=0.e0f;
1157 234 equemene
     fp=0.e0f;
1158 217 equemene
  }
1159 217 equemene

1160 218 equemene
  __syncthreads();
1161 218 equemene

1162 217 equemene
  zImage[yi+sizex*xi]=(float)zp;
1163 217 equemene
  fImage[yi+sizex*xi]=(float)fp;
1164 217 equemene
}
1165 217 equemene

1166 217 equemene
__global__ void Pixel(float *zImage,float *fImage,
1167 217 equemene
                      float *Trajectories,int *IdLast,
1168 224 equemene
                      uint ImpactParameter,
1169 217 equemene
                      float Mass,float InternalRadius,
1170 217 equemene
                      float ExternalRadius,float Angle,
1171 217 equemene
                      int Line)
1172 217 equemene
{
1173 219 equemene
   uint xi=(uint)(blockIdx.x*blockDim.x+threadIdx.x);
1174 219 equemene
   uint yi=(uint)(blockIdx.y*blockDim.y+threadIdx.y);
1175 219 equemene
   uint sizex=(uint)gridDim.x*blockDim.x;
1176 219 equemene
   uint sizey=(uint)gridDim.y*blockDim.y;
1177 217 equemene

1178 217 equemene
  // Perform trajectory for each pixel
1179 217 equemene

1180 243 equemene
  float m,ri,re,tho;
1181 217 equemene
  int q,raie;
1182 217 equemene

1183 217 equemene
  m=Mass;
1184 217 equemene
  ri=InternalRadius;
1185 217 equemene
  re=ExternalRadius;
1186 217 equemene
  tho=Angle;
1187 217 equemene
  q=-2;
1188 217 equemene
  raie=Line;
1189 217 equemene

1190 243 equemene
  float bmx,db,b,h;
1191 243 equemene
  float phi,phd,php,nr,r;
1192 217 equemene
  float zp=0,fp=0;
1193 217 equemene
  // Autosize for image, 25% greater than external radius
1194 234 equemene
  bmx=1.25e0f*re;
1195 217 equemene

1196 217 equemene
  // Angular step of integration
1197 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1198 217 equemene

1199 217 equemene
  // Step of Impact Parameter
1200 234 equemene
  db=bmx/(2.e0f*(float)ImpactParameter);
1201 217 equemene

1202 217 equemene
  // set origin as center of image
1203 217 equemene
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
1204 217 equemene
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
1205 217 equemene
  // angle extracted from cylindric symmetry
1206 217 equemene
  phi=atanp(x,y);
1207 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1208 217 equemene

1209 217 equemene
  // Real Impact Parameter
1210 217 equemene
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
1211 217 equemene

1212 217 equemene
  // Integer Impact Parameter
1213 217 equemene
  uint bi=(uint)sqrt(x*x+y*y);
1214 217 equemene

1215 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1216 217 equemene

1217 217 equemene
  if (bi<ImpactParameter)
1218 217 equemene
  {
1219 217 equemene
    do
1220 217 equemene
    {
1221 217 equemene
      php=phd+(float)HalfLap*PI;
1222 217 equemene
      nr=php/h;
1223 217 equemene
      ni=(int)nr;
1224 217 equemene

1225 217 equemene
      if (ni<IdLast[bi])
1226 217 equemene
      {
1227 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1228 217 equemene
      }
1229 217 equemene
      else
1230 217 equemene
      {
1231 224 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1232 217 equemene
      }
1233 234 equemene

1234 217 equemene
      if ((r<=re)&&(r>=ri))
1235 217 equemene
      {
1236 217 equemene
        ExitOnImpact=1;
1237 217 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1238 217 equemene
      }
1239 234 equemene

1240 217 equemene
      HalfLap++;
1241 217 equemene
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
1242 217 equemene

1243 217 equemene
  }
1244 217 equemene

1245 217 equemene
  zImage[yi+sizex*xi]=zp;
1246 217 equemene
  fImage[yi+sizex*xi]=fp;
1247 217 equemene
}
1248 217 equemene

1249 217 equemene
__global__ void Circle(float *Trajectories,int *IdLast,
1250 217 equemene
                       float *zImage,float *fImage,
1251 217 equemene
                       float Mass,float InternalRadius,
1252 217 equemene
                       float ExternalRadius,float Angle,
1253 217 equemene
                       int Line)
1254 217 equemene
{
1255 234 equemene
   // Integer Impact Parameter ID
1256 219 equemene
   int bi=blockIdx.x*blockDim.x+threadIdx.x;
1257 217 equemene
   // Integer points on circle
1258 219 equemene
   int i=blockIdx.y*blockDim.y+threadIdx.y;
1259 217 equemene
   // Integer Impact Parameter Size (half of image)
1260 217 equemene
   int bmaxi=gridDim.x*blockDim.x;
1261 217 equemene
   // Integer Points on circle
1262 217 equemene
   int imx=gridDim.y*blockDim.y;
1263 217 equemene

1264 217 equemene
   // Perform trajectory for each pixel
1265 217 equemene

1266 243 equemene
  float m,ri,re,tho;
1267 217 equemene
  int q,raie;
1268 217 equemene

1269 217 equemene
  m=Mass;
1270 217 equemene
  ri=InternalRadius;
1271 217 equemene
  re=ExternalRadius;
1272 217 equemene
  tho=Angle;
1273 217 equemene
  raie=Line;
1274 217 equemene

1275 217 equemene
  float bmx,db,b,h;
1276 243 equemene
  float phi,phd;
1277 217 equemene
  float zp=0,fp=0;
1278 217 equemene

1279 217 equemene
  // Autosize for image
1280 234 equemene
  bmx=1.25e0f*re;
1281 217 equemene

1282 217 equemene
  // Angular step of integration
1283 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1284 217 equemene

1285 217 equemene
  // impact parameter
1286 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1287 234 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1288 217 equemene

1289 234 equemene
  phi=2.e0f*PI/(float)imx*(float)i;
1290 217 equemene
  phd=atanp(cos(phi)*sin(tho),cos(tho));
1291 217 equemene
  int yi=(int)((float)bi*sin(phi))+bmaxi;
1292 217 equemene
  int xi=(int)((float)bi*cos(phi))+bmaxi;
1293 217 equemene

1294 217 equemene
  int HalfLap=0,ExitOnImpact=0,ni;
1295 217 equemene
  float php,nr,r;
1296 217 equemene

1297 217 equemene
  do
1298 217 equemene
  {
1299 217 equemene
     php=phd+(float)HalfLap*PI;
1300 217 equemene
     nr=php/h;
1301 217 equemene
     ni=(int)nr;
1302 217 equemene

1303 217 equemene
     if (ni<IdLast[bi])
1304 217 equemene
     {
1305 234 equemene
        r=(Trajectories[bi*TRACKPOINTS+ni+1]-Trajectories[bi*TRACKPOINTS+ni])*(nr-ni*1.e0f)+Trajectories[bi*TRACKPOINTS+ni];
1306 217 equemene
     }
1307 217 equemene
     else
1308 217 equemene
     {
1309 234 equemene
        r=Trajectories[bi*TRACKPOINTS+ni];
1310 217 equemene
     }
1311 234 equemene

1312 217 equemene
     if ((r<=re)&&(r>=ri))
1313 217 equemene
     {
1314 234 equemene
        ExitOnImpact=1;
1315 234 equemene
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1316 217 equemene
     }
1317 234 equemene

1318 217 equemene
     HalfLap++;
1319 217 equemene
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
1320 234 equemene

1321 217 equemene
  zImage[yi+2*bmaxi*xi]=zp;
1322 234 equemene
  fImage[yi+2*bmaxi*xi]=fp;
1323 217 equemene

1324 217 equemene
}
1325 217 equemene

1326 224 equemene
__global__ void Trajectory(float *Trajectories,int *IdLast,
1327 217 equemene
                           float Mass,float InternalRadius,
1328 217 equemene
                           float ExternalRadius,float Angle,
1329 217 equemene
                           int Line)
1330 217 equemene
{
1331 234 equemene
  // Integer Impact Parameter ID
1332 219 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1333 217 equemene
  // Integer Impact Parameter Size (half of image)
1334 217 equemene
  int bmaxi=gridDim.x*blockDim.x;
1335 217 equemene

1336 217 equemene
  // Perform trajectory for each pixel
1337 217 equemene

1338 243 equemene
  float m,rs,re;
1339 217 equemene

1340 217 equemene
  m=Mass;
1341 234 equemene
  rs=2.e0f*m;
1342 217 equemene
  re=ExternalRadius;
1343 217 equemene

1344 243 equemene
  float bmx,b,h;
1345 217 equemene
  int nh;
1346 217 equemene

1347 217 equemene
  // Autosize for image
1348 234 equemene
  bmx=1.25e0f*re;
1349 217 equemene

1350 217 equemene
  // Angular step of integration
1351 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1352 217 equemene

1353 217 equemene
  // impact parameter
1354 217 equemene
  b=(float)bi/(float)bmaxi*bmx;
1355 217 equemene

1356 217 equemene
  float up,vp,pp,us,vs,ps;
1357 217 equemene

1358 234 equemene
  up=0.e0f;
1359 234 equemene
  vp=1.e0f;
1360 234 equemene
  pp=0.e0f;
1361 217 equemene
  nh=0;
1362 217 equemene

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

1365 217 equemene
  // b versus us
1366 217 equemene
  float bvus=fabs(b/us);
1367 217 equemene
  float bvus0=bvus;
1368 224 equemene
  Trajectories[bi*TRACKPOINTS+nh]=bvus;
1369 217 equemene

1370 217 equemene
  do
1371 217 equemene
  {
1372 217 equemene
     nh++;
1373 217 equemene
     pp=ps;
1374 217 equemene
     up=us;
1375 217 equemene
     vp=vs;
1376 217 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1377 217 equemene
     bvus=fabs(b/us);
1378 224 equemene
     Trajectories[bi*TRACKPOINTS+nh]=bvus;
1379 217 equemene

1380 217 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1381 217 equemene

1382 217 equemene
  IdLast[bi]=nh;
1383 217 equemene

1384 217 equemene
}
1385 224 equemene

1386 225 equemene
__global__ void EachCircle(float *zImage,float *fImage,
1387 225 equemene
                           float Mass,float InternalRadius,
1388 225 equemene
                           float ExternalRadius,float Angle,
1389 225 equemene
                           int Line)
1390 224 equemene
{
1391 234 equemene
  // Integer Impact Parameter ID
1392 224 equemene
  int bi=blockIdx.x*blockDim.x+threadIdx.x;
1393 224 equemene

1394 224 equemene
  // Integer Impact Parameter Size (half of image)
1395 224 equemene
  int bmaxi=gridDim.x*blockDim.x;
1396 224 equemene

1397 225 equemene
  float Trajectory[2048];
1398 224 equemene

1399 224 equemene
  // Perform trajectory for each pixel
1400 224 equemene

1401 224 equemene
  float m,rs,ri,re,tho;
1402 224 equemene
  int raie,q;
1403 224 equemene

1404 224 equemene
  m=Mass;
1405 224 equemene
  rs=2.*m;
1406 224 equemene
  ri=InternalRadius;
1407 224 equemene
  re=ExternalRadius;
1408 224 equemene
  tho=Angle;
1409 224 equemene
  q=-2;
1410 224 equemene
  raie=Line;
1411 224 equemene

1412 224 equemene
  float bmx,db,b,h;
1413 224 equemene
  int nh;
1414 224 equemene

1415 224 equemene
  // Autosize for image
1416 224 equemene
  bmx=1.25e0f*re;
1417 224 equemene

1418 224 equemene
  // Angular step of integration
1419 224 equemene
  h=4.e0f*PI/(float)TRACKPOINTS;
1420 224 equemene

1421 224 equemene
  // impact parameter
1422 224 equemene
  b=(float)bi/(float)bmaxi*bmx;
1423 224 equemene
  db=bmx/(2.e0f*(float)bmaxi);
1424 224 equemene

1425 224 equemene
  float up,vp,pp,us,vs,ps;
1426 224 equemene

1427 224 equemene
  up=0.;
1428 224 equemene
  vp=1.;
1429 224 equemene
  pp=0.;
1430 224 equemene
  nh=0;
1431 224 equemene

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

1434 224 equemene
  // b versus us
1435 224 equemene
  float bvus=fabs(b/us);
1436 224 equemene
  float bvus0=bvus;
1437 225 equemene
  Trajectory[nh]=bvus;
1438 224 equemene

1439 224 equemene
  do
1440 224 equemene
  {
1441 224 equemene
     nh++;
1442 224 equemene
     pp=ps;
1443 224 equemene
     up=us;
1444 224 equemene
     vp=vs;
1445 224 equemene
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1446 224 equemene
     bvus=fabs(b/us);
1447 225 equemene
     Trajectory[nh]=bvus;
1448 224 equemene

1449 224 equemene
  } while ((bvus>=rs)&&(bvus<=bvus0));
1450 224 equemene

1451 224 equemene
  int imx=(int)(16*bi);
1452 224 equemene

1453 224 equemene
  for (int i=0;i<imx;i++)
1454 224 equemene
  {
1455 224 equemene
     float zp=0,fp=0;
1456 224 equemene
     float phi=2.*PI/(float)imx*(float)i;
1457 224 equemene
     float phd=atanp(cos(phi)*sin(tho),cos(tho));
1458 224 equemene
     uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1459 224 equemene
     uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1460 224 equemene

1461 224 equemene
     int HalfLap=0,ExitOnImpact=0,ni;
1462 224 equemene
     float php,nr,r;
1463 224 equemene

1464 224 equemene
     do
1465 224 equemene
     {
1466 224 equemene
        php=phd+(float)HalfLap*PI;
1467 224 equemene
        nr=php/h;
1468 224 equemene
        ni=(int)nr;
1469 224 equemene

1470 224 equemene
        if (ni<nh)
1471 224 equemene
        {
1472 225 equemene
           r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1473 224 equemene
        }
1474 224 equemene
        else
1475 224 equemene
        {
1476 225 equemene
           r=Trajectory[ni];
1477 224 equemene
        }
1478 234 equemene

1479 224 equemene
        if ((r<=re)&&(r>=ri))
1480 224 equemene
        {
1481 224 equemene
           ExitOnImpact=1;
1482 224 equemene
           impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1483 224 equemene
        }
1484 234 equemene

1485 224 equemene
        HalfLap++;
1486 224 equemene

1487 224 equemene
     } while ((HalfLap<=2)&&(ExitOnImpact==0));
1488 224 equemene

1489 224 equemene
   __syncthreads();
1490 224 equemene

1491 224 equemene
   zImage[yi+2*bmaxi*xi]=zp;
1492 224 equemene
   fImage[yi+2*bmaxi*xi]=fp;
1493 224 equemene

1494 224 equemene
  }
1495 234 equemene

1496 224 equemene
}
1497 225 equemene

1498 225 equemene
__global__ void Original(float *zImage,float *fImage,
1499 225 equemene
                         uint Size,float Mass,float InternalRadius,
1500 225 equemene
                         float ExternalRadius,float Angle,
1501 225 equemene
                         int Line)
1502 225 equemene
{
1503 225 equemene
   // Integer Impact Parameter Size (half of image)
1504 225 equemene
   uint bmaxi=(uint)Size;
1505 225 equemene

1506 225 equemene
   float Trajectory[TRACKPOINTS];
1507 225 equemene

1508 225 equemene
   // Perform trajectory for each pixel
1509 225 equemene

1510 225 equemene
   float m,rs,ri,re,tho;
1511 225 equemene
   int raie,q;
1512 225 equemene

1513 225 equemene
   m=Mass;
1514 234 equemene
   rs=2.e0f*m;
1515 225 equemene
   ri=InternalRadius;
1516 225 equemene
   re=ExternalRadius;
1517 225 equemene
   tho=Angle;
1518 225 equemene
   q=-2;
1519 225 equemene
   raie=Line;
1520 225 equemene

1521 225 equemene
   float bmx,db,b,h;
1522 225 equemene
   int nh;
1523 225 equemene

1524 225 equemene
   // Autosize for image
1525 225 equemene
   bmx=1.25e0f*re;
1526 225 equemene

1527 225 equemene
   // Angular step of integration
1528 225 equemene
   h=4.e0f*PI/(float)TRACKPOINTS;
1529 225 equemene

1530 234 equemene
   // Integer Impact Parameter ID
1531 225 equemene
   for (int bi=0;bi<bmaxi;bi++)
1532 225 equemene
   {
1533 225 equemene
      // impact parameter
1534 225 equemene
      b=(float)bi/(float)bmaxi*bmx;
1535 225 equemene
      db=bmx/(2.e0f*(float)bmaxi);
1536 225 equemene

1537 225 equemene
      float up,vp,pp,us,vs,ps;
1538 225 equemene

1539 225 equemene
      up=0.;
1540 225 equemene
      vp=1.;
1541 225 equemene
      pp=0.;
1542 225 equemene
      nh=0;
1543 225 equemene

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

1546 225 equemene
      // b versus us
1547 225 equemene
      float bvus=fabs(b/us);
1548 225 equemene
      float bvus0=bvus;
1549 225 equemene
      Trajectory[nh]=bvus;
1550 225 equemene

1551 225 equemene
      do
1552 225 equemene
      {
1553 225 equemene
         nh++;
1554 225 equemene
         pp=ps;
1555 225 equemene
         up=us;
1556 225 equemene
         vp=vs;
1557 225 equemene
         rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
1558 225 equemene
         bvus=fabs(b/us);
1559 225 equemene
         Trajectory[nh]=bvus;
1560 225 equemene

1561 225 equemene
      } while ((bvus>=rs)&&(bvus<=bvus0));
1562 225 equemene

1563 225 equemene
      for (uint i=(uint)nh+1;i<TRACKPOINTS;i++) {
1564 225 equemene
         Trajectory[i]=0.e0f;
1565 225 equemene
      }
1566 225 equemene

1567 225 equemene
      int imx=(int)(16*bi);
1568 225 equemene

1569 225 equemene
      for (int i=0;i<imx;i++)
1570 225 equemene
      {
1571 225 equemene
         float zp=0,fp=0;
1572 225 equemene
         float phi=2.e0f*PI/(float)imx*(float)i;
1573 225 equemene
         float phd=atanp(cos(phi)*sin(tho),cos(tho));
1574 225 equemene
         uint yi=(uint)((float)bi*sin(phi)+bmaxi);
1575 225 equemene
         uint xi=(uint)((float)bi*cos(phi)+bmaxi);
1576 225 equemene

1577 225 equemene
         int HalfLap=0,ExitOnImpact=0,ni;
1578 225 equemene
         float php,nr,r;
1579 225 equemene

1580 225 equemene
         do
1581 225 equemene
         {
1582 225 equemene
            php=phd+(float)HalfLap*PI;
1583 225 equemene
            nr=php/h;
1584 225 equemene
            ni=(int)nr;
1585 225 equemene

1586 225 equemene
            if (ni<nh)
1587 225 equemene
            {
1588 225 equemene
               r=(Trajectory[ni+1]-Trajectory[ni])*(nr-ni*1.)+Trajectory[ni];
1589 225 equemene
            }
1590 225 equemene
            else
1591 225 equemene
            {
1592 225 equemene
               r=Trajectory[ni];
1593 225 equemene
            }
1594 234 equemene

1595 225 equemene
            if ((r<=re)&&(r>=ri))
1596 225 equemene
            {
1597 225 equemene
               ExitOnImpact=1;
1598 225 equemene
               impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
1599 225 equemene
            }
1600 234 equemene

1601 225 equemene
            HalfLap++;
1602 234 equemene

1603 225 equemene
         } while ((HalfLap<=2)&&(ExitOnImpact==0));
1604 234 equemene

1605 225 equemene
         zImage[yi+2*bmaxi*xi]=zp;
1606 225 equemene
         fImage[yi+2*bmaxi*xi]=fp;
1607 234 equemene

1608 225 equemene
      }
1609 225 equemene

1610 234 equemene
   }
1611 234 equemene

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