double Srbs_mc(double z1,double z2,double t,double E) { double value; value = ipow2((z1*z2*P_E*P_E)/(4.0*PI*P_EPS0))*ipow2(1.0/(4.0*E))* ipow(1.0/sin(t/2.0),4); return(value); }
double mc2lab_scatc(double mcs,double tcm,double t) { double value; value = (mcs*ipow2(sin(tcm)))/(ipow2(sin(t))*cos(tcm - t)); return(value); }
int main(int argc, char* argv[]) { int xx = 3; if (getenv("NUMBER_NOT_USED")) xx = atoi(getenv("NUMBER_NOT_USED")); int kk = POW; if (getenv("NUMBER_TO_IGNORE")) kk = atoi(getenv("NUMBER_TO_IGNORE")); int zz = 50 * 1000 * 1000; if (getenv("ITERS")) zz = atoi(getenv("ITERS")); cake_timer tm; cake_timer_reset(&tm); int yy = xx; for (int ii = 0; ii < zz; ++ii) { yy = ipow2(yy, kk); } double secs = cake_timer_read(&tm); printf("%d^%d (%d) = %d\n", xx, kk, zz, yy); printf("time: %.04f\n", secs); return 0; }
Point coord_transform(Point porig,double theta,double fii,Point pin,int flag) { /* * This routine will calculate the cartesian coordinates of point pin * in another coordinate system. The origin of pin system in this * other system is given by point porig. The rotation angles of pin * system is given by theta and fii. * Flag says which way the conversion is done. */ Point pout; double r,in_theta,in_fii,out_theta,out_fii; if(flag == BACK){ pin.x -= porig.x; pin.y -= porig.y; pin.z -= porig.z; } r = sqrt(ipow2(pin.x) + ipow2(pin.y) + ipow2(pin.z)); if(r == 0.0){ pout = porig; return(pout); } in_theta = acos(pin.z/r); in_fii = atan2(pin.y,pin.x); rotate(theta,fii,in_theta,in_fii,&out_theta,&out_fii); pout.x = r*sin(out_theta)*cos(out_fii); pout.y = r*sin(out_theta)*sin(out_fii); pout.z = r*cos(out_theta); if(flag == FORW){ pout.x += porig.x; pout.y += porig.y; pout.z += porig.z; } return(pout); }
double Serd(int z1,double m1,int z2,double m2,double t,double E, enum cross_section cs) /* t is recoil angle in lab, E lab energy of incident particle */ { double E_cm = m2*E/(m1+m2); double t_sc=PI-2*t; double sigma_r = ipow2(z1*z2*P_E*P_E/(8*PI*P_EPS0*E))*ipow2(1.0 + m1/m2)/ipow(cos(t),3); double F; switch(cs) { case CS_RUTHERFORD: default: F=1.0; break; case CS_ANDERSEN: F=Andersen(z1, z2, E_cm, t_sc); break; case CS_LECUYER: F=Lecuyer(z1, z2, E_cm); break; } return(F*sigma_r); }
double get_cross(Ion *ion,Scattering *scat) { /* * Interpolate the cross section ie. the maximum impact parameter * for current ion energy. * */ double b,e; int i; e = log(ion->E*scat->E2eps); /* * Check that the maximum impact parameter does not exceed the half of the * atom distance. (Actually we do not do it here). */ i = (int) ((e - scat->cross.emin)/scat->cross.estep); b = scat->cross.b[i] + (scat->cross.b[i+1] - scat->cross.b[i])* (e - (i*scat->cross.estep + scat->cross.emin))/scat->cross.estep; b *= scat->a; b = PI*ipow2(b); if(!(b > 0 && b < 1e-15)){ fprintf(stderr,"%e\n",b); fprintf(stderr,"%i %g %g\n",i,ion->E,scat->E2eps); fprintf(stderr,"%g %g %g\n",e,scat->cross.emin,scat->cross.estep); fprintf(stderr,"%g %g %g\n",scat->cross.b[i],scat->cross.b[i+1],scat->a); } return(b); }
uint32_t numColsAtLevel(uint32_t level) const { return ipow2(level) * m_nc0; }
uint32_t numRowsAtLevel(uint32_t level) const { return ipow2(level) * m_nr0; }
void read_events(General *general,Measurement *meas,Event *event, Concentration *conc) { FILE *fp; char buf[NLINE],type[TYPELEN]; double x,y,E,M,w; int c,Z,A,n,i=0,cont=TRUE,j,k; if(!strncmp(general->eventfile,"-",1) && strlen(general->eventfile) == 1) fp = stdin; else fp = fopen(general->eventfile,"r"); if(fp == NULL){ fprintf(stderr,"Could not open file %s\n",general->eventfile); exit(1); } while(fgets(buf,NLINE,fp) != NULL && cont){ c = sscanf(buf,"%lf %lf %lf %i %lf %s %lf %i", &x,&y,&E,&Z,&M,type,&w,&n); if(c != 8){ fprintf(stderr,"Problems at input line %i\n",i+1); } if(i < MAXEVENTS){ event[i].theta = meas->detector_angle + x; event[i].fii = y; event[i].E = E*C_MEV; event[i].Z = Z; #ifdef DEBUG printf("%5i %10.3f %10.3f\n",Z,event[i].theta/C_DEG,event[i].E/C_MEV); #endif event[i].M = M*C_U; event[i].A = (int) (M + 0.5); A = event[i].A; event[i].w0 = w; event[i].w = w/ipow2(Z*(1.0 + meas->M/event[i].M)); event[i].n = n; event[i].v = sqrt(2.0*event[i].E/event[i].M); if(event[i].v > general->vmax) general->vmax = event[i].v; event[i].d = 0.0; k = (int) (event[i].d/conc->dstep); conc->w[Z][k] += event[i].w; conc->n[Z][k] ++; conc->wsum[k] += event[i].w; conc->nsum[k] ++; (general->element[Z])++; (general->nuclide[Z][A])++; general->M[Z] = M*C_U; if(!strncmp(type,"ERD",TYPELEN)){ event[i].type = ERD; } else if(!strncmp(type,"RBS",TYPELEN)){ event[i].type = RBS; } else { fprintf(stderr,"Event type neither ERD nor RBS!\n"); exit(2); } i++; } else { cont = FALSE; fprintf(stderr,"Too many events, reading stopped at line %i\n",i+1); } } fclose(fp); general->nevents = i; /* We calculate the number of different isotopes for each element */ for(i=0;i<general->maxelements;i++){ for(j=1;j<general->maxnucmasses;j++) if(general->nuclide[i][j] > 0) (general->nuclide[i][0])++; } fprintf(stderr,"%i events read\n",general->nevents); }
double Andersen(int z1, int z2, double E, double theta) { /* E in CM coordinates, theta is scattering angle (of scattered particle) in CM also */ double r_VE=48.73*C_EV*z1*z2*sqrt(pow(z1,2.0/3)+pow(z2,2.0/3))/E; double F=ipow2(1+0.5*r_VE)/ipow2(1+r_VE+ipow2(0.5*r_VE/(sin(theta/2.0)))); return F; }
void calculate_recoil_depths(General *general,Measurement *meas,Event *event, Stopping *sto,Concentration *conc) { double K,dmult,recE,beamE,d,dstep,M,dE=0,w,bk,rk; int Z,id,ie; for(ie=0;ie<general->nevents;ie++){ Z = event[ie].Z; M = event[ie].M; dmult = 1.0/sin(event[ie].theta - meas->target_angle); if(event[ie].type == ERD) K = (4.0*meas->M*event[ie].M*ipow2(cos(event[ie].theta)))/ ipow2(meas->M + event[ie].M); else { /* RBS */ K = sqrt(ipow2(event[ie].M) - ipow2(meas->M*sin(event[ie].theta))); K += meas->M*cos(event[ie].theta); K /= (meas->M + event[ie].M); K = ipow2(K); } d = 0.0; id = 0; dstep = conc->dstep; recE = event[ie].E; beamE = conc->Ebeam[0]*K; if(recE >= beamE){ dE = get_eloss(general, Z,M,recE,d,dstep*dmult,sto); rk = dE/dstep; bk = (conc->Ebeam[id+1]*K - conc->Ebeam[id]*K)/dstep; event[ie].d = 0.5*(d - dstep) + (conc->Ebeam[id]*K - (recE - dE))/(rk - bk); beamE = conc->Ebeam[0]; #ifdef DEBUG printf("A %8i %10.3f\n",Z,event[ie].d/(1.0e15/C_CM2)); #endif } else { while((id < general->maxdstep) && (recE < beamE)){ if(event[ie].type == ERD) dE = get_eloss(general, Z,M,recE,d,dstep*dmult,sto); else dE = get_eloss(general, meas->Z,meas->M,recE,d,dstep*dmult,sto); recE += dE; id++; d += dstep; beamE = conc->Ebeam[id]*K; } if(id < general->maxdstep){ bk = (beamE - conc->Ebeam[id-1]*K)/dstep; rk = dE/dstep; event[ie].d = (d - dstep) + (conc->Ebeam[id-1]*K - (recE - dE))/(rk - bk); recE = (recE - dE) + rk*(event[ie].d - (d - dstep)); } beamE = conc->Ebeam[id] + (event[ie].d - id*dstep)* (conc->Ebeam[id] - conc->Ebeam[id-1])/dstep; #ifdef DEBUG printf("B %8i %10.3f\n",Z,event[ie].d/(1.0e15/C_CM2)); #endif } if(id < general->maxdstep){ if(event[ie].type == ERD){ w = Serd(meas->Z,meas->M,event[ie].Z,event[ie].M,event[ie].theta,beamE, general->cs); } else { w = Srbs(meas->Z,meas->M,event[ie].Z,event[ie].M,event[ie].theta,beamE, general->cs); } event[ie].w = event[ie].w0/w; #ifdef DEBUG printf("W %i %10.4f %10.4f\n",event[ie].type,w/C_BARN,beamE/C_MEV); printf("%3i %14.5e %14.5e\n",Z,(event[ie].d*C_CM2)/1.0e15,event[ie].w); #endif if(event[ie].d < 0.0) id = 0.0; else id = (int) (event[ie].d/conc->dstep); conc->w[Z][id] += event[ie].w; conc->n[Z][id] ++; conc->wsum[id] += event[ie].w; conc->nsum[id] ++; } else { event[ie].w = 0.0; } } }