Révision 197

TrouNoir/trou_noir.f (revision 197)
1
      PROGRAM MODELISATION_NUMERIQUE
2

  
3
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
4
c                                                                            c
5
c MODELISATION NUMERIQUE D'UN DISQUE D'ACCRETION AUTOUR D'UN TROU NOIR :     c
6
c                                                                            c
7
c APPARENCE & SPECTRE                                                        c
8
c                                                                            c
9
c Programme realise par : Herve AUSSEL                                       c
10
c                         Emmanuel QUEMENER                                  c
11
c                                                                            c
12
c Dans le cadre de l'unite de modelisation numerique du DEA                  c
13
c d'Astrophysique & Techniques Spatiales (Paris 7 & 11)                      c
14
c                                                                            c
15
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
16

  
17
      IMPLICIT NONE
18
      REAL*8 pi
19
      PARAMETER (pi=3.141592654)
20

  
21
c
22
c PARAMETRES PHYSIQUES DU SYSTEME DISQUE, TROU-NOIR, OBSERVATEUR
23
c
24

  
25
      REAL*8 m                  ! masse reduite du trou noir
26
      REAL*8 rs,ri,re           ! rayons de Schwarzschild,interieur et exterieur
27
      REAL*8 tho                ! angle normale-disque & direction-observateur
28
      REAL*8 ro                 ! distance entre l'observateur et le trou noir
29
      INTEGER*4 q               ! parametre de spectre
30
      REAL*4 bss                ! borne superieure du spectre
31

  
32
c
33
c PARAMETRES DE LA PLAQUE PHOTOGRAPHIQUE
34
c
35

  
36
      INTEGER*4 dim             ! dimension de la plaque photographique (en pixels)
37
      PARAMETER (dim=512)
38
      REAL*4 stp                ! pas d'iteration en pixels sur la plaque
39
      INTEGER*4 nmx             ! nombre total d'iterations
40
      REAL*8 d                  ! distance exploree du centre de la plaque
41
      REAL*8 bmx                ! parametre d'impact maximal
42

  
43
c
44
c PARAMETRES INITIAUX D' INTEGRATION
45
c
46

  
47
      REAL*8 db                 ! avancement du parametre d'impact
48
      REAL*8 b                  ! parametre d'impact du photon
49
      REAL*8 h                  ! avancement angulaire initial
50

  
51
c
52
c PARAMETRES D'INTEGRATION DU SYSTEME DIFFERENTIEL
53
c
54

  
55
      REAL*8 up,vp,pp           ! parametres du SED , precedents
56
      REAL*8 us,vs,ps           ! parametres du SED , suivants
57

  
58
c
59
c RESULTATS DE L'INTEGRATION DE L'EQUATION DIFFERENTIELLE
60
c
61

  
62
      REAL*8 rp(2000)           ! vecteur polaire
63
      REAL*8 nh                 ! nombre d'avancements angulaires
64

  
65
c
66
c RESULTATS DE LA SIMULATION
67
c
68

  
69
      REAL*4 zp(dim,dim) 	! image en decalage spectral
70
      REAL*4 fp(dim,dim) 	! image en flux
71
      REAL*8 fx(200)            ! flux par tranche de decalage de frequence
72
      INTEGER*4 nt(200) 	! nombre de photon par tranche de decalage
73

  
74
c
75
c AUTRES VARIABLES...
76
c
77

  
78
      INTEGER*4 pc              ! pourcentage du balayage realise
79
      REAL*8 phi                ! angle de la plaque photographique
80
      REAL*8 thi                ! angle trou noir-observateur & direction emission
81
      REAL*8 thx                ! angle thi maximal
82
      REAL*8 phd                ! angle donnant l'intersection des plans
83
      REAL*8 php                ! angle d'intersection intermediaire
84
      REAL*8 nr                 ! indice d'intersection reel du vecteur
85
      INTEGER*4 ni              ! indice d'intersection entier du vecteur
86
      INTEGER*4 ii              ! indice de 1' image (primaire, secondaire, ...)
87
      REAL*8 r                  ! rayon moyen d'impact sur le disque
88
      INTEGER*4 nbr             ! nombre de bandes de rapport de frequence
89
      INTEGER*4 i,imx,j,n
90
      LOGICAL tst
91
      REAL*8 atanp              ! fonction arctangente : resultat entre 0 et 2*pi
92
      LOGICAL raie            ! variable interactive de type de spectre
93
      LOGICAL dist            ! variable interactive de distance
94

  
95
c
96
c TYPE DE SPECTRE
97
c
98

  
99
      raie=.TRUE.               ! TRUE -> raie infiniment fine
100
c                               ! FALSE -> corps noir
101

  
102
c
103
c TYPE DE DISTANCE
104
c
105

  
106
      dist=.TRUE.               ! TRUE -> distance infinie
107
c                               ! FALSE -> distance finie
108

  
109
c
110
c INITIALISATION DES TABLEAUX
111
c
112

  
113
      DO i=1,200
114
         fx(i)=0.
115
         nt(i)=0
116
      END DO
117
      
118
      DO i=1,dim
119
         DO j=1,dim
120
            zp(i,j)=0.
121
            fp(i,j)=0.
122
         END DO
123
      END DO
124

  
125
c
126
c DEFINITION DES PARAMETRES PHYSIQUES
127
c
128

  
129
      m=1.
130
      rs=2.*m
131
      ri=3.*rs
132
      re=12.
133
      ro=100.
134
      tho=pi/180.*80.
135
      IF (raie .EQV. .TRUE.) THEN
136
         q=-2
137
      ELSE
138
         q=-3/4
139
      ENDIF
140

  
141
c
142
c DEFINITION DES PARAMETRES NUMERIQUES
143
c
144

  
145
      nmx=dim
146
      stp=dim/(2.*nmx)
147
      bmx=1.25*re
148
      b=0.
149
      thx=asin(bmx/ro)
150
      pc=0
151
      nbr=200
152
      IF (raie .EQV. .TRUE.) THEN
153
         bss=2.
154
      ELSE
155
         bss=1.e19
156
      ENDIF
157

  
158
c
159
c BOUCLE PRINCIPALE DE LA SIMULATION
160
c
161

  
162
      DO n=1,nmx
163
         pc=INT(100./nmx*n)
164
         IF (pc.NE.INT(100./nmx*(n-1))) WRITE (*,*) pc, ' %'
165

  
166
c
167
c Affectation des conditions initiales de la resolution Runge-Kutta
168
c ( Premier etage d'imbrication -> n )
169
c
170
         h=pi/500.
171
         d=stp*n
172
         IF (dist .EQV. .TRUE.) THEN
173
            db=bmx/nmx
174
            b=db*n
175
            up=0.
176
            vp=1.
177
         ELSE
178
            thi=thx/nmx*n
179
            db=ro*DSIN(thi)-b
180
            b=ro*DSIN(thi)
181
            up=DSIN(thi)
182
            vp=DCOS(thi)
183
         ENDIF
184
         pp=0.
185
         nh=1
186
         CALL rungekutta(ps,us,vs,pp,up,vp,h,m,b)
187
         rp(nh)=ABS(b/us)
188

  
189
c
190
c Resolution de l'equation differentielle pour un parametre b donne
191
c Les resultats sont stockes dans le vecteur polaire rp(n)
192
c ( Deuxieme etage d'imbrication -> n & nh )
193
c
194

  
195
         DO WHILE ((rp(nh).GE.rs).AND.(rp(nh).LE.rp(1)))
196
            nh=nh+1
197
            pp=ps
198
            up=us
199
            vp=vs
200
            CALL rungekutta(ps,us,vs,pp,up,vp,h,m,b)
201
            rp(nh)=b/us
202
         END DO
203

  
204
c
205
c Mise a zero de tous les termes non redefinis du vecteur polaire
206
c ( Deuxieme etage d'imbrication -> n & 1 )
207
c
208

  
209
         DO i=nh+1,2000
210
            rp(i)=0. 
211
         END DO
212

  
213
c
214
c Determination des points de la trajectoire coupant le plan du disque
215
c par echantillonnage de 1' angle phi sur un cercle, a pas radial constant
216
c ( Deuxieme etage d'imbrication -> n & 1 )
217
c
218

  
219
         imx=INT(8*d)
220
         DO i=0,imx
221
            phi=2*pi/imx*i
222

  
223
c Calcul de l'angle "brut" d'intersection dans la base polaire
224

  
225
            phd=atanp(DCOS(phi)*DSIN(tho),DCOS(tho))
226
            phd=phd-INT(phd/pi)*pi
227
            ii=0
228
            tst=.FALSE.
229

  
230
c
231
c Boucle tant que - que l'image tertiaire n'a pas ete teste
232
c - le rayon n'est pas dans le domaine du disque
233
c ( Troisieme etage d'imbrication -> n , 1 , (ii, tst) , r )
234
c
235

  
236
            DO WHILE((ii.LE.2).AND.(tst.EQV..FALSE.))
237

  
238
c Calcul de l'angle d'intersection pour chacune des images
239

  
240
               php=phd+ii*pi
241
               nr=php/h
242
               ni=INT(nr)
243

  
244
c Interpolation lineaire de la distance photon-trou noir
245

  
246
               IF (ni.LT.nh) THEN
247
                  r=(rp(ni+1)-rp(ni))*(nr-ni*1.)+rp(ni)
248
               ELSE
249
                  r=rp(ni)
250
               ENDIF
251

  
252

  
253
c
254
c Test d'impact sur le disque
255
c ( Quatrieme etage d'imbrication -> n , i , (ii,tst) , r )
256
c
257

  
258
               IF ((r.LE.re).AND.(r.GE.ri)) then
259
                  tst=.TRUE.
260

  
261
c S'il y a impact calcul - du rapport de frequence
262
c - du spectre de photons et de flux
263

  
264
                  CALL impact(raie,d,phi,dim,r,b,tho,m,zp,fp,nt,
265
     & fx,q,db,h,nbr,bss)
266

  
267
               END IF
268

  
269
               ii=ii+1
270
            END DO
271
         END DO
272
      END DO
273

  
274
c Appel de la routine d'affichage
275

  
276
      CALL affichage(zp,fp,nt,fx,dim,nbr,bss,bmx,m,ri,re,tho,pi)
277

  
278
      WRITE(*,*)
279
      WRITE(*,*) 'C''est TERMINE ! '
280
      WRITE(*,*) 
281

  
282
      STOP
283
      END
284

  
285
c
286
c Cette fonction permet de trouver un arctangente entre 0 et 2*pi
287
c
288

  
289
      REAL*8 function atanp(x,y)
290
      REAL*8 x,y,pi,eps
291
      pi=3.141592654
292
      eps=1.e-20
293
      IF (ABS(x).LE.eps) then
294
         IF (ABS(y).EQ.Y) then
295
            atanp=pi/2.
296
         ELSE
297
            atanp=3.*pi/2.
298
         END IF
299
      ELSE
300
         IF (ABS(x).EQ.x) then
301
            IF (ABS(y).EQ.Y) then
302
               atanp=DATAN(y/x)
303
            ELSE
304
               atanp=DATAN(y/x)+2.*pi
305
            END IF
306
         ELSE
307
            atanp=DATAN(y/x)+pi
308
         END IF
309
      END IF
310
      RETURN
311
      END
312

  
313
c
314
c Premiere fonction du systeme -> ( d(u)/d(phi)=f(phi,u,v) )
315
c
316

  
317
      REAL*8 function f(v)
318
      REAL*8 v
319
      f=v
320
      RETURN
321
      END
322

  
323
c
324
c Deuxieme fonction du systeme -> ( d(v)/d(phi)=g(phi,u,v) )
325
c
326

  
327
      REAL*8 function g(u,m,b)
328
      REAL*8 u, m, b
329
      g=3.*m/b*u**2-u
330
      RETURN
331
      END
332

  
333
c
334
c Routine de d'intergration par la methode de Runge-Kutta
335
c
336

  
337
      SUBROUTINE rungekutta(ps,us,vs,pp,up,vp,h,m,b)
338
      REAL*8 ps,us,vs,pp,up,vp,h,m,b
339
      CALL calcul(us,vs,up,vp,h,m,b)
340
      ps=pp+h
341
      RETURN
342
      END
343

  
344
      SUBROUTINE calcul(us,vs,up,vp,h,m,b)
345
      REAL*8 us,vs,up,vp,h,m,b
346
      REAL*8 c(4),d(4),f,g
347
      c(1)=h*f(vp)
348
      c(2)=h* f(vp+c(1)/2.)
349
      c(3)=h*f(vp+c(2)/2.)
350
      c(4)=h*f(vp+c(3))
351
      d(1)=h*g(up,m,b)
352
      d(2)=h*g(up+d(1)/2.,m,b)
353
      d(3)=h*g(up+d(2)/2.,m,b)
354
      d(4)=h*g(up+d(3),m,b)
355
      us=up+(c(1)+2.*c(2)+2.*c(3)+c(4))/6.
356
      vs=vp+(d(1)+2.*d(2)+2.*d(3)+d(4))/6.
357
      RETURN
358
      END
359

  
360
c
361
c En cas d'impact, cette procedure :
362
c - etablit la position du pixel consisdere sur les images
363
c - appelle la routine de calcul de decalage spectral
364
c - appelle la routine de calcul du flux et du spectre
365
c - affecte a chacun des pixels sa valeur calculee
366
c
367

  
368
      SUBROUTINE impact(raie,d,phi,dim,r,b,tho,m,zp,fp, 
369
     & nt,fx,q,db,h,nbr,bss)
370
      REAL*8 d,phi,r,b,tho,m,fx(200),db,h
371
      INTEGER*4 dim,nt(200),q,nbr
372
      REAL*4 zp(dim,dim),fp(dim,dim),bss
373
      REAL*4 xe,ye
374
      INTEGER*4 xi,yi
375
      REAL*8 flx,rf
376
      LOGICAL raie
377
      xe=d*DSIN(phi)
378
      ye=-d*DCOS(phi)
379

  
380
c Calcul des coordonnees (x,y) du pixel sur chacune des images
381

  
382
      xi=INT(xe)+INT(dim/2.)
383
      yi=INT(ye)+INT(dim/2.)
384

  
385
c Appel de la routine de decalage spectral
386

  
387
      CALL decalage_spectral(rf,r,b,phi,tho,m)
388

  
389
c Appel de la routine de calcul de flux et de modification de spectre
390
c pour le cas d'une raie infiniment fine ou un corps noir
391

  
392
      IF (raie .EQV. .TRUE.) THEN
393
         CALL spectre(nt,fx,rf,q,b,db,h,r,m,nbr,bss,flx)
394
      ELSE
395
         CALL spectre_bb(nt,fx,rf,q,b,db,h,r,m,nbr,bss,flx)
396
      END IF
397

  
398
c Affectation sur chacune des images du decalage spectral et du flux
399

  
400
      IF(zp(xi,yi).EQ.0.) zp(xi,yi)=1./rf
401
      IF(fp(xi,yi).EQ.0.) fp(xi,yi)=flx
402

  
403
      RETURN
404
      END
405

  
406
c Calcul du rapport entre la frequence recue et la frequence emise
407

  
408
      SUBROUTINE decalage_spectral(rf,r,b,phi,tho,m)
409
      REAL*8 rf,r,b,phi,tho,m
410
      rf=sqrt(1-3*m/r)/(1+sqrt(m/r**3)*b*sin(tho)*sin(phi))
411
      RETURN
412
      END
413

  
414
c Calcul du flux puis du spectre pour une raie infiniment fine
415

  
416
      SUBROUTINE spectre(nt,fx,rf,q,b,db,h,r,m,nbr,bss,flx)
417
      REAL*8 fx(200)
418
      REAL*8 rf,b,db,h,r,m,flx
419
      REAL*4 bss
420
      INTEGER*4 nt(200),q,nbr
421
      INTEGER*4 fi
422
      fi=INT(rf*nbr/bss)
423
      nt(fi)=nt(fi)+1
424
      flx=(r/m)**q*rf**4*b*db*h
425
      fx(fi)=fx(fi)+flx
426
      RETURN
427
      END
428

  
429
c Calcul du flux puis du spectre pour un corps noir
430

  
431
      SUBROUTINE spectre_bb(nr,fx,rf,q,b,db,h,r,m,nbr,bss,flx)
432
      REAL*8 fx(200),nu_rec,nu_em,qu,v
433
      REAL*8 rf,b,db,h,r,m,flx,temp,temp_em,flux_int
434
      REAL*8 m_point
435
      REAL*4 bss
436
      INTEGER*4 nr(200),q,nbr
437
      INTEGER*4 fi,posfreq
438
      REAL*8 planck,c,k
439
      PARAMETER (planck=6.62e-34) ! definition des constantes
440
      PARAMETER (c=3.e8)
441
      PARAMETER (k=1.38e-23)
442

  
443
c
444
c Definition des parametres pour le calcul de la temperature d'emission
445
c puis calcul
446
c
447

  
448
      temp=3.e7
449
      m_point=1.
450

  
451
c v -> C du rapport
452

  
453
      v=1.-3./r
454

  
455
c qu -> Q du rapport
456

  
457
      qu=((1-3./r)**-.5)*(r**-.5)*((r**.5-6.**.5)+
458
     & ((3.**.5)/2.)*log ((r**.5)-(3.**.5))*0.171517)
459
      qu=abs(qu)
460
      temp_em=temp*m**.5
461
      temp_em=temp_em*m_point**.25
462
      temp_em=temp_em*r**(-.75)
463
      temp_em=temp_em*v**(-1./8.)
464
      temp_em=temp_em*qu**.25
465

  
466
c 
467
c initialisation des compteurs de flux
468
c flux int : flux recu pour le pixel dans la tranque posfreq
469
c flx : flux "bolometrique", integre de 0. a bss
470
c
471

  
472
      flux_int=0.
473
      flx=0.
474

  
475
c
476
c Balayage en frequence du spectre
477
c
478

  
479
      DO fi=1,nbr
480
         nu_em=bss*fi/nbr 	!frequence d' emission
481
         nu_rec=nu_em*rf 	!frequence de reception
482
         posfreq=INT(nu_rec*200./bss) !case ou se trouve nu rec
483

  
484
c
485
c test pour savoir si la frequence de reception est bien dans le
486
c domaine du spectre calcule
487
c
488

  
489
         if ((posfreq.GE.1).AND.(posfreq.LE.nbr)) THEN
490
            nr(posfreq)=nr(posfreq)+1
491

  
492
c Loi du corps noir
493

  
494
            flux_int=(2.*h*(nu_em**3/c**2))*
495
     & (1./(exp(planck*nu_em/(k*temp_em))-1.))
496

  
497
c Integration sur le pixel
498

  
499
            flux_int=flux_int*rf**3*b*db*h
500

  
501
c Remplissage du spectre
502

  
503
            fx(posfreq)=flux_int+fx(posfreq)
504

  
505
c Intergration bolometrique
506

  
507
            flx=flx+flux_int
508
         ENDIF
509
      END DO
510
      RETURN
511
      END
512

  
513
c
514
c AFFICHAGE DES RESULTATS : 6 fenetres de sortie
515
c
516
c - Image en decalage spectral
517
c - Image en flux
518
c - Dessin de parametres physiques interessants
519
c - Dessin des limites du disque a l'infini
520
c - Dessin du spectre en flux
521
c - Dessin du spectre en nombre de photons
522
c
523

  
524
      SUBROUTINE affichage(zp,fp,nt,fx,dim,nbr,bss,bmx,m,ri,re,tho,pi)
525
      INTEGER*4 nt(200),dim,nbr
526
      REAL*4 zp(dim,dim),fp(dim,dim),bss
527
      REAL*8 fx(200),bmx,m,ri,re,tho,pi
528
      INTEGER*4 np,i,j
529
      REAL*8 fm,nm
530
      REAL*4 fmx,zmx,x(200),y(200),tr(6),c(20),bmp
531
      LOGICAL tg
532
      LOGICAL ps
533

  
534
      tg=.TRUE.                 ! TRUE : affichage en tons de gris
535
c                               ! FALSE : affichage en contours
536

  
537
      ps=.FALSE.                ! TRUE : affichage postscript 
538
c                               ! FALSE : affichage fenetre Xwindow
539

  
540

  
541
c
542
c TRANSFORMATION DE L'IMAGE DES FLUX : FLUX -> FLUX RELATIFS
543
c
544

  
545
      np=0
546
      fm=0.
547
      DO i=1,dim
548
         DO j=1,dim
549
            IF (fp(i,j).NE.0.) np=np+1
550
            fm=fm+fp(i,j)
551
         END DO
552
      END DO
553
      fm=fm/np
554

  
555
c
556
c DETERMINATION DU DECALAGE SPECTRAL MAXIMUM ET DU FLUX MAXIMUM
557
c
558

  
559
      fmx=0.
560
      zmx=0.
561
      DO i=1,dim
562
         DO j=1,dim
563
            fp(i,j)=fp(i,j)/fm
564
            IF (fmx.LT.fp(i,j)) fmx=fp(i,j)
565
            IF (zmx.LT.zp(i,j)) zmx=zp(i,j)
566
         END DO
567
      END DO
568

  
569
      DATA tr/0.,1.,0.,0.,0.,1./
570

  
571
c
572
c AFFICHAGE DE L'IMAGE DES DECALAGES SPECTRAUX
573
c
574

  
575
      if (ps .EQV. .TRUE.) THEN
576
         CALL PGBEGIN (0,'image1.ps/ps',1,1)
577
      ELSE
578
         CALL PGBEGIN (0,'/xwindow',1,1)
579
      END IF
580
      CALL PGENV (1.,dim/1.,1.,dim/1.,1,-1)
581
      CALL PGLABEL('Image des decalages spectraux','',
582
     &'DISQUE D''ACCRETION AUTOUR D''UN TROU NOIR')
583
      IF (tg .EQV. .TRUE.) THEN
584
         DO i=0,25
585
            DO j=0,25
586
               zp(i+25,j+25)=1.
587
            END DO
588
         END DO
589
         CALL PGGRAY(zp,dim,dim,2,dim-1,2,dim-1,zmx,0.,tr)
590
      ELSE
591
         DO i=1,20
592
            c(i)=0.2*(i-1)
593
         END DO
594
         CALL PGCONS(zp,dim,dim,1,dim,1,dim,c,12,tr)
595
      END IF
596
      CALL PGEND
597

  
598
c
599
c AFFICHAGE DE L'IMAGE DES FLUX
600
c
601

  
602
      if (ps .EQV. .TRUE.) THEN
603
         CALL PGBEGIN (0,'image2.ps/ps',1,1)
604
      ELSE
605
         CALL PGBEGIN (0,'/xwindow',1,1)
606
      END IF
607
      CALL PGENV(1.,dim/1.,1.,dim/1.,1,-1)
608
      CALL PGLABEL(' Image des flux','',
609
     &'DISQUE D''ACCRETION AUTOUR D''UN TROU NOIR')
610
      if (tg) THEN
611
         DO i=0,25
612
            DO j=0,25
613
               fp(i+25,j+25)=1.
614
            END DO
615
         END DO
616
         CALL PGGRAY(fp,dim,dim,2,dim-1,2,dim-1,fmx,0.,tr)
617
      ELSE
618
         DO i=1,8
619
            c(i)=0.0625*2.**(i-1)
620
         END DO
621
         CALL PGCONS(fp,dim,dim,1,dim,1,dim,c,8,tr)
622
      END IF
623
      CALL PGEND
624

  
625
c
626
c AFFICHAGE DES DONNEES PHYSIQUES
627
c
628

  
629
      bmp=bmx
630

  
631
      if (ps .EQV. .TRUE.) THEN
632
         CALL PGBEGIN (0,'image3.ps/ps',1,1)
633
      ELSE
634
         CALL PGBEGIN (0,'/xwindow',1,1)
635
      END IF
636
      CALL PGENV (-bmp,bmp,-bmp,bmp,1,0)
637
      CALL PGLABEL('Rayon de Schwarzschild &
638
     &Parametre d''impact critique','',
639
     &'DISQUE D''ACCRETION AUTOUR D''UN TROU NOIR')
640
      DO i=1,200
641
         x(i)=2.*m*cos(2.*pi*i/200.)
642
         y(i)=2.*m*sin(2.*pi*i/200.)
643
      END DO
644
      CALL PGLINE(200,x,y)
645
      DO i=1,200
646
         x(i)=m*SQRT(27.)*cos(2.*pi*i/200.)
647
         y(i)=m*SQRT(27.)*sin(2.*pi*i/200.)
648
      END DO 
649
      CALL PGLINE(200,x,y)
650
      CALL PGEND
651

  
652
c
653
c AFFICHAGE DES CONTOURS DU DISQUE
654
c
655

  
656
      if (ps .EQV. .TRUE.) THEN
657
         CALL PGBEGIN (0,'image4.ps/ps',1,1)
658
      ELSE
659
         CALL PGBEGIN (0,'/xwindow',1,1)
660
      END IF
661
      CALL PGENV(-bmp,bmp,-bmp,bmp,1,0)
662
      CALL PGLABEL('Limites interieure & 
663
     &exterieure du disque a l''infini','',
664
     &'DISQUE D''ACCRETION AUTOUR D''UN TROU NOIR')
665
      DO i=1,200
666
         x(i)=ri*cos(2.*pi*i/200.)
667
         y(i)=ri*cos(tho)*sin (2.*pi*i/200.)
668
      END DO
669
      CALL PGLINE(200,x,y)
670
      DO i=1,200
671
         x(i)=re*cos(2.*pi*i/200.)
672
         y(i)=re*cos(tho)*sin(2.*pi*i/200.)
673
      END DO
674
      CALL PGLINE(200,x,y)
675
      CALL PGEND
676

  
677
c
678
c DETERMINATION DES FLUX ET NOMBRE D'IMPACTS MOYENS SUR LES SPECTRES
679
c
680

  
681
      fm=0.
682
      nm=0.
683
      stp=bss/nbr
684
      j=0
685
      do i=1,nbr
686
         x(i)=i*stp
687
         fm=fm+fx(i)
688
         nm=nm+1.*nt(i)
689
         IF (nt(i).GT.0) j=j+1
690
      END DO
691
      fm=fm/j
692
      nm=nm/j
693

  
694
c
695
c AFFICHAGE DU SPECTRE EN FLUX
696
c
697

  
698
      DO i=1,nbr
699
         y(i)=fx(i)/fm
700
      END DO
701
      if (ps .EQV. .TRUE.) THEN
702
         CALL PGBEGIN (0,'image5.ps/ps',1,1)
703
      ELSE
704
         CALL PGBEGIN (0,'/xwindow',1,1)
705
      END IF
706
      CALL PGENV (0.,2.,0.,10.,0,1)
707
      CALL PGLABEL('Rapport des frequences recue/emise',
708
     &'Flux relatif','SPECTRE DU DISQUE')
709
      CALL PGLINE(200,x,y)
710
      CALL PGEND
711

  
712
c
713
c AFFICHAGE DU SPECTRE EN NOMBRE D'IMPACTS
714
c
715

  
716
      DO i=1,nbr
717
         y(i)=1.*nt(i)/nm
718
      END DO
719
      if (ps .EQV. .TRUE.) THEN
720
         CALL PGBEGIN (0,'image6.ps/ps',1,1)
721
      ELSE
722
         CALL PGBEGIN (0,'/xwindow',1,1)
723
      END IF
724
      CALL PGENV(0.,2.,0.,10.,0,1)
725
      CALL PGLABEL('Rapport des frequences recue/emise',
726
     &' Nombre relatif d''impacts','SPECTRE DU DISQUE')
727
      CALL PGLINE(200,x,y)
728
      CALL PGEND
729

  
730
      RETURN
731
      END
732

  
733
c compilation : 
734
c gfortran --std=gnu -o trou_noir_Fortran trou_noir.f -lpgplot
735
c SORTIE GRAPHIQUE : -> Envoi sur l'ecran : /xwindow
736
c ( dans PGBEGIN ) -> Envoi en format postscript : nom image.ps/ps
737

  
738

  
739

  
740

  
741

  
TrouNoir/trou_noir_float.c (revision 197)
1
/*
2
	Programme original realise en Fortran 77 en mars 1994
3
	pour les Travaux Pratiques de Modelisation Numerique
4
	DEA d'astrophysique et techniques spatiales de Meudon
5

  
6
		par Herve Aussel et Emmanuel Quemener
7

  
8
	Conversion en C par Emmanuel Quemener en aout 1997
9

  
10
	Remerciements a :
11

  
12
	- Herve Aussel pour sa procedure sur le spectre de corps noir
13
	- Didier Pelat pour l'aide lors de ce travail
14
	- Jean-Pierre Luminet pour son article de 1979
15
	- Le Numerical Recipies pour ses recettes de calcul
16
	- Luc Blanchet pour sa disponibilite lors de mes interrogations en RG
17

  
18
	Mes Coordonnees :	Emmanuel Quemener
19
				Departement Optique
20
				ENST de Bretagne
21
				BP 832
22
				29285 BREST Cedex
23

  
24
				Emmanuel.Quemener@enst-bretagne.fr
25

  
26
	Compilation sous gcc ( Compilateur GNU sous Linux ) :
27

  
28
		gcc -O6 -m486 -o trou_noir trou_noir.c -lm
29
*/ 
30

  
31
#include <stdio.h>
32
#include <math.h>
33
#include <stdlib.h>
34
#include <string.h>
35

  
36
#define nbr 200 /* Nombre de colonnes du spectre */
37

  
38
#define PI 3.14159265359
39

  
40
float atanp(float x,float y)
41
{
42
  float angle;
43

  
44
  angle=atan2(y,x);
45

  
46
  if (angle<0)
47
    {
48
      angle+=2*PI;
49
    }
50

  
51
  return angle;
52
}
53

  
54

  
55
float f(float v)
56
{
57
  return v;
58
}
59

  
60
float g(float u,float m,float b)
61
{
62
  return (3.*m/b*pow(u,2)-u);
63
}
64

  
65

  
66
void calcul(float *us,float *vs,float up,float vp,
67
	    float h,float m,float b)
68
{
69
  float c[4],d[4];
70

  
71
  c[0]=h*f(vp);
72
  c[1]=h*f(vp+c[0]/2.);
73
  c[2]=h*f(vp+c[1]/2.);
74
  c[3]=h*f(vp+c[2]);
75
  d[0]=h*g(up,m,b);
76
  d[1]=h*g(up+d[0]/2.,m,b);
77
  d[2]=h*g(up+d[1]/2.,m,b);
78
  d[3]=h*g(up+d[2],m,b);
79

  
80
  *us=up+(c[0]+2.*c[1]+2.*c[2]+c[3])/6.;
81
  *vs=vp+(d[0]+2.*d[1]+2.*d[2]+d[3])/6.;
82
}
83

  
84
void rungekutta(float *ps,float *us,float *vs,
85
		float pp,float up,float vp,
86
		float h,float m,float b)
87
{
88
  calcul(us,vs,up,vp,h,m,b);
89
  *ps=pp+h;
90
}
91

  
92

  
93
float decalage_spectral(float r,float b,float phi,
94
			 float tho,float m)
95
{
96
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
97
}
98

  
99
/* void spectre(float rf,int q,float b,float db, */
100
/* 	     float h,float r,float m,float bss,float *flx) */
101
float spectre(float rf,int q,float b,float db,
102
	     float h,float r,float m,float bss)
103
{
104
  float flx;
105
  int fi;
106

  
107
  fi=(int)(rf*nbr/bss);
108
  flx=pow(r/m,q)*pow(rf,4)*b*db*h;
109
  return(flx);
110
}
111

  
112
/* void spectre_cn(float rf,float b,float db, */
113
/* 		float h,float r,float m,float bss,float *flx) */
114
float spectre_cn(float rf,float b,float db,
115
		float h,float r,float m,float bss)
116
{
117
  float flx;
118
  float nu_rec,nu_em,qu,v,temp,temp_em,flux_int,m_point,planck,c,k;
119
  int fi,posfreq;
120

  
121
  planck=6.62e-34;
122
  k=1.38e-23;
123
  temp=3.e7;
124
  m_point=1.e14;
125
  v=1.-3./r;
126

  
127
  qu=1/sqrt(1-3./r)/sqrt(r)*(sqrt(r)-sqrt(6)+sqrt(3)/2*log((sqrt(r)+sqrt(3))/(sqrt(r)-sqrt(3))*(sqrt(6)-sqrt(3))/(sqrt(6)+sqrt(3))));
128

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

  
132
  flux_int=0;
133
  flx=0;
134

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

  
149
void impact(float d,float phi,int dim,float r,float b,float tho,float m,
150
	    float **zp,float **fp,
151
	    int q,float db,
152
	    float h,float bss,int raie)
153
{
154
  float xe,ye;
155
  int xi,yi;
156
  float flx,rf;
157
  xe=d*sin(phi);
158
  ye=-d*cos(phi);
159

  
160
  xi=(int)xe+dim/2;
161
  yi=(int)ye+dim/2;
162

  
163
  rf=decalage_spectral(r,b,phi,tho,m);
164

  
165
  if (raie==0)
166
    {
167
      flx=spectre(rf,q,b,db,h,r,m,bss);
168
    }
169
  else
170
    {
171
      flx=spectre_cn(rf,b,db,h,r,m,bss);
172
    }
173
  
174
  if (zp[xi][yi]==0.)
175
    {
176
      zp[xi][yi]=1./rf;
177
    }
178
  
179
  if (fp[xi][yi]==0.)
180
    {
181
      fp[xi][yi]=flx;
182
    }
183
}
184

  
185
void sauvegarde_pgm(char nom[24],unsigned int **image,int dim)
186
{
187
  FILE            *sortie;
188
  unsigned long   i,j;
189
  
190
  sortie=fopen(nom,"w");
191
  
192
  fprintf(sortie,"P5\n");
193
  fprintf(sortie,"%i %i\n",dim,dim);
194
  fprintf(sortie,"255\n");
195

  
196
  for (j=0;j<dim;j++) for (i=0;i<dim;i++)
197
    {
198
      fputc(image[i][j],sortie);
199
    }
200

  
201
  fclose(sortie);
202
}
203

  
204
int main(int argc,char *argv[])
205
{
206

  
207
  float m,rs,ri,re,tho,ro;
208
  int q;
209

  
210
  float bss,stp;
211
  int nmx,dim;
212
  float d,bmx,db,b,h;
213
  float up,vp,pp;
214
  float us,vs,ps;
215
  float rp[2000];
216
  float **zp,**fp;
217
  unsigned int **izp,**ifp;
218
  float zmx,fmx,zen,fen;
219
  float flux_tot,impc_tot;
220
  float phi,thi,thx,phd,php,nr,r;
221
  int ni,ii,i,imx,j,n,tst,dist,raie,pc,fcl,zcl;
222
  float nh;
223

  
224
  if (argc==2)
225
    {
226
      if (strcmp(argv[1],"-aide")==0)
227
	{
228
	  printf("\nSimulation d'un disque d'accretion autour d'un trou noir\n");
229
	  printf("\nParametres a definir :\n\n");
230
	  printf("   1) Dimension de l'Image\n");
231
	  printf("   2) Masse relative du trou noir\n");
232
	  printf("   3) Dimension du disque exterieur\n");
233
	  printf("   4) Distance de l'observateur\n");
234
	  printf("   5) Inclinaison par rapport au disque (en degres)\n");
235
	  printf("   6) Observation a distance FINIE ou INFINIE\n");
236
	  printf("   7) Rayonnement de disque MONOCHROMATIQUE ou CORPS_NOIR\n");
237
	  printf("   8) Normalisation des flux INTERNE ou EXTERNE\n");
238
	  printf("   9) Normalisation de z INTERNE ou EXTERNE\n"); 
239
	  printf("  10) Impression des images NEGATIVE ou POSITIVE\n"); 
240
	  printf("  11) Nom de l'image des Flux\n");
241
	  printf("  12) Nom de l'image des decalages spectraux\n");
242
	  printf("  13) Valeur de normalisation des flux\n");
243
	  printf("  14) Valeur de normalisation des decalages spectraux\n");
244
	  printf("\nSi aucun parametre defini, parametres par defaut :\n\n");
245
	  printf("   1) Dimension de l'image : 256 pixels de cote\n");
246
	  printf("   2) Masse relative du trou noir : 1\n");
247
	  printf("   3) Dimension du disque exterieur : 12 \n");
248
	  printf("   4) Distance de l'observateur : 100 \n");
249
	  printf("   5) Inclinaison par rapport au disque (en degres) : 10\n");
250
	  printf("   6) Observation a distance FINIE\n");
251
	  printf("   7) Rayonnement de disque MONOCHROMATIQUE\n");
252
	  printf("   8) Normalisation des flux INTERNE\n");
253
	  printf("   9) Normalisation des z INTERNE\n");
254
	  printf("  10) Impression des images NEGATIVE ou POSITIVE\n"); 
255
       	  printf("  11) Nom de l'image des flux : flux.pgm\n");
256
	  printf("  12) Nom de l'image des z : z.pgm\n");
257
	  printf("  13) <non definie>\n");
258
	  printf("  14) <non definie>\n");
259
	}
260
    }
261
  
262
  if ((argc==13)||(argc==15))
263
    {
264
      printf("# Utilisation les valeurs definies par l'utilisateur\n");
265
      
266
      dim=atoi(argv[1]);
267
      m=atof(argv[2]);
268
      re=atof(argv[3]);
269
      ro=atof(argv[4]);
270
      tho=PI/180.*(90-atof(argv[5]));
271
      
272
      rs=2.*m;
273
      ri=3.*rs;
274
      q=-2;
275

  
276
      if (strcmp(argv[6],"FINIE")==0)
277
	{
278
	  dist=0;
279
	}
280
      else
281
	{
282
	  dist=1;
283
	}
284

  
285
      if (strcmp(argv[7],"MONOCHROMATIQUE")==0)
286
	{
287
	  raie=0;
288
	}
289
      else
290
	{
291
	  raie=1;
292
	}
293

  
294
      if (strcmp(argv[8],"EXTERNE")==0)
295
	{
296
	  fen=atof(argv[14]);
297
	}
298
      
299
      if (strcmp(argv[9],"EXTERNE")==0)
300
	{
301
	  zen=atof(argv[15]);
302
	}
303
      
304
    }
305
  else
306
    {
307
      printf("# Utilisation les valeurs par defaut\n");
308
      
309
      dim=256;
310
      m=1.;
311
      rs=2.*m;
312
      ri=3.*rs;
313
      re=12.;
314
      ro=100.;
315
      tho=PI/180.*80;
316
      q=-2;
317
      dist=0;
318
      raie=0;
319
    }
320
      
321
      printf("# Dimension de l'image : %i\n",dim);
322
      printf("# Masse : %f\n",m);
323
      printf("# Rayon singularite : %f\n",rs);
324
      printf("# Rayon interne : %f\n",ri);
325
      printf("# Rayon externe : %f\n",re);
326
      printf("# Distance de l'observateur : %f\n",ro);
327
      printf("# Inclinaison a la normale en radian : %f\n",tho);
328
  
329
  zp=(float**)calloc(dim,sizeof(float*));
330
  zp[0]=(float*)calloc(dim*dim,sizeof(float));
331
  
332
  fp=(float**)calloc(dim,sizeof(float*));
333
  fp[0]=(float*)calloc(dim*dim,sizeof(float));
334

  
335
  izp=(unsigned int**)calloc(dim,sizeof(unsigned int*));
336
  izp[0]=(unsigned int*)calloc(dim*dim,sizeof(unsigned int));
337
  
338
  ifp=(unsigned int**)calloc(dim,sizeof(unsigned int*));
339
  ifp[0]=(unsigned int*)calloc(dim*dim,sizeof(unsigned int));
340

  
341
  for (i=1;i<dim;i++)
342
    {
343
      zp[i]=zp[i-1]+dim;
344
      fp[i]=fp[i-1]+dim;
345
      izp[i]=izp[i-1]+dim;
346
      ifp[i]=ifp[i-1]+dim;
347
    }
348

  
349
  nmx=dim;
350
  stp=dim/(2.*nmx);
351
  bmx=1.25*re;
352
  b=0.;
353
  thx=asin(bmx/ro);
354
  pc=0;
355

  
356
  if (raie==0)
357
    {
358
      bss=2;
359
    }
360
  else
361
    {
362
      bss=3e21;
363
    }
364

  
365
  for (n=1;n<=nmx;n++)
366
    {     
367
      h=PI/500.;
368
      d=stp*n;
369

  
370
      if (dist==1)
371
	{
372
	  db=bmx/(float)nmx;
373
	  b=db*(float)n;
374
	  up=0.;
375
	  vp=1.;
376
	}
377
      else
378
	{
379
	  thi=thx/(float)nmx*(float)n;
380
	  db=ro*sin(thi)-b;
381
	  b=ro*sin(thi);
382
	  up=sin(thi);
383
	  vp=cos(thi);
384
	}
385
      
386
      pp=0.;
387
      nh=1;
388

  
389
      rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
390
    
391
      rp[(int)nh]=fabs(b/us);
392
      
393
      do
394
	{
395
	  nh++;
396
	  pp=ps;
397
	  up=us;
398
	  vp=vs;
399
	  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
400
	  
401
	  rp[(int)nh]=b/us;
402
	  
403
	} while ((rp[(int)nh]>=rs)&&(rp[(int)nh]<=rp[1]));
404
      
405
      for (i=nh+1;i<2000;i++)
406
	{
407
	  rp[i]=0.; 
408
	}
409
      
410
      imx=(int)(8*d);
411
      
412
      for (i=0;i<=imx;i++)
413
	{
414
	  phi=2.*PI/(float)imx*(float)i;
415
	  phd=atanp(cos(phi)*sin(tho),cos(tho));
416
	  phd=fmod(phd,PI);
417
	  ii=0;
418
	  tst=0;
419
	  
420
	  do
421
	    {
422
	      php=phd+(float)ii*PI;
423
	      nr=php/h;
424
	      ni=(int)nr;
425

  
426
	      if ((float)ni<nh)
427
		{
428
		  r=(rp[ni+1]-rp[ni])*(nr-ni*1.)+rp[ni];
429
		}
430
	      else
431
		{
432
		  r=rp[ni];
433
		}
434
	   
435
	      if ((r<=re)&&(r>=ri))
436
		{
437
		  tst=1;
438
		  impact(d,phi,dim,r,b,tho,m,zp,fp,q,db,h,bss,raie);
439
		}
440
	      
441
	      ii++;
442
	    } while ((ii<=2)&&(tst==0));
443
	}
444
    }
445

  
446
  fmx=fp[0][0];
447
  zmx=zp[0][0];
448
  
449
  for (i=0;i<dim;i++) for (j=0;j<dim;j++)
450
    {
451
      if (fmx<fp[i][j])
452
	{
453
	  fmx=fp[i][j];
454
	}
455
      
456
      if (zmx<zp[i][j])
457
	{
458
	  zmx=zp[i][j];
459
	}
460
    }
461

  
462
  printf("\nLe flux maximal detecte est de %f",fmx);
463
  printf("\nLe decalage spectral maximal detecte est de %f\n\n",zmx);
464

  
465
  if (strcmp(argv[8],"EXTERNE")==0)
466
    {
467
      fmx=fen;
468
    }
469

  
470
  if (strcmp(argv[9],"EXTERNE")==0)
471
    {  
472
      zmx=zen;
473
    }
474

  
475
  for (i=0;i<dim;i++) for (j=0;j<dim;j++)
476
    {
477
      zcl=(int)(255/zmx*zp[i][dim-1-j]);
478
      fcl=(int)(255/fmx*fp[i][dim-1-j]);
479

  
480
      if (strcmp(argv[8],"NEGATIVE")==0)
481
	{
482
	  if (zcl>255)
483
	    {
484
	      izp[i][j]=0;
485
	    }
486
	  else
487
	    {
488
	      izp[i][j]=255-zcl;
489
	    }
490
	  
491
	  if (fcl>255)
492
	    {
493
	      ifp[i][j]=0;
494
	    }
495
	  else
496
	    {
497
	      ifp[i][j]=255-fcl;
498
	    } 
499
	  
500
	}
501
      else
502
	{
503
	  if (zcl>255)
504
	    {
505
	      izp[i][j]=255;
506
	    }
507
	  else
508
	    {
509
	      izp[i][j]=zcl;
510
	    }
511
	  
512
	  if (fcl>255)
513
	    {
514
	      ifp[i][j]=255;
515
	    }
516
	  else
517
	    {
518
	      ifp[i][j]=fcl;
519
	    } 
520
	  
521
	}
522
	
523
    }
524

  
525
  if ((argc==14)||(argc==16))
526
   {
527
     sauvegarde_pgm(argv[11],ifp,dim);
528
     sauvegarde_pgm(argv[12],izp,dim);
529
   }
530
  else
531
    {
532
      sauvegarde_pgm("z.pgm",izp,dim);
533
      sauvegarde_pgm("flux.pgm",ifp,dim);
534
    }
535

  
536
  free(zp[0]);
537
  free(zp);
538
  free(fp[0]);
539
  free(fp);
540

  
541
  free(izp[0]);
542
  free(izp);
543
  free(ifp[0]);
544
  free(ifp);
545

  
546
}
547

  
548

  
TrouNoir/trou_noir_20190607.c (revision 197)
1
/*
2
	Programme original realise en Fortran 77 en mars 1994
3
	pour les Travaux Pratiques de Modelisation Numerique
4
	DEA d'astrophysique et techniques spatiales de Meudon
5

  
6
		par Herve Aussel et Emmanuel Quemener
7

  
8
	Conversion en C par Emmanuel Quemener en aout 1997
9

  
10
	Remerciements a :
11

  
12
	- Herve Aussel pour sa procedure sur le spectre de corps noir
13
	- Didier Pelat pour l'aide lors de ce travail
14
	- Jean-Pierre Luminet pour son article de 1979
15
	- Le Numerical Recipies pour ses recettes de calcul
16
	- Luc Blanchet pour sa disponibilite lors de mes interrogations en RG
17

  
18
	Mes Coordonnees :	Emmanuel Quemener
19
				Departement Optique
20
				ENST de Bretagne
21
				BP 832
22
				29285 BREST Cedex
23

  
24
				Emmanuel.Quemener@enst-bretagne.fr
25

  
26
	Compilation sous gcc ( Compilateur GNU sous Linux ) :
27

  
28
		gcc -O6 -m486 -o trou_noir trou_noir.c -lm
29
*/ 
30

  
31
#include <stdio.h>
32
#include <math.h>
33
#include <stdlib.h>
34
#include <string.h>
35

  
36
#define nbr 200 /* Nombre de colonnes du spectre */
37

  
38
#define PI 3.14159265359
39

  
40
float atanp(float x,float y)
41
{
42
  float angle;
43

  
44
  angle=atan2(y,x);
45

  
46
  if (angle<0)
47
    {
48
      angle+=2*PI;
49
    }
50

  
51
  return angle;
52
}
53

  
54

  
55
float f(float v)
56
{
57
  return v;
58
}
59

  
60
float g(float u,float m,float b)
61
{
62
  return (3.*m/b*pow(u,2)-u);
63
}
64

  
65

  
66
void calcul(float *us,float *vs,float up,float vp,
67
	    float h,float m,float b)
68
{
69
  float c[4],d[4];
70

  
71
  c[0]=h*f(vp);
72
  c[1]=h*f(vp+c[0]/2.);
73
  c[2]=h*f(vp+c[1]/2.);
74
  c[3]=h*f(vp+c[2]);
75
  d[0]=h*g(up,m,b);
76
  d[1]=h*g(up+d[0]/2.,m,b);
77
  d[2]=h*g(up+d[1]/2.,m,b);
78
  d[3]=h*g(up+d[2],m,b);
79

  
80
  *us=up+(c[0]+2.*c[1]+2.*c[2]+c[3])/6.;
81
  *vs=vp+(d[0]+2.*d[1]+2.*d[2]+d[3])/6.;
82
}
83

  
84
void rungekutta(float *ps,float *us,float *vs,
85
		float pp,float up,float vp,
86
		float h,float m,float b)
87
{
88
  calcul(us,vs,up,vp,h,m,b);
89
  *ps=pp+h;
90
}
91

  
92

  
93
float decalage_spectral(float r,float b,float phi,
94
			 float tho,float m)
95
{
96
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
97
}
98

  
99
/* void spectre(float rf,int q,float b,float db, */
100
/* 	     float h,float r,float m,float bss,float *flx) */
101
float spectre(float rf,int q,float b,float db,
102
	     float h,float r,float m,float bss)
103
{
104
  float flx;
105
  int fi;
106

  
107
  fi=(int)(rf*nbr/bss);
108
  flx=pow(r/m,q)*pow(rf,4)*b*db*h;
109
  return(flx);
110
}
111

  
112
/* void spectre_cn(float rf,float b,float db, */
113
/* 		float h,float r,float m,float bss,float *flx) */
114
float spectre_cn(float rf,float b,float db,
115
		float h,float r,float m,float bss)
116
{
117
  float flx;
118
  float nu_rec,nu_em,qu,v,temp,temp_em,flux_int,m_point,planck,c,k;
119
  int fi,posfreq;
120

  
121
  planck=6.62e-34;
122
  k=1.38e-23;
123
  temp=3.e7;
124
  m_point=1.e14;
125
  v=1.-3./r;
126

  
127
  qu=1/sqrt(1-3./r)/sqrt(r)*(sqrt(r)-sqrt(6)+sqrt(3)/2*log((sqrt(r)+sqrt(3))/(sqrt(r)-sqrt(3))*(sqrt(6)-sqrt(3))/(sqrt(6)+sqrt(3))));
128

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

  
132
  flux_int=0;
133
  flx=0;
134

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

  
149
void impact(float d,float phi,int dim,float r,float b,float tho,float m,
150
	    float **zp,float **fp,
151
	    int q,float db,
152
	    float h,float bss,int raie)
153
{
154
  float xe,ye;
155
  int xi,yi;
156
  float flx,rf;
157
  xe=d*sin(phi);
158
  ye=-d*cos(phi);
159

  
160
  xi=(int)xe+dim/2;
161
  yi=(int)ye+dim/2;
162

  
163
  rf=decalage_spectral(r,b,phi,tho,m);
164

  
165
  if (raie==0)
166
    {
167
      flx=spectre(rf,q,b,db,h,r,m,bss);
168
    }
169
  else
170
    {
171
      flx=spectre_cn(rf,b,db,h,r,m,bss);
172
    }
173
  
174
  if (zp[xi][yi]==0.)
175
    {
176
      zp[xi][yi]=1./rf;
177
    }
178
  
179
  if (fp[xi][yi]==0.)
180
    {
181
      fp[xi][yi]=flx;
182
    }
183
}
184

  
185
void sauvegarde_pgm(char nom[24],unsigned int **image,int dim)
186
{
187
  FILE            *sortie;
188
  unsigned long   i,j;
189
  
190
  sortie=fopen(nom,"w");
191
  
192
  fprintf(sortie,"P5\n");
193
  fprintf(sortie,"%i %i\n",dim,dim);
194
  fprintf(sortie,"255\n");
195

  
196
  for (j=0;j<dim;j++) for (i=0;i<dim;i++)
197
    {
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff