source: Sophya/trunk/FrEROS/AnaLC/nbgene.cc@ 4084

Last change on this file since 4084 was 3615, checked in by cmv, 16 years ago

Modifs relatives a l'introduction de RandomGeneratorInterface + delete de srandgen.c, cmv 01/05/2009

  • Property svn:executable set to *
File size: 12.5 KB
Line 
1#include "machdefs.h"
2#include "sopnamsp.h" // using SOPHYA namespace
3#include <stdio.h>
4#include <stdlib.h>
5#include <math.h>
6
7#include "fsvcache.h"
8#include "nbtri.h"
9#include "nbmath.h"
10#include "nbinteg.h"
11#include "strutil.h"
12#include "fsvst.h"
13#include "srandgen.h"
14#include "nbsread.h"
15#include "nbgene.h"
16
17/*==========================================================================*/
18int Give_Annee_Obs(int lp)
19/* retourne l'annee d'observation codee en entier du fichier de suivi utilise */
20{
21int j,anneeobs;
22double t=0.;
23anneeobs = -1;
24for(j=0;j<nmes[0];j++) {
25 t = timeu[0][j].TStart / JourSec;
26 if( t <= 0. ) continue;
27 /* confusion possible smc 93 avec debut lmc 9394 */
28 if( t > 1288. && t < 1314. ) continue;
29 if( t > 700. && t < 850. ) {anneeobs=9192; break;}
30 if( t > 950. && t < 1200. ) {anneeobs=9293; break;}
31 if( t > 1300. && t < 1570. ) {anneeobs=9394; break;}
32 if( t > 1630. && t < 1900. ) {anneeobs=9495; break;}
33 if( t > 2300. && t < 9999. ) {anneeobs=9697; break;}
34}
35if(lp>0) printf("annee_obs = %d (j=%d t=%f)\n",anneeobs,j,t);
36return (anneeobs);
37}
38
39/*=========================================================================*/
40float Rayon_SP_Th(float magv)
41/* Fournit le rayon de l'etoile de SP en rayons solaires
42* en fonction de sa magnitude Vj.
43* Formule theorique uniquement pour la sequence principale:
44* Rstar_SP = exp(-0.22 * (magv - MagV_sol) ) avec MagV_sol = 5.1
45*/
46{
47return( (float) exp(-0.22*(magv-5.1)) );
48}
49
50/*==========================================================================*/
51void AMPLML(int io)
52/* Generation MonteCarlo */
53{
54int i,ic,j,tf;
55float x;
56double t,tt,u2,u;
57int Nseq_tf = 3;
58unsigned short seed_16v[3];
59
60mc.TauSim = mc.TauSimI;
61mc.T0Sim = mc.T0SimI;
62mc.U0Sim = mc.U0SimI;
63mc.USim = mc.USimI;
64
65if(io == 1) {
66
67 /* initialisation des generateurs */
68 seed_16v[0]=(unsigned short) mc.iseed1;
69 seed_16v[1]=(unsigned short) mc.iseed2;
70 seed_16v[2]=(unsigned short) mc.iseed3;
71 RandGen->SetSeed(seed_16v);
72
73 mc.NGene = mc.NPoints_ampli = mc.NPoints_ampli_tf = mc.Net_ampli_tf = 0;
74
75 if(mc.montecar<=0) return;
76 if ( mc.Taille_Finie > 2 )
77 { printf("mauvaise valeur mc.Taille_Finie %d\n",mc.Taille_Finie);
78 exit(-1); }
79 if ( mc.Blending > 2 || mc.Blending < 0 )
80 { printf("mauvaise valeur mc.Blending %d\n",mc.Blending);
81 exit(-1); }
82
83 printf("MONTECARLO %2d: seed %d %d %d\n",io,mc.iseed1,mc.iseed2,mc.iseed3);
84 printf(" Generation %d, Taille_Finie %d blending %d\n"
85 ,mc.montecar,mc.Taille_Finie,mc.Blending);
86 printf(" Nombre de generations par etoile %d\n",mc.NGenStar);
87 printf(" TauSim=%f TauMinI=%f TauMaxI=%f TireTau=%p\n"
88 ,mc.TauSimI,mc.TauMinI,mc.TauMaxI,mc.TireTau);
89 printf(" T0Sim=%f T0MinI=%f T0MaxI=%f TireT0=%p\n"
90 ,mc.T0SimI,mc.T0MinI,mc.T0MaxI,mc.TireT0);
91 printf(" U0Sim=%f U0MinI=%f U0MaxI=%f TireU0=%p\n"
92 ,mc.U0SimI,mc.U0MinI,mc.U0MaxI,mc.TireU0);
93 printf(" USim =%f UMinI =%f UMaxI =%f TireU=%p\n"
94 ,mc.USimI,mc.UMinI,mc.UMaxI,mc.TireU);
95 printf(" coupure pour taille finie a U/u0 < %f\n",mc.Usu0_Cut);
96
97 if( (mc.U0MaxI <= mc.U0MinI && mc.U0SimI <= 0. && mc.Taille_Finie==0 )
98 || (mc.U0MaxI <= mc.U0MinI && mc.U0SimI < 0. && mc.Taille_Finie>0 ) ) {
99 printf("Mauvaises valeurs U0SimI U0MinI U0MaxI\n");
100 exit(-1);
101 }
102 if( mc.UMaxI <= mc.UMinI && mc.USimI <= 0. && mc.Taille_Finie>0 ) {
103 printf("Mauvaises valeurs USimI UMinI UMaxI\n");
104 exit(-1);
105 }
106 if( mc.TauMaxI <= mc.TauMinI && mc.TauSimI <= 0.) {
107 printf("Mauvaises valeurs TauSimI TauMinI TauMaxI\n");
108 exit(-1);
109 }
110
111} else if(io == 2) {
112
113 if( mc.T0MaxI <= mc.T0MinI && mc.T0SimI <= 0. ) {
114 mc.T0MinI_eff=TFIRST;
115 mc.T0MaxI_eff=TLAST;
116 } else {
117 mc.T0MinI_eff=mc.T0MinI;
118 mc.T0MaxI_eff=mc.T0MaxI;
119 }
120
121 if(mc.montecar<=0) return;
122
123 if( mc.Blending>0 && mc.Get_Par_Blending==0 ) {
124 printf("Vous avez demande une generation avec du Blending\n");
125 printf(" mais vous n'avez pas fourni la generation des parametres\n");
126 exit(-1);
127 }
128
129 printf("MONTECARLO %2d: ccd %6d, T0MinI_eff=%f T0MaxI_eff=%f\n"
130 ,io,ccdnum,mc.T0MinI_eff,mc.T0MaxI_eff);
131
132} else if(io == 3) {
133
134 mc.NGene++;
135
136 /* Blending preparation */
137 if( mc.Blending>0 ) mc.Get_Par_Blending();
138
139 /* Tirage aleatoire de u0 */
140 if ( mc.TireU0 != 0 ) {
141 x = drand01();
142 mc.U0Sim = mc.TireU0(x);
143 } else if(mc.U0MaxI > mc.U0MinI) {
144 mc.U0Sim= -1.;
145 while( mc.U0Sim <= 0. ) {
146 mc.U0Sim = mc.U0MinI + (mc.U0MaxI-mc.U0MinI)*drand01();
147 if(mc.U0Sim<=0.) printf("ATTENTION: U0 SIMULE A %f min=%f max=%f\n"
148 ,mc.U0Sim,mc.U0MinI,mc.U0MaxI);
149 } }
150
151 /* generation plate de tau */
152 if ( mc.TireTau != 0 ) {
153 x = drand01();
154 mc.TauSim = mc.TireTau(x);
155 } else if ( mc.TauMaxI > mc.TauMinI ) {
156 mc.TauSim = mc.TauMinI
157 + (mc.TauMaxI-mc.TauMinI)*drand01();
158 }
159
160 /* Tirage aleatoire de t0 */
161 if ( mc.TireT0 != 0 ) {
162 x = drand01();
163 mc.T0Sim = mc.TireT0(x);
164 } else if( mc.T0MaxI_eff > mc.T0MinI_eff ) {
165 mc.T0Sim = mc.T0MinI_eff
166 + (mc.T0MaxI_eff-mc.T0MinI_eff)*drand01();
167 }
168
169 /* generation plate de U */
170 if( mc.Taille_Finie > 0 ) {
171 if ( mc.TireU != 0 ) {
172 x = drand01();
173 mc.USim = mc.TireU(x);
174 } else if ( mc.Taille_Finie>0 && mc.UMaxI > mc.UMinI ) {
175 mc.USim= mc.UMinI + (mc.UMaxI-mc.UMinI)*drand01();
176 }
177 if(mc.Taille_Finie==2) {
178 if( mc.Blending==0 ) mc.USim *= starcal.Rstar;
179 else if( mc.Blending==1 ) mc.USim *= mc.starcal1.Rstar;
180 else if( mc.Blending==2 ) mc.USim *= mc.starcal2.Rstar;
181 }
182 }
183
184 /* calcul amplification ponctuelle/taille finie (paczinsky) */
185 mc.A0MaxPt = GRAND;
186 if( mc.U0Sim > 0. ) mc.A0MaxPt = ampli_ponct(mc.U0Sim);
187 mc.A0Max = (mc.Taille_Finie && mc.USim>0.) ?
188 ampli_tf(mc.U0Sim,mc.USim,Nseq_tf) : mc.A0MaxPt;
189 if( mc.Blending>0) for(ic=0;ic<NCOULMX;ic++) {
190 if( mc.Blending == 1 )
191 mc.A0Max_blend[ic] = (mc.A0Max -1.)* mc.coeff_Arec1[ic] + 1.;
192 else if( mc.Blending == 2 )
193 mc.A0Max_blend[ic] = (mc.A0Max -1.)* mc.coeff_Arec2[ic] + 1.;
194 }
195
196 tf = 0;
197 for(ic=0;ic<NCOULMX;ic++) {
198 for(i=0;i<nmes[ic];i++) {
199 t = date[ic][i];
200 tt = (t-mc.T0Sim)/mc.TauSim;
201 u2 = mc.U0Sim*mc.U0Sim + tt*tt;
202 u = sqrt(u2);
203 ampli[ic][i] = ampli_ponct(u);
204 mc.NPoints_ampli++;
205 if( mc.Taille_Finie && t<GRAND2 && mc.USim>0. ) {
206 if( mc.USim > mc.Usu0_Cut * u ) {
207 ampli[ic][i] = ampli_tf(u,mc.USim,Nseq_tf);
208 mc.NPoints_ampli_tf++;
209 if(tf==0) { mc.Net_ampli_tf++ ; tf = 1;}
210 }
211 }
212 if(mc.Blending==1)
213 ampli[ic][i] = (ampli[ic][i] -1.)* mc.coeff_Arec1[ic] + 1.;
214 else if(mc.Blending==2)
215 ampli[ic][i] = (ampli[ic][i] -1.)* mc.coeff_Arec2[ic] + 1.;
216 } }
217
218 if(debug>1) {
219 for(ic=0;ic<NCOULMX;ic++) {
220 printf("ampli[%3d]-1 u0=%12.5g t0=%12.5g tau=%12.5g U=%12.5g:\n"
221 ,ic,mc.U0Sim,mc.T0Sim,mc.TauSim,mc.USim);
222 for(i=0;i<nmesure[ic];i++)
223 { j=indexu[ic][i]; printf(" %12.5g",ampli[ic][j]-1.);
224 if(i%10==9) printf("\n");}
225 if((nmesure[ic]-1)%10!=9) printf("\n");
226 } }
227
228} else if(io == 4) {
229
230 return;
231
232} else if(io == 5) {
233
234 if(mc.montecar<=0) return;
235
236 printf("MONTECARLO %2d: Nombre d'evenements engendres %d\n",io,mc.NGene);
237 printf("Nb de pts amplifies %d, nb de pts amplifies avec taille finie %d\n"
238 ,mc.NPoints_ampli,mc.NPoints_ampli_tf);
239 printf("Nb d'etoiles amplifiees avec taille finie %d\n"
240 ,mc.Net_ampli_tf);
241 RandGen->SetSeed(seed_16v);
242 mc.iseed1 = (int_4)seed_16v[0];
243 mc.iseed2 = (int_4)seed_16v[1];
244 mc.iseed3 = (int_4)seed_16v[2];
245 printf("Aleatoire_de_fin_de_Generation %d %d %d\n"
246 ,mc.iseed1,mc.iseed2,mc.iseed3);
247
248}
249return;
250}
251
252/*==========================================================================*/
253double ampli_ponct(double u)
254/* amplification paczinsky dans le cas d'une source ponctuelle */
255{
256u *= u;
257if(u==0.) return(GRAND2);
258u = (u+2.)/sqrt(u*(u+4.));
259return (u);
260}
261
262/*==========================================================================*/
263double ampli_tf(double u, double U,int Nseq)
264/*
265Amplification paczinsky dans le cas d'une source non ponctuelle.
266 ( integration analytique partie interieure et
267 integration numerique partie exterieure )
268Integration exterieure par methode de Gauss (Higher order terms).
269 u = parametre d'impact en rayon d'Einstein en fct du temps
270 U = rayon de l'etoile projete en rayon d'Einstein
271 Nseq = nombre de pas pour l'integrale
272*/
273{
274int i,j;
275double u2,U2,lim1,lim2,dlim,A0,xc,x,nx,b,teta,Ka,z;
276int mIhoqN;
277double *IhoqNX, *IhoqNW;
278
279if( Nseq <= 0 ) Nseq = 2;
280if( u<0. || U<0. ) return(-1.);
281if( u==0. && U==0. ) return(GRAND2);
282
283mIhoqN=mIhoq9; IhoqNX=Ihoq9X; IhoqNW=Ihoq9W;
284
285u2 = u*u;
286U2 = U*U;
287
288Ka = 0.;
289lim1 = -1.;
290lim2 = 1.;
291dlim = (lim2 - lim1)/Nseq;
292
293/*** CAS 1 : u<=U (u=0 possible si U!=0) *** */
294/* A = A0 + A1 */
295/* A0 = partie integrable (sum(dx,0<x<U-u)) */
296/* = (U-u) * sqrt((U-u)**2 + 4) / U2 */
297/* A1 = 2*u/(Pi*U2) * sum(dx,-1<x<1) */
298/* {(u2+2)/sqrt(u2+4)*acos[(u*(1+x**2)/2+U*x)/(U+x*u)]} */
299
300if(u<=U) {
301 /* on calcule d'abord la partie analytique A0 */
302 x = (U-u);
303 A0 = x * sqrt(x*x + 4.);
304
305 /* on integre ensuite la partie numerique A1 */
306 for(j=0;j<Nseq;j++) {
307 xc = lim1 + (j+0.5)*dlim;
308 for(i=0;i<mIhoqN;i++) {
309 x = xc + IhoqNX[i]*dlim;
310 nx = U + x*u;
311 teta = acos( ( u*(1.+x*x)/2. + U*x ) /nx );
312 nx *= nx;
313 b = (nx + 2.) / sqrt(nx + 4.);
314 Ka += b * teta * IhoqNW[i];
315 } }
316 A0 += 2. * u / Pi * Ka * dlim;
317 A0 /= U2;
318}
319
320/*** CAS 2 : u>U --> U peut tendre vers 0 *** */
321/* A = 2/(Pi*U) * sum(dx,-1<x<1) */
322/* {(u2+2)/sqrt(u2+4)*acos[1-U2*(1-x**2)/(2*u*(u+x*U))]} */
323/* quand U->0, la divergence (1/U) est enlevee en developpant */
324/* acos(1-z) = sqrt(2*z)*[1+z/12+3*z2/160+...] */
325
326else if(u>U) {
327 for(j=0;j<Nseq;j++) {
328 xc = lim1 + (j+0.5)*dlim;
329 for(i=0;i<mIhoqN;i++) {
330 x = xc + IhoqNX[i]*dlim;
331 nx = u + x*U;
332 z = (1.-x*x) /(2.*u*nx);
333 nx *= nx;
334 b = (nx + 2.) / sqrt(nx + 4.);
335 if(U > 0.001*u) {
336 teta = acos( 1. - U2*z ) / U;
337 } else { /* cas U-> 0 */
338 teta = sqrt(2.*z);
339 z *= U2;
340 teta *= 1. + z*(0.08333333333333 + 0.01875*z);
341 }
342 Ka += b * teta * IhoqNW[i];
343 } }
344 A0 = 2. / Pi * Ka * dlim;
345}
346
347/*** CAS IMPOSSIBLE ****/
348else {
349 printf("ampli_tf: CAS IMPOSSIBLE u=%f U=%f\n",u,U);
350 A0 = -1.;
351}
352
353return (A0);
354}
355
356/*==========================================================================*/
357double u0_ponct(double A)
358/*
359Parametre d'impact pour une amplification A
360 dans le cas d'une source ponctuelle.
361input: A = amplification
362*/
363{
364double u0;
365if(A<1.) return(-1.);
366if(A==1.) return(GRAND2);
367u0 = 2. * ( A/sqrt(A*A-1.) - 1.);
368u0 = sqrt(u0);
369return(u0);
370}
371
372/*==========================================================================*/
373double u0_tf(double A,double U,double prec,int *niter,double *Afinal)
374/*
375Parametre d'impact pour une amplification A
376 dans le cas d'une source non ponctuelle.
377input:
378 A = amplification
379 U = Rstar projete / Reinst
380 prec = precision souhaitee sur u0
381 niter = nombre maximum d'iterations permises
382output:
383 niter = nombre d'iterations utilisees (-1 si pas converge)
384 Afinal = amplification finale calculee pour u0
385 return = u0 si trouve
386 -1. si A<1.
387 -2. si A=1.
388 -3. si U<=0
389 -4. si A trop grand
390 -5. si encadrement de A non trouve
391*/
392{
393int nitermx;
394double a0=0,a1,a2,u0=0,u1,u2,test;
395
396nitermx = *niter;
397if(nitermx<=0) nitermx = 25;
398
399*Afinal = A;
400*niter = 0;
401if(A<1.) return(-1.);
402if(A==1.) return(-2.);
403if(U<=0.) return(-3.);
404
405u1 = 0.;
406a1 = ampli_tf(u1,U,-1);
407if(a1==A) return(0.);
408/* on ne peut atteindre la valeur A */
409if(a1<A) { *Afinal = a1; return(-4.);}
410
411/* on recherche un intervalle encadrant A */
412u2 = u0_ponct(A);
413a2 = ampli_tf(u2,U,-1);
414while( a2>A && *niter<=nitermx ) {
415 /* printf("recherche inter %f (%f), %f (%f)\n",u1,a1,u2,a2); */
416 u1 = u2;
417 a1 = a2;
418 u2 *= 5.;
419 a2 = ampli_tf(u2,U,-1);
420 (*niter)++;
421}
422
423if( *niter>nitermx ) {
424 *Afinal = a2;
425 return(-5.);
426}
427
428/* a ce niveau u1 (a1) et u2 (a2) encadrent u0 (a0) */
429test = 100.*prec;
430*niter = 0;
431while (test > prec && *niter<= nitermx ) {
432 /* printf("recherche conv %f (%f), %f (%f)\n",u1,a1,u2,a2); */
433 u0 = (u1+u2)/2.;
434 a0 = ampli_tf(u0,U,-1);
435 (*niter)++;
436 if(a0<A) {
437 u2 = u0;
438 a2 = a0;
439 } else {
440 u1 = u0;
441 a1 = a0;
442 }
443 test = fabs(a0-A);
444}
445
446if( *niter > nitermx ) *niter = -1;
447/* printf("conv atteinte %f (%f), %f (%f)\n",u1,u2,a2); */
448*Afinal = a0;
449return(u0);
450
451}
452
Note: See TracBrowser for help on using the repository browser.