/*Funzione che calcola la distanza tra i centri di due sfere*/ double distanza( double *cx, double *cy, int n1, int n2 ) { double dist; dist = 0.0; dist = sqrt( prodscal( *(cx + n1) - *(cx + n2), *(cy + n1) - *(cy + n2), *(cx + n1) - *(cx + n2), *(cy + n1) - *(cy + n2) ) ); return dist; }
/*Funzione che calcola il tempo di collisione tra due sfere date le loro posizioni e velocità (e tenendo conto delle copie)*/ double tempocollisione( double *cx, double *cy, double *velx, double *vely, int ns, double d, int n1, int n2 ) { double t, r12[2], v12[2], discr, tempocopia[9], coordcopia[2], r12v12, mqv, mqr; int i1, i2, i3; t = 0.0; discr = 0.0; r12v12 = 0.0; mqv = 0.0; mqr = 0.0; i1 = 0; i2 = 0; i3 = 0; for( i1 = 0; i1 < 2; i1++ ) { r12[i1] = 0.0; v12[i1] = 0.0; coordcopia[i1] = 0.0; } for( i1 = 0; i1 < 9; i1++ ) { tempocopia[i1] = 0.0; } /*Si setta in partenza t = -1.0 (nessuna collisione)*/ t = -1.0; /*Con gli indici i1 e i2 si scorre sulle copie della particella n2, si calcolano i tempi di collisione e, se c'è un tempo di collisione diverso da -1.0 (infinito), allora quello è il tempo di collisione tra la sfera n1 e la sfera n2*/ for( i1 = -1; i1 < 2; i1++ ) { for( i2 = -1; i2 < 2; i2++ ) { coordcopia[0] = *(cx + n2) + (double)(i2); coordcopia[1] = *(cy + n2) + (double)(i1); r12[0] = *(cx + n1) - coordcopia[0]; r12[1] = *(cy + n1) - coordcopia[1]; v12[0] = *(velx + n1) - *(velx + n2); v12[1] = *(vely + n1) - *(vely + n2); r12v12 = prodscal(r12[0], r12[1], v12[0], v12[1]); mqv = prodscal(v12[0], v12[1], v12[0], v12[1]); mqr = prodscal(r12[0], r12[1], r12[0], r12[1]); discr = r12v12*r12v12 - mqv*( mqr - d*d ); if( ( r12v12 >= 0.0 )||( discr < 0.0 ) ) { tempocopia[i3] = -1.0; } else { tempocopia[i3] = - r12v12 - sqrt( discr ); tempocopia[i3] = tempocopia[i3]/mqv; if(tempocopia[i3] < 0.0) { printf("\nAttezione: tempo negativo. prodscal = %lf, discr = %lf, r12v12^2 = %lf, sqrt(mqr) = %lf, d = %lf\n", r12v12, discr, r12v12*r12v12, sqrt(mqr), d); } } i3 = i3 + 1; coordcopia[0] = 0.0; coordcopia[1] = 0.0; discr = 0.0; r12[0] = 0.0; r12[1] = 0.0; v12[0] = 0.0; v12[1] = 0.0; mqv = 0.0; mqr = 0.0; r12v12 = 0.0; } } /*Nel vettore tempocopia[i] ci sono i tempi di collisione di n1 con tutte le copie di n2. Il tempo di collisione tra n1 ed n2 sarà il minore tempo positivo nel vettore (oppure -1.0 se non ve ne è)*/ for( i1 = 0; i1 < 9; i1++ ) { if( tempocopia[i1] != -1.0 ) { if( t == -1.0 ) { t = tempocopia[i1]; } else { if( tempocopia[i1] < t ) { t = tempocopia[i1]; } } } } return t; }
/*Funzione che fa evolvere il sistema fino all'urto successivo, aggiorna le velocità delle particelle che collidono, aggiorna la matrice dei tempi e restituisce il tempo trascorso*/ double urto( double *coordinate_x, double *coordinate_y, double *velocita_x, double *velocita_y, double **matrice, int numero_sfere, double d, double *dvelx, double *dvely ) { double tm, congiungente[2], vel_relativa[2], ausiliario, delta[2]; int indice1, indice2, part1, part2; tm = 0.0; ausiliario = 0.0; indice1 = 0; indice2 = 0; for( indice1 = 0; indice1 < 2; indice1++ ) { congiungente[indice1] = 0.0; vel_relativa[indice1] = 0.0; delta[indice1] = 0.0; } /*Calcolo il tempo minimo nella matrice*/ tm = tempominimo( matrice, numero_sfere, &part1, &part2 ); /*Faccio evolvere il sistema con moto rettilineo uniforme*/ for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { *(coordinate_x + indice1) = *(coordinate_x + indice1) + *(velocita_x + indice1)*tm; *(coordinate_y + indice1) = *(coordinate_y + indice1) + *(velocita_y + indice1)*tm; } /*Impongo le condizioni di bordo periodiche*/ for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { while( *(coordinate_x + indice1) > 1.0 ) { *(coordinate_x + indice1) = *(coordinate_x + indice1) - 1.0; } while( *(coordinate_x + indice1) < 0.0 ) { *(coordinate_x + indice1) = *(coordinate_x + indice1) + 1.0; } while( *(coordinate_y + indice1) > 1.0 ) { *(coordinate_y + indice1) = *(coordinate_y + indice1) - 1.0; } while( *(coordinate_y + indice1) < 0.0 ) { *(coordinate_y + indice1) = *(coordinate_y + indice1) + 1.0; } } /*Sottraggo il tempo dell'urto alle entrate della matrice diverse da -1.0*/ for( indice1 = 1; indice1 < numero_sfere; indice1++ ) { for( indice2 = 0; indice2 < indice1; indice2++ ) { if( *(*(matrice + indice1) + indice2) != -1.0 ) { *(*(matrice + indice1) + indice2) = *(*(matrice + indice1) + indice2) - tm; } } } /*Tengo conto delle copie*/ if( modulo( *(coordinate_x + part1) - *(coordinate_x + part2) ) > 0.5 ) { if( *(coordinate_x + part1) - *(coordinate_x + part2) > 0.0 ) { delta[0] = 1.0; } if( *(coordinate_x + part1) - *(coordinate_x + part2) < 0.0 ) { delta[0] = -1.0; } } if( modulo( *(coordinate_y + part1) - *(coordinate_y + part2) ) > 0.5 ) { if( *(coordinate_y + part1) - *(coordinate_y + part2) > 0.0 ) { delta[1] = 1.0; } if( *(coordinate_y + part1) - *(coordinate_y + part2) < 0.0 ) { delta[1] = -1.0; } } /*Calcolo le componenti del versore congiungente e del vettore velocità relativa*/ congiungente[0] = *(coordinate_x + part1) - (*(coordinate_x + part2) + delta[0]); congiungente[1] = *(coordinate_y + part1) - (*(coordinate_y + part2) + delta[1]); ausiliario = prodscal( congiungente[0], congiungente[1], congiungente[0], congiungente[1] ); ausiliario = sqrt(ausiliario); congiungente[0] = congiungente[0]/ausiliario; congiungente[1] = congiungente[1]/ausiliario; ausiliario = 0.0; vel_relativa[0] = *(velocita_x + part1) - *(velocita_x + part2); vel_relativa[1] = *(velocita_y + part1) - *(velocita_y + part2); /*Metto l'opposto delle componenti della velocità relativa prima dell'urto in dvelx e dvely, in modo tale che sommando quelle dopo l'urto si ottenga la variazione della velocità relativa*/ *dvelx = -vel_relativa[0]; *dvely = -vel_relativa[1]; /*Aggiorno le componenti delle velocità*/ ausiliario = prodscal( vel_relativa[0], vel_relativa[1], congiungente[0], congiungente[1] ); *(velocita_x + part1) = *(velocita_x + part1) - ausiliario*congiungente[0]; *(velocita_y + part1) = *(velocita_y + part1) - ausiliario*congiungente[1]; *(velocita_x + part2) = *(velocita_x + part2) + ausiliario*congiungente[0]; *(velocita_y + part2) = *(velocita_y + part2) + ausiliario*congiungente[1]; /*Calcolo le componenti della velocità relativa DOPO l'urto*/ vel_relativa[0] = *(velocita_x + part1) - *(velocita_x + part2); vel_relativa[1] = *(velocita_y + part1) - *(velocita_y + part2); /*Calcolo la variazione delle componenti della velocità relativa prima e dopo l'urto (finale - iniziale)*/ *dvelx = *dvelx + vel_relativa[0]; *dvely = *dvely + vel_relativa[1]; ausiliario = prodscal( vel_relativa[0], vel_relativa[1], congiungente[0], congiungente[1] ); /*Aggiorno le entrate della matrice nelle righe/colonne corrispondenti alle particelle che hanno colliso*/ for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { *(*(matrice + part1) + indice1) = tempocollisione( coordinate_x, coordinate_y, velocita_x, velocita_y, numero_sfere, d, part1, indice1 ); } for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { *(*(matrice + indice1) + part1) = tempocollisione( coordinate_x, coordinate_y, velocita_x, velocita_y, numero_sfere, d, indice1, part1 ); } for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { *(*(matrice + part2) + indice1) = tempocollisione( coordinate_x, coordinate_y, velocita_x, velocita_y, numero_sfere, d, part2, indice1 ); } for( indice1 = 0; indice1 < numero_sfere; indice1++ ) { *(*(matrice + indice1) + part2) = tempocollisione( coordinate_x, coordinate_y, velocita_x, velocita_y, numero_sfere, d, indice1, part2 ); } return tm; }
double gmuon_(void) { /*compute the total g-2 from supersymmetry. Parameters are : Mmu : muon mass Mz : Z-boson's mass Mw : W-boson's mass s2thw : sin^2(thw) e : alpha modM1 & argM1 : modulus and argument of M1 modM2 & argM2 : modulus and argument of M2 modmu & argmu : modulus and argument of mu modAmu & argAmu : modulus and argument of Amu */ /*declaration des variables*/ double thw, cb,cw,sw, ymu, g1,masssneutr, g2,gmuo = 0,beta,Mz,Mw,Mmu,e,tbeta; matrix massmatrc,massmatrn,massmatrsmu; matrix Ncomp, Nconj,N,Ucomp,Uconj,U,Vcomp,Vconj,V,X,Xconj,Xcomp; vecteur massen,massec,massesmu; double coeff1 ,coeff2; matrix matrixtemp,matrixtemp2,matrixtemp3,matrixtemp4,matrixtemp5; my_complex nc1,nc2; int i,j; /*Memory Allocation*/ massmatrn=initm(4); massmatrc=initm(2); massmatrsmu=initm(2); Ncomp=initm(4); Nconj=initm(4); N=initm(4); Ucomp=initm(2); Vcomp=initm(2); X=initm(2); U=initm(2); V=initm(2); Uconj=initm(2); Vconj=initm(2); Xcomp=initm(2); Xconj=initm(2); massen=initv(4); massesmu=initv(2); massec=initv(2); matrixtemp=initm(2); matrixtemp2=initm(2); matrixtemp3=initm(4); matrixtemp4=initm(4); matrixtemp5=initm(4); /*Get the values for the masses and mixing matrices*/ e=sqrt(4*M_PI*0.00781653); sw=0.48076; Mz=91.1876; Mmu=0.1057; findVal("tB",&tbeta); beta = atan(tbeta); cb = cos(beta); thw=asin(sw); cw=cos(thw); Mw=Mz*cw; g1 = e/cw; g2 = e/sw; ymu = g2 * Mmu / (sqrt(2)*cb*Mw); findVal("MNE1",&massen.e[0].r); findVal("MNE2",&massen.e[1].r); findVal("MNE3",&massen.e[2].r); findVal("MNE4",&massen.e[3].r); findVal("MC1",&massec.e[0].r); findVal("MC2",&massec.e[1].r); findVal("MSnm",&masssneutr); findVal("Zn11",&Nconj.e[0][0].r); findVal("Zn12",&Nconj.e[1][0].r); findVal("Zn13",&Nconj.e[2][0].r); findVal("Zn14",&Nconj.e[3][0].r); findVal("Zn21",&Nconj.e[0][1].r); findVal("Zn22",&Nconj.e[1][1].r); findVal("Zn23",&Nconj.e[2][1].r); findVal("Zn24",&Nconj.e[3][1].r); findVal("Zn31",&Nconj.e[0][2].r); findVal("Zn32",&Nconj.e[1][2].r); findVal("Zn33",&Nconj.e[2][2].r); findVal("Zn34",&Nconj.e[3][2].r); findVal("Zn41",&Nconj.e[0][3].r); findVal("Zn42",&Nconj.e[1][3].r); findVal("Zn43",&Nconj.e[2][3].r); findVal("Zn44",&Nconj.e[3][3].r); findVal("Zu11",&Uconj.e[0][0].r); findVal("Zu12",&Uconj.e[1][0].r); findVal("Zu21",&Uconj.e[0][1].r); findVal("Zu22",&Uconj.e[1][1].r); findVal("Zv11",&Vcomp.e[0][0].r); findVal("Zv12",&Vcomp.e[0][1].r); findVal("Zv21",&Vcomp.e[1][0].r); findVal("Zv22",&Vcomp.e[1][1].r); { double MSmuLL,MSmuRR,MSmuLR,Am,mu,MSmuth; MSmuLL=findValW("MSmL"); MSmuLL*=MSmuLL; MSmuRR=findValW("MSmR"); MSmuRR*=MSmuRR; Am=findValW("Am"); mu=findValW("mu"); MSmuLR=(Am-mu*tbeta)*Mmu; massesmu.e[0].r=sqrt((MSmuLL+MSmuRR-sqrt((MSmuLL-MSmuRR)*(MSmuLL-MSmuRR)+4*MSmuLR*MSmuLR))/2); massesmu.e[1].r=sqrt((MSmuLL+MSmuRR+sqrt((MSmuLL-MSmuRR)*(MSmuLL-MSmuRR)+4*MSmuLR*MSmuLR))/2); MSmuth=atan2(-2*MSmuLR, -MSmuLL+MSmuRR)/2; X.e[0][0].r=cos(MSmuth); X.e[0][1].r=sin(MSmuth); X.e[1][0].r=-X.e[0][1].r; X.e[1][1].r=X.e[0][0].r; } for(i=0;i<4;i++) if (massen.e[i].r<0) {for(j=0;j<4;j++) {Nconj.e[j][i]=prod(icomp,Nconj.e[j][i]); } massen.e[i].r=-massen.e[i].r; } for(i=0;i<2;i++) {if (massec.e[i].r<0) {for(j=0;j<2;j++) { Uconj.e [j][i]=prod(icomp,Uconj.e[j][i]); Vcomp.e [i][j]=prod(icomp,Vcomp.e[i][j]); } massec.e[i].r=-massec.e[i].r; } if (massesmu.e[i].r<0) {for(j=0;j<2;j++) {X.e [i][j]=prod(icomp,X.e[i][j]); } massesmu.e[i].r=-massesmu.e[i].r; } } N=adj(Nconj); U=adj(Uconj); /*Compute the coefficients entering the formula for the neutral and chargino contribution to g-2_muon and calculates gmuon*/ /*neutralinos*/ for ( i=0;i<4;i=i+1) for ( j=0;j<2;j=j+1) {nc1=somme(prodscal(sqrt(2)*g1,prod(N.e[i][0],X.e[j][1])),prodscal(ymu,prod(N.e[i][2],X.e[j][0]))); nc2=diff(prodscal(1/sqrt(2),prod(somme(prodscal(g2,N.e[i][1]),prodscal(g1,N.e[i][0])),conjug(X.e[j][0]))),prodscal(ymu,prod(N.e[i][2],conjug(X.e[j][1])))); coeff1 =(somme(prod(nc1,conjug(nc1)),prod(nc2,conjug(nc2)))).r; coeff2 = prod(nc1,nc2).r; if (massesmu.e[j].r<1e-8) {return 0; printf("erreur : Mass smuons nul\n");} gmuo=gmuo+calcgmuon (0,Mmu, massen.e[i].r, massesmu.e[j].r,coeff1, coeff2); } /*charginos*/ for (j=0;j<2;j=j+1) { nc1=prodscal(ymu,U.e[j][1]); nc2=prodscal(-g2,conjug(Vcomp.e[j][0])); coeff1 =(somme(prod(nc1,conjug(nc1)),prod(nc2,conjug(nc2)))).r; coeff2 = prod(nc1,nc2).r; if (masssneutr<1e-8) {return 0; printf("erreur : Mass sneutrinos nul\n");} gmuo=gmuo+calcgmuon (1,Mmu, massec.e[j].r, masssneutr,coeff1, coeff2); } return gmuo; }