示例#1
0
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);
}
示例#2
0
文件: neutrino.c 项目: Omer80/wimps
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);
}
示例#3
0
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;
}
示例#4
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];
}
示例#5
0
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 */
}
示例#6
0
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;
  }   
}
示例#7
0
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;
}
示例#8
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];
}
示例#9
0
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);
}
示例#10
0
文件: make_king.c 项目: lysj9/fractal
//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;
	

}
示例#11
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;
}
示例#12
0
文件: neutrino.c 项目: Omer80/wimps
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;
}
示例#13
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;
}