void shootf(int n, float v[], float f[]) { void derivs(float x, float y[], float dydx[]); void load1(float x1, float v1[], float y[]); void load2(float x2, float v2[], float y[]); void odeint(float ystart[], int nvar, float x1, float x2, float eps, float h1, float hmin, int *nok, int *nbad, void (*derivs)(float, float [], float []), void (*rkqs)(float [], float [], int, float *, float, float, float [], float *, float *, void (*)(float, float [], float []))); void rkqs(float y[], float dydx[], int n, float *x, float htry, float eps, float yscal[], float *hdid, float *hnext, void (*derivs)(float, float [], float [])); void score(float xf, float y[], float f[]); int i,nbad,nok; float h1,hmin=0.0,*f1,*f2,*y; f1=vector(1,nvar); f2=vector(1,nvar); y=vector(1,nvar); kmax=0; h1=(x2-x1)/100.0; load1(x1,v,y); odeint(y,nvar,x1,xf,EPS,h1,hmin,&nok,&nbad,derivs,rkqs); score(xf,y,f1); load2(x2,&v[nn2],y); odeint(y,nvar,x2,xf,EPS,h1,hmin,&nok,&nbad,derivs,rkqs); score(xf,y,f2); for (i=1;i<=n;i++) f[i]=f1[i]-f2[i]; free_vector(y,1,nvar); free_vector(f2,1,nvar); free_vector(f1,1,nvar); }
static void fillGravPotential(void) { double x[2],phi0,r1,r0,m1; int i; r0=rTab[0]*Rcm; if(r0==0) { phiTab[0]=0; r1=rTab[1]*Rcm; x[0]=4./3.*M_PI*rhoTab[0]*r1*r1*r1; phiTab[1]=x[1]=2./3.*M_PI*rhoTab[0]*r1*r1*Gconst*100; i=2; } else { x[0]=4./3.*M_PI*rhoTab[0]*r0*r0*r0; phiTab[0]=x[1]=2./3.*M_PI*rhoTab[0]*r0*r0*Gconst*100; //printf("phiTab[0]=%E\n",phiTab[0]); i=1; } for( ;i<nTab;i++) { odeint(x,2,Rcm*rTab[i-1], Rcm*rTab[i],1.E-3,Rcm*(rTab[i]-rTab[i-1])/3,derivePhi); phiTab[i]=x[1]; } phi0=x[0]*Gconst*100/Rcm; //printf("VescSurface=%E\n", sqrt(2*phi0)*Vlight); for(i=0;i<nTab;i++) phiTab[i]= phiTab[nTab-1]-phiTab[i]+phi0; //printf("VescCenter=%E\n", sqrt(2*phiTab[0])*Vlight); }
int main(void) { int i,nbad,nok; float eps=1.0e-4,h1=0.1,hmin=0.0,x1=1.0,x2=10.0,*ystart; ystart=vector(1,N); xp=vector(1,200); yp=matrix(1,10,1,200); ystart[1]=bessj0(x1); ystart[2]=bessj1(x1); ystart[3]=bessj(2,x1); ystart[4]=bessj(3,x1); nrhs=0; kmax=100; dxsav=(x2-x1)/20.0; odeint(ystart,N,x1,x2,eps,h1,hmin,&nok,&nbad,derivs,rkqs); printf("\n%s %13s %3d\n","successful steps:"," ",nok); printf("%s %20s %3d\n","bad steps:"," ",nbad); printf("%s %9s %3d\n","function evaluations:"," ",nrhs); printf("\n%s %3d\n","stored intermediate values: ",kount); printf("\n%8s %18s %15s\n","x","integral","bessj(3,x)"); for (i=1;i<=kount;i++) printf("%10.4f %16.6f %14.6f\n", xp[i],yp[4][i],bessj(3,xp[i])); free_matrix(yp,1,10,1,200); free_vector(xp,1,200); free_vector(ystart,1,N); return 0; }
void NR::shootf(Vec_I_DP &v, Vec_O_DP &f) { const DP EPS=1.0e-14; int i,nbad,nok; DP h1,hmin=0.0; int nvar=v.size(); Vec_DP f1(nvar),f2(nvar),y(nvar); Vec_DP v2(&v[n2],nvar-n2); kmax=0; h1=(x2-x1)/100.0; load1(x1,v,y); odeint(y,x1,xf,EPS,h1,hmin,nok,nbad,derivs,rkqs); score(xf,y,f1); load2(x2,v2,y); odeint(y,x2,xf,EPS,h1,hmin,nok,nbad,derivs,rkqs); score(xf,y,f2); for (i=0;i<nvar;i++) f[i]=f1[i]-f2[i]; }
double darkOmega(double * Xf, int Fast, double Beps) { double Yt,Yi,Xt=25; double Z1=1.1; double Z2=10; int i; double Xf1; if(Xf)*Xf=Xt; assignVal("Q",2*M); if(Beps>=1) Beps=0.999; if(Z1<=1) Z1=1.1; fast_=Fast; Yt= darkOmega1(&Xt, Z1, (Z1-1)/5,Fast, Beps); if(Yt<0||FError) return -1; Xf1=Xt; for(i=0; ;i++) { double X2=vSigmaGrid.xtop*pow(XSTEP,i+1); double y; if(Yt>=Z2*Yeq(Xt)) break; if(Xt>X2*0.999999) continue; while(vSigmaGrid.pow<=i+1) { double X; if(vSigmaGrid.pow==vSigmaGrid.size) { vSigmaGrid.size+=10; vSigmaGrid.data=(double*)realloc(vSigmaGrid.data,sizeof(double)*vSigmaGrid.size); } X=vSigmaGrid.xtop*pow(XSTEP,vSigmaGrid.pow); MassCut=M*(2-log(Beps)/X); vSigmaGrid.data[vSigmaGrid.pow++]=aRate(X,0,Fast,NULL); if(FError) return -1; } y=log(Yt); odeint(&y,1 , Xt , X2 , 1.E-3, (X2-Xt)/2, &XderivLn); Yt=exp(y); Xt=X2; } if(Xf) *Xf=0.5*(Xf1+Xt); Yi=1/( (M/Xt)*sqrt(M_PI/45)*MPlank*aRate(Xt,1,Fast,NULL) ); if(!finite(Yi)||FError) return -1; return 2.742E8*M/(1/Yt + 1/Yi); /* 2.828-old 2.755-new,2.742 -newnew */ }
double darkOmega(double * Xf, int Fast, double Beps) { double Yt,Yi,Xt=25; double Z1=1.1; double Z2=10; int i; double Xf1; if(Xf)*Xf=Xt; assignVal("Q",2*Mcdm); if(Beps>=1) Beps=0.999; Beps_=Beps; Fast_=Fast; if(Z1<=1) Z1=1.1; Yt= darkOmega1(&Xt, Z1, (Z1-1)/5,Fast, Beps); if(Yt<0||FError) {return -1;} Xf1=Xt; for(i=0; ;i++) { double X2=vSigmaGrid.xtop*pow(XSTEP,i+1); double y; if(Yt>=Z2*Yeq(Xt)) break; if(Xt>X2*0.999999) continue; y=Yt; if(odeint(&y,1 , Xt , X2 , 1.E-3, (X2-Xt)/2, &XderivLn)){return -1;} Yt=y; Xt=X2; } if(Xf) *Xf=0.5*(Xf1+Xt); Yi=1/( (Mcdm/Xt)*sqrt(M_PI/45)*MPlank*aRate(Xt,1,Fast,NULL,NULL)); if(!finite(Yi)||FError) return -1; if(deltaY==0.) { dmAsymm=0; return 2.742E8*Mcdm/(1/Yt + 1/Yi); /* 2.828-old 2.755-new,2.742 -newnew */ } else { double a,f,z0,Y0; a=fabs(deltaY); f= (sqrt(Yt*Yt+a*a)-a)/ (sqrt(Yt*Yt+a*a)+a)*exp(-2*a/Yi); z0=sqrt(f)*2*a/(1-f); Y0=sqrt(z0*z0+a*a); dmAsymm=log((Y0+deltaY)/(Y0-deltaY)); return 2.742E8*Mcdm*Y0; } }
int main(void) { float eps,hstart,x1=0.0,x2=50.0,y[4]; int nbad,nok; for (;;) { printf("Enter eps,hstart\n"); if (scanf("%f %f",&eps,&hstart) == EOF) break; kmax=0; y[1]=y[2]=1.0; y[3]=0.0; odeint(y,3,x1,x2,eps,hstart,0.0,&nok,&nbad,derivs,stifbs); printf("\n%s %13s %3d\n","successful steps:"," ",nok); printf("%s %20s %3d\n","bad steps:"," ",nbad); printf("Y(END) = %12.6f %12.6f %12.6f\n",y[1],y[2],y[3]); } printf("Normal completion\n"); return 0; }
fcomplex hypgeo(fcomplex a, fcomplex b, fcomplex c, fcomplex z) { void bsstep(float y[], float dydx[], int nv, float *xx, float htry, float eps, float yscal[], float *hdid, float *hnext, void (*derivs)(float, float [], float [])); void hypdrv(float s, float yy[], float dyyds[]); void hypser(fcomplex a, fcomplex b, fcomplex c, fcomplex z, fcomplex *series, fcomplex *deriv); void odeint(float ystart[], int nvar, float x1, float x2, float eps, float h1, float hmin, int *nok, int *nbad, void (*derivs)(float, float [], float []), void (*rkqs)(float [], float [], int, float *, float, float, float [], float *, float *, void (*)(float, float [], float []))); int nbad,nok; fcomplex ans,y[3]; float *yy; kmax=0; if (z.r*z.r+z.i*z.i <= 0.25) { hypser(a,b,c,z,&ans,&y[2]); return ans; } else if (z.r < 0.0) z0=Complex(-0.5,0.0); else if (z.r <= 1.0) z0=Complex(0.5,0.0); else z0=Complex(0.0,z.i >= 0.0 ? 0.5 : -0.5); aa=a; bb=b; cc=c; dz=Csub(z,z0); hypser(aa,bb,cc,z0,&y[1],&y[2]); yy=vector(1,4); yy[1]=y[1].r; yy[2]=y[1].i; yy[3]=y[2].r; yy[4]=y[2].i; odeint(yy,4,0.0,1.0,EPS,0.1,0.0001,&nok,&nbad,hypdrv,bsstep); y[1]=Complex(yy[1],yy[2]); free_vector(yy,1,4); return y[1]; }
void shoot(int n, float v[], float f[]) { void derivs(float x, float y[], float dydx[]); void load(float x1, float v[], float y[]); void odeint(float ystart[], int nvar, float x1, float x2, float eps, float h1, float hmin, int *nok, int *nbad, void (*derivs)(float, float [], float []), void (*rkqs)(float [], float [], int, float *, float, float, float [], float *, float *, void (*)(float, float [], float []))); void rkqs(float y[], float dydx[], int n, float *x, float htry, float eps, float yscal[], float *hdid, float *hnext, void (*derivs)(float, float [], float [])); void score(float xf, float y[], float f[]); int nbad,nok; float h1,hmin=0.0,*y; y=vector(1,nvar); kmax=0; h1=(x2-x1)/100.0; load(x1,v,y); odeint(y,nvar,x1,x2,EPS,h1,hmin,&nok,&nbad,derivs,rkqs); score(x2,y,f); free_vector(y,1,nvar); }
//int generate_king(int N, double W0, double **star, double *rvir, double *rh, double *rking, double D, int symmetry) int generate_king(int N, double W0, double **star, double *rvir, double *rh, double *rking) { //ODE variables int M = 10001; //Number of interpolation points int KMAX = 10000; //Maximum number of output steps of the integrator int i,j,k; double h; double den; double xstart, ystart0, ystart1; double x1, x2; double xp[KMAX], x[M]; int kount = 0; double yking[M][2], mass[M]; double rmin = 0.2; double **yp; yp = (double **)calloc(KMAX,sizeof(double *)); for (i=0;i<KMAX;i++){ yp[i] = (double *)calloc(2,sizeof(double)); if (yp[i] == NULL) { printf("\nMemory allocation failed!\n"); return 0; } } double pot = 0.0; double totmas; double zh; double ve, cg1; double fmass, r2; double costh, sinth, phi, r, xstar, ystar, zstar; double w1, w, wj1, wj; double vmax, speed, fstar, ustar, vstar, wstar, mstar; double ri; double **coord; coord = (double **)calloc(N,sizeof(double *)); for (j=0;j<N;j++){ coord[j] = (double *)calloc(6,sizeof(double)); if (coord[j] == NULL) { printf("\nMemory allocation failed!\n"); return 0; } } if (W0>12.0) { printf("W0 too large\n"); return 0; } else if (W0 < 0.2) { printf("W0 too small\n"); return 0; } /*************************** * INTERPOLATE KING VALUES * ***************************/ h = pow(W0-rmin,2)/(1.0*M-1.0); //step size for interpolation den = densty(W0); //central density //x is King's W, y[0] is z**2, y[1] is 2*z*dz/dW, where z is scaled radius //so x(y[0]) is energy as function of radius^2 and x(y[1]) is the derivative xstart = 0.000001; ystart0 = 2.0*xstart/3.0; ystart1 = -2.0/3.0; x1 = W0 - xstart; x2 = 0.0; //integrate Poisson's eqn printf("Integrating Poisson's equation\n"); odeint(ystart0, ystart1, x1, x2, den, &kount, xp, yp, M, KMAX); printf("No of integration steps = %i\n",kount); //interpolate yking for (k=0;k<M;k++) { x[k] = W0-rmin-sqrt(h*k); if (x[k] > xp[0]) { yking[k][0] = (W0-x[k])*yp[0][0]/(W0 - xp[0]); yking[k][1] = yp[0][1]; printf("+"); } else { i = 0; do { if ((x[k]-xp[i])*(x[k]-xp[i+1]) <= 0.0) { yking[k][0] = yp[i][0] + (yp[i+1][0]-yp[i][0])*(x[k]-xp[i])/(xp[i+1]-xp[i]); yking[k][1] = yp[i][1] + (yp[i+1][1]-yp[i][1])*(x[k]-xp[i])/(xp[i+1]-xp[i]); goto jump; } else { i++; } } while (i<kount); } jump: if (i >= kount) { yking[k][0] = yp[kount][0]; yking[k][1] = yp[kount][1]; } //get mass as a function of radius mass[k] = -2.0*pow(yking[k][0],1.5)/yking[k][1]; //calculate total potential energy if (k == 0) { pot = -0.5*pow(mass[k],2)/sqrt(yking[k][0]); } else { pot -= 0.5*(pow(mass[k],2) - pow(mass[k-1],2))/(0.5*(sqrt(yking[k][0]) + sqrt(yking[k-1][0]))); } } /****************************** * DETERMINE BASIC QUANTITIES * ******************************/ //Total mass totmas = -2.0*pow(yking[M-2][0],1.5)/yking[M-2][1]; //Half-mass radius k=0; do { k++; } while (mass[k] < 0.5*totmas); zh = yking[k][0] - (yking[k][0]-yking[k-1][0])*(mass[k]-0.5*totmas)/(mass[k]-mass[k-1]); *rh = sqrt(zh); //Virial radius and King radius *rvir = -pow(totmas,2)/(2.0*pot); *rking = sqrt(yking[M-2][0]); //Central velocity dispersion**2 (3-dimensional) ve = sqrt(2.0*W0); cg1 = (-pow(ve,3)*exp(-pow(ve,2)/2.0) - 3.0*ve*exp(-pow(ve,2)/2.0) + 3.0/2.0*sqrt(2.0*PI)*erf(ve*sqrt(2.0)/2.0) - pow(ve,5)*exp(-pow(ve,2)/2.0)/5.0)/(-ve*exp(-pow(ve,2)/2.0) + sqrt(2.0*PI)*erf(ve*sqrt(2.0)/2.0)/2.0 - pow(ve,3)*exp(-pow(ve,2)/2.0)/3.0); printf("\nTheoretical values:\n"); printf("Total mass (King units) = %g\n", totmas); printf("Viriral radius (King units) = %g\n", *rvir); printf("Half-mass radius (King units) = %g\t(Nbody units) = %g\n", *rh, *rh/ *rvir); printf("Edge radius (King units) = %g\t(Nbody units) = %g\n", *rking, *rking/ *rvir); printf("Concentration = %g\n", log10(*rking)); printf("Core radius (King units) = %g\t(Nbody units) = %g\n", 1.0, 1.0/ *rvir); printf("3d velocity dispersion**2: %g (central)\t %g (global)\n", cg1, -pot/totmas); /*************************** * GENERATE STAR POSITIONS * ***************************/ printf("\nGenerating Stars:\n"); if (1) { for (i=0;i<N;i++) { if ((i/1000)*1000 == i) printf("Generating orbits #%i\n", i); fmass = drand48()*mass[M-1]; if (fmass < mass[0]) { r2 = pow(fmass/mass[0],2.0/3.0)*yking[0][0]; } else { j = 0; do { j++; if (j>M) printf("WARNING: failing iteration\n"); } while (mass[j] <= fmass); r2 = yking[j-1][0] + (fmass-mass[j-1])*(yking[j][0] - yking[j-1][0])/(mass[j]-mass[j-1]); } r = sqrt(r2); costh = 2.0*drand48()-1.0; sinth = sqrt(1.0-pow(costh,2)); phi = 2.0*PI*drand48(); xstar = r*sinth*cos(phi); ystar = r*sinth*sin(phi); zstar = r*costh; /**************** * CHOOSE SPEED * ****************/ if (r < *rking) { if (r < sqrt(yking[0][0])) { w1 = x[0]; w = W0 - (r2/yking[0][0])*(W0 - w1); } else { j = 0; do { j++; } while (r > sqrt(yking[j][0])); wj1 = x[j-1]; wj = x[j]; w = wj1 + (r2-yking[j-1][0])*(wj-wj1)/(yking[j][0]-yking[j-1][0]); } } else { printf("radius too big\n"); } vmax = sqrt(2.0*w); do { speed = vmax*drand48(); fstar = pow(speed,2)*(exp(-0.5*pow(speed,2))-exp(-1.0*w)); } while (fstar < 2.0*drand48()/exp(1.0)); costh = 2.0*drand48()-1.0; phi = 2.0*PI*drand48(); sinth = sqrt(1.0-pow(costh,2)); ustar = speed*sinth*cos(phi); vstar = speed*sinth*sin(phi); wstar = speed*costh; mstar = star[i][0]; //printf("i: %i\tr=%g\tm=%.5f\tx=%.5f y=%.5f z=%.5f\tvx=%.5f vy=%.5f vz=%.5f\n",i,sqrt(r2),mstar,xstar,ystar,zstar,ustar,vstar,wstar); coord[i][0] = xstar; coord[i][1] = ystar; coord[i][2] = zstar; coord[i][3] = ustar; coord[i][4] = vstar; coord[i][5] = wstar; } for (i=0;i<N;i++) { for (j=0;j<3;j++) { star[i][j+1] = 1.0*coord[i][j]; star[i][j+4] = 1.0*coord[i][j+3]; } } } for (j=0;j<KMAX;j++) free (yp[j]); free(yp); for (j=0;j<N;j++) free (coord[j]); free(coord); return 0; }
void calc_soil_balance(fluxes *f, nrutil *nr, params *p, state *s, int soil_layer, double *water_lost) { // // Integrator for soil gravitational drainage // int nbad; /* N of unsuccessful changes of the step size */ int nok; /* N of successful changes of the step size */ int i, N = 1, max_iter; double eps = 1.0e-4; /* precision */ double h1 = .001; /* first guess at integrator size */ double hmin = 0.0; /* minimum value of the integrator step */ double x1 = 1.0; /* initial time */ double x2 = 2.0; /* final time */ /* value affecting the max time interval at which variables should b calc */ double soilpor = p->porosity[soil_layer]; double unsat, drain_layer, liquid, new_water_frac, change; //double *ystart = NULL; //ystart = dvector(1,N); for (i = 1; i <= N; i++) { nr->ystart[i] = 0.0; } /* unsaturated volume of layer below (m3 m-2) */ unsat = MAX(0.0, (p->porosity[soil_layer+1] - \ s->water_frac[soil_layer+1]) *\ s->thickness[soil_layer+1] / s->thickness[soil_layer]); /* soil water capacity of the current layer */ drain_layer = p->field_capacity[soil_layer]; liquid = s->water_frac[soil_layer]; /* ** initial conditions; i.e. is there liquid water and more ** water than layer can hold */ if (liquid > 0.0 && liquid > drain_layer) { // ystart is a vector 1..N, so need to index from 1 not 0 nr->ystart[1] = s->water_frac[soil_layer]; // Runge-Kunte ODE integrator used to estimate soil gravitational // drainage during each time-step odeint(nr->ystart, N, x1, x2, eps, h1, hmin, &nok, &nbad, unsat, drain_layer, p->cond1[soil_layer], p->cond2[soil_layer], p->cond3[soil_layer], nr, soil_water_store, rkqs); /* ystart is a vector 1..N, so need to index from 1 */ new_water_frac = nr->ystart[1]; /* convert from water fraction to absolute amount (m) */ change = (s->water_frac[soil_layer] - new_water_frac) * \ s->thickness[soil_layer]; // update soil layer below with drained liquid if (soil_layer+1 < p->n_layers) { f->water_gain[soil_layer+1] += change; } else { // We are draining through the bottom soil layer, add to runoff *water_lost += change; } f->water_loss[soil_layer] += change; } if (f->water_loss[soil_layer] < 0.0) { fprintf(stderr, "waterloss probem in soil_balance: %d %f\n", soil_layer, f->water_loss[soil_layer]); exit(EXIT_FAILURE); } //free_dvector(ystart, 1, N); return; }
int neutrinoFlux(double (* fvf)(double), int forSun, double* nu, double * Nu) { int i,n,err; double vcs0,vcs1; char lop[100]; double nu_[NZ],Nu_[NZ]; char *name, *aname; double pA0[2],pA5[2],nA0[2],nA5[2]; double R,Prop,Cr0,Cr1,Dv; double Veff; double rho,T; for(i=0;i<NZ;i++) nu[i]=Nu[i]=0; err=sortOddParticles(lop); // it also calculated by nucleonAmplitudes, but we need to know 'lop' if(err) return err; err=nucleonAmplitudes(FeScLoop,pA0,pA5,nA0,nA5); if(err) return err; Cr0=forSun? captureSun(fvf,pA0[0],nA0[0],pA5[0],nA5[0]):captureEarth(fvf, pA0[0],nA0[0],pA5[0],nA5[0]); if(pA0[0]==pA0[1] && nA0[0]==nA0[1] &&pA5[0]==pA5[1]&&nA5[0]==nA5[1]) Cr1=Cr0; else Cr1=forSun? captureSun(fvf,pA0[1],nA0[1],pA5[1],nA5[1]):captureEarth(fvf,pA0[1],nA0[1],pA5[1],nA5[1]); for(n=0;n<Nodd;n++) if(strcmp(lop,OddPrtcls[n].name)==0 || strcmp(lop,OddPrtcls[n].aname)==0 ) break; name=OddPrtcls[n].name; aname=OddPrtcls[n].aname; if(forSun) R=150E6; else R=6378.1; /* Distance to Sun/Earth in [km] */ Prop=31556925.2/(4*M_PI*R*R); /* for Year*km^2 */ vcs0= calcSpectrum0(name,aname,forSun, nu,Nu); { double r_,v_,r095,S,ph,Veff1; for(i=0,r_=0;i<10;i++) { T=polint2(r_/Rcm,nTab,rTab,tTab)*KelvinEv*1E-9; rho= polint2(r_/Rcm,nTab,rTab,rhoTab); r_= sqrt(6*T/(Gconst*100*rho*Mcdm))/M_PI; if(r_>Rcm) r_=Rcm; } //printf("r_/RS=%E\n", r_/Rcm); rho=polint2(r_/Rcm,nTab,rTab,rhoTab); T=polint2(r_/Rcm,nTab,rTab,tTab); r095=polint2(T*0.95,nTab,tTab,rTab); if(r095>1) r095=1; //printf("r095=%E\n",r095); T*=KelvinEv*1E-9; //printf("T=%E[GeV]\n",T); r095*=Rcm; Veff1=pow(r_*M_PI,3)/8; if(forSun) S=sigmaSun(pA0[0],nA0[0],pA5[0],nA5[0],r095*r095*r095); else S=sigmaEarth(pA0[0],nA0[0],pA5[0],nA5[0],r095*r095*r095); v_=sqrt(8*T/(M_PI*Mcdm)); //printf("v_=%E\n",v_); //printf("S/Veff1=%E\n",S/Veff1); ph=phiTab[0]*Mcdm/T; //printf(" Mcdm=%E T=%E phi[0]=%E\n",Mcdm,T,phiTab[0]); //printf("ph=%E\n",ph); ph=ph*exp(-ph); Ev[0]=v_*S/Veff1*ph*Vlight*100; //printf("S=%E (expected = cs[cm^2]* %E) , phi[0]=%E \n",S, 4./3.*M_PI*r095*r095*r095*150/mp_g, phiTab[0]); if(strcmp(name,aname)) { if(forSun)S=sigmaSun(pA0[1],nA0[1],pA5[1],nA5[1],r095); else S=sigmaEarth(pA0[1],nA0[1],pA5[1],nA5[1],r095); Ev[1]=v_*S/Veff1*ph; } //printf("Temperature New =%E Old=%E \n", T/(KelvinEv*1E-9), tTab[0]); //printf("rho New %E old %E\n", rho,rhoTab[0]); { // compare // double mu=Mcdm*mp_gev/(Mcdm+mp_gev); // double cs=mu*mu/M_PI*(12*pA5[0]*pA5[0]+ 4*pA0[0]*pA0[0])*3.8937966E8; //printf("cs=%E\n",cs); // printf("Evaporation New=%E Old=%E\n",Ev[0], cs/5.e-3*pow(10,-(3.5*Mcdm+4))); } Veff=pow(Gconst*100*rho*Mcdm/T/3,-1.5); // printf("Veff : new=%E old=%E\n",Veff, pow(Gconst*100*(150)*Mcdm/(tTab[0]*KelvinEv*1E-9)/3,-1.5) ); } if(strcmp(name,aname)) { double G01,G00,G11; double N[2]={0,0}; int err; vcs1=calcSpectrum0(name,name,forSun, nu_,Nu_); C[0]=Cr0/(1+exp(-dmAsymm)); C[1]=Cr1/(1+exp(dmAsymm)); An[0]=vcs0/Veff; An[1]=vcs1/Veff; err=odeint(N,2, 0 ,Etime , 1.E-3, Etime/10, deriv2); //printf("err=%d N={%E,%E}\n",err, N[0],N[1]); G00=0.5*An[1]*N[0]*N[0]; G11=0.5*An[1]*N[1]*N[1]; G01= An[0]*N[0]*N[1]; { /* symbolic solution for large Etime */ double alpha,beta,x,G01_,G00_,G11_; alpha=vcs1/vcs0; beta= Cr0/Cr1; x=(beta-1 + sqrt((beta-1)*(beta-1) + 4*beta*alpha*alpha))/(2*alpha); /* x= rho_particle/rho_antiparticle */ G01_=Cr0/(1+alpha*x); G00_=0.5*G01_*alpha*x; G11_=0.5*G01_*alpha/x; // printf("x=%E G00 = %E/%E G01 = %E/%E G11 = %E/%E\n",x, G00,G00_,G01,G01_,G11,G11_); } for(i=0;i<NZ;i++) { nu[i]=Prop*(G01*nu[i]+G00*nu_[i]+G11*Nu_[i]); Nu[i]=Prop*(G01*Nu[i]+G00*Nu_[i]+G11*nu_[i]); } } else { int err; double N=0; double rf; C[0]=Cr0; An[0]=vcs0/Veff; err=odeint(&N,1, 0 ,Etime , 1.E-3, Etime/10, deriv1); rf=0.5*An[0]*N*N*Prop; //printf("Rate Factor = %E(num.sol), =%E(formula)\n",rf, 0.5*Cr0*pow(tanh(Etime*sqrt(Cr0*vcs0/Veff)),2)*Prop); for(i=0;i<NZ;i++) { nu[i]*=rf; Nu[i]*=rf;} } return 0; }
int King_model(double w0, double rmin, double dlogr, int Nmax, double *radius, double *potential, double *mass) /* Purpose: This function will compute a king model of parameter w0 from rmin up to the tidal radius of the cluster, logarithmically stepping by dlogr. Arguments: double w0 - King parameter, the higher the deeper. double rmin - starting radius, will be radius[0], double dlogr - log radius bin int Nmax - Maximum number of points we want double *radius - Malloc'd (Nmax) array double *potential - Malloc'd (Nmax) array double *mass - Malloc'd (Nmax) array Returns: nrg - actual number of data points stored in the arrays */ { /* ERROR CONTROL */ double eps = 1e-6; /* MISC VARIABLES */ double sigma2=1.0; double den1=1.0; int i,j,nok,nbad,nk,nr,nrg; int nvar = 2, Nrmax = Nmax; double h1=1e-3, hmin = 1e-8; double r1, r2, rt, ppot, a,b; double oldpot1, oldpot2; double p,tote,totm,h,r0,p0,ss,d0; double pot[2]; double *den = ALLOC(Nrmax, double); double *dene = ALLOC(Nrmax, double); double *denm = ALLOC(Nrmax, double); double *dene2 = ALLOC(Nrmax, double); double *denm2 = ALLOC(Nrmax, double); double *der = ALLOC(Nrmax, double); double *v2 = ALLOC(Nrmax, double); pot[0] = w0 * sigma2; pot[1] = 0; r2 = rmin; /*-------------------------------------------------------------------- Integrate outward to tidal boundary. Store potential and density, and mass at every step. --------------------------------------------------------------------*/ for( nr=0; nr<Nrmax; nr++ ){ r1 = r2; r2 = pow(10, log10(r1)+dlogr); oldpot1 = pot[0]; oldpot2 = pot[1]; odeint( pot, nvar, r1, r2, eps, h1, hmin, &nok, &nbad, sigma2 , den1, potdir, rkqs); //printf("nr %d pot %le %le \n", nr, pot[0], pot[1]); if(pot[0] > 0){ /* Have not reached rt yet; store data and continue.*/ radius[nr] = r2; potential[nr] = pot[0]; mass[nr] = -pot[1]*r2*r2; p = pot[0]/sigma2; den[nr] = den1 * ( exp(p) * erf(sqrt(p)) - sqrt(4.*p/M_PI)*(1. +2.*p/3) ); }else{ if (pot[0] == 0){ break; } /* Have passed rt. Use bisection to find it.*/ for( i=0; i<20; i++ ){ pot[0] = oldpot1; pot[1] = oldpot2; rt = 0.5 * (r1+r2); odeint( pot, nvar, r1, rt, eps, h1, hmin, &nok, &nbad, sigma2 , den1, potdir, rkqs); if(pot[0] > 0){ r1 = rt; oldpot1 = pot[0]; oldpot2 = pot[1]; }else if(pot[0] < 0){ r2 = rt; }else{ break; } } radius[nr] = rt; potential[nr] = 0; mass[nr] = -pot[1]*r2*r2; den[nr] = 0; break; } if(den[nr] < 0) break; } nrg = nr; /*------------------------------------------------------------------- Compute total mass and energy. --------------------------------------------------------------------*/ for( nr=0; nr<nrg; nr++ ){ dene[nr] = radius[nr]*radius[nr] * den[nr] * potential[nr]; denm[nr] = radius[nr]*radius[nr] * den[nr]; } spline(radius, dene, nrg, 0, 2e30, dene2); spline(radius, denm, nrg, 0, 2e30, denm2); tote = 0; totm = 0; for( nr=0; nr<nrg-1; nr++ ){ h = radius[nr+1]-radius[nr]; tote = tote + 0.5*h*( dene[nr+1] + dene[nr] ) - cub(h)/24.*( dene2[nr+1] + dene2[nr] ); totm = totm + 0.5*h*( denm[nr+1] + denm[nr] ) - cub(h)/24.*( denm2[nr+1] + denm2[nr] ); } totm = 4.*M_PI*totm; tote = 2.*M_PI*tote + 0.5*totm*totm/radius[nrg-1]; tote = 0.5*tote; r0 = 4.*tote/sqre(totm); p0 = totm/(4.*tote); d0 = pow(totm,5)/cub(4.*tote); for( nr=0; nr<nrg; nr++ ){ radius[nr] = r0*radius[nr]; potential[nr] = p0*potential[nr]; mass[nr] = mass[nr]/totm; den[nr] = d0*den[nr]; } /*-------------------------------------------------------------------- Get the mean square velocity v2 as a function of radius. --------------------------------------------------------------------*/ /* for( nr=0; nr<nrg; nr++ ){ */ /* nk = 2; */ /* ppot = potential[nr]; */ /* a = 0; b = sqrt(2*ppot); */ /* ss = qromo(a, b, eps, kgvfnc, midpoint, nk, ppot, sigma2); */ /* v2[nr] = ss; */ /* nk = 0; */ /* ss = qromo(a, b, eps, kgvfnc, midpoint, nk, ppot, sigma2); */ /* v2[nr] = v2[nr]/ss; */ /* } */ free(v2); free(den); free(dene); free(denm); free(dene2); free(denm2); free(der); return nrg; }