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 |
{ |
Formats disponibles : Unified diff