def fdelx( vpara, v, vi, B, e, Egg ): # time the electron moves (De/v), angular vel (v/R), speed of el (v,vi) , mag field B, charge e (+/- 1) # w2,tau2=w,tau if gv.STODE == 1: w2 = gv.drawMFPe(Egg, gv.zE(gv.dS)) / v else: w2 = gv.De(gv.zE(gv.dS), gv.Ee(Egg, gv.zE(gv.dS))) / v tau2 = v * 1.0 / gv.R(gv.Ee(Egg, gv.zE(gv.dS)), gv.B0, gv.zE(gv.dS)) return v * (vpara * (tau2 - np.sin(w2 * tau2) / w2) * B + vi * np.sin(w2 * tau2) / w2 + e * (np.cos(w2 * tau2) - 1.0) * np.cross(B, vi) / w2)
def F(angles): x, y, z = getxyzB(dg, dE, angles) fB = B(x, y, z) bnorm = np.sqrt(fB[0] * fB[0] + fB[1] * fB[1] + fB[2] * fB[2] + 1e-20) if RnB: w = bnorm / (RnB * 1e-14) else: w = 1.0 / gv.R(gv.Ee(Egg, gv.zE(gv.dS)), bnorm, gv.zE(gv.dS)) wtau = w * tau cons1 = fLoS(angles[0], angles[2], dg, dE) cons2 = fvcBdphi( fBz(fB, angles[0], angles[1]), fBrho(fB, angles[0], angles[1]), angles[2], angles[0], ) cons3 = fdeltaEqn(angles[2], fvpara(fB / bnorm, angles[0], angles[1], angles[2]), Egg, wtau) return (cons1, cons2, cons3)
def fsolvecsq_stable( dg, dE, Egg, tG, pG, deltaG, ranget, Morp=False, xtol=1e-10, tau=False, RnB=False ): # Solves the Constraints - quite stable, but can jump to other branches anglesG = np.array([tG, pG, deltaG]) x, y, z = getxyzB(dg, dE, anglesG) if not tau: if gv.STODE == 1 and not Morp: tau = gv.drawMFPe(Egg, gv.zE(gv.dS)) else: tau = gv.De(gv.zE(gv.dS), gv.Ee(Egg, gv.zE(gv.dS))) w = 1.0 / gv.R(gv.Ee(Egg, gv.zE(gv.dS)), gv.B0, gv.zE(gv.dS)) wtau = w * tau def F(angles): x, y, z = getxyzB(dg, dE, angles) fB = B(x, y, z) bnorm = np.sqrt(fB[0] * fB[0] + fB[1] * fB[1] + fB[2] * fB[2] + 1e-20) if RnB: w = bnorm / (RnB * 1e-14) else: w = 1.0 / gv.R(gv.Ee(Egg, gv.zE(gv.dS)), bnorm, gv.zE(gv.dS)) wtau = w * tau cons1 = fLoS(angles[0], angles[2], dg, dE) cons2 = fvcBdphi( fBz(fB, angles[0], angles[1]), fBrho(fB, angles[0], angles[1]), angles[2], angles[0], ) cons3 = fdeltaEqn(angles[2], fvpara(fB / bnorm, angles[0], angles[1], angles[2]), Egg, wtau) return (cons1, cons2, cons3) sol, o1, ier, o2 = opt.fsolve(F, anglesG, xtol=xtol, full_output=1) charge = 1 # initialize the charge variable, now look what charge this has to be. if gv.chargeanalyze == 1: xvec = getxyz(dg, dE, sol) Bvec = B(xvec[0], xvec[1], xvec[2] + dE) orientation = np.dot(xvec, np.cross(fvi(sol[0], sol[1], sol[2]), Bvec)) temp = np.dot(Bvec, fvi(sol[0], sol[1], sol[2])) / np.linalg.norm(Bvec) r = int(np.floor(wtau / (np.pi * np.power(1 - temp * temp, 0.5)))) % 2 if orientation >= 0: # the electron initially moves towards us if r == 0: # electron must be the lepton charge = -1 else: # positron must be the lepton charge = 1 if orientation < 0: # the electron initially moves away from us if r == 0: # positron must be the lepton charge = 1 else: # electron must be the lepton charge = -1 return sol, ier, charge