def __init__(self, beta, xi=None, xmin=None, method='match head to tail'): """`xmin` is minimum x value of natural matching point. If `x_m` < `xmin`, then the matching point will be forced to be `xmin`""" # # Set head parameters # self.A_h = A(beta, xi) self.theta_h = theta_c(beta, xi) self.sig_h = np.sign(self.theta_h) self.tau_h = np.tan(np.abs(self.theta_h)) self.a_h = self.A_h/self.tau_h**2 self.x0_h = 1.0 - self.sig_h*self.a_h self.head_conic = Conic(A=self.A_h, th_conic=np.degrees(self.theta_h)) self.t_h = self.head_conic.make_t_array() # # Set tail parameters # # Distance to other star in units of R0 self.D = (1 + np.sqrt(beta)) / np.sqrt(beta) if xi == None: # Opening angle of tail self.theta_t = theta_tail(beta, xi, f=finf_CRW) # This was formerly known as phi1_over_phi self.J = phi_ratio_CRW(beta, self.theta_t) self.K = K_func_CRW(beta, self.theta_t, self.J) # Empirically determined correction factor self.K *= 0.5*self.J*(1.0 + beta) else: self.theta_t = theta_tail(beta, xi, f=finf) self.J = phi_ratio_anisotropic(beta, xi, self.theta_t) self.K = K_func_anisotropic(beta, xi, self.theta_t, self.J) self.tau_t = np.tan(self.theta_t) self.T = (self.tau_h/self.tau_t)**2 self.R90 = B(beta, xi) self.m90 = m90_func(beta, xi) if method == 'match R90 and gradient': # New 30 Sep 2016 - fit tail to y, dy/dx @ 90 deg, instead # of to head conic self.x0_t = self.R90*self.m90 / self.tau_t**2 self.a_t = np.sqrt(self.x0_t**2 - (self.R90/self.tau_t)**2) self.x_m = 0.0 # for completeness, but we don't use it elif method == 'match head to tail': # Original method, that I am not satisfied with (30 Sep 2016) # Center of tail hyperbola in units of R_0 self.x0_t = self.D / (1.0 + self.J) # New 30 Aug 2016 # Scale of hyperbola now determined from the K coefficient # self.a_t = self.x0_t*a_over_x(self.tau_t, self.J, self.K) # Find the x value where two conics match in dy/dx self.x_m = (self.x0_t + self.sig_h*self.T*self.x0_h) / (1 + self.sig_h*self.T) if xmin is not None: # and self.x_m < xmin: # 30 Aug 2016: Match at x = xmin if gradients would naturally # match at a more negative value of x self.x_m = xmin # And throw away the previous value of x0_t so that we can # force y and dy/dx to match at x=xmin self.x0_t = (1 + self.sig_h*self.T)*xmin - self.sig_h*self.T*self.x0_h # Major and minor axes of tail hyperbola self.a_t = np.sqrt( (self.x_m - self.x0_t)**2 - self.T*np.abs(self.a_h**2 - (self.x_m - self.x0_h)**2) ) elif method == 'match R90 and asymptote': # Hyperbola center depends on asymptote only self.x0_t = self.D / (1.0 + self.J) self.a_t = np.sqrt(self.x0_t**2 - (self.R90/self.tau_t)**2) self.x_m = 0.0 else: raise NotImplementedError('Unknown match method: "{}"'.format(method)) self.t_t = np.linspace(0.0, max(2.0, 10.0/self.a_t), 500)
figfilename = sys.argv[0].replace('.py', '.pdf') fig, axes = plt.subplots(nxi, nbeta, sharex=True, sharey=True) for j, xi in enumerate(xigrid): for i, beta in enumerate(betagrid): ax = axes[j, i] # Geberalized CRW solution R_crw = R_from_theta(theta, beta, xi) x_crw = R_crw*np.cos(theta) y_crw = R_crw*np.sin(theta) # Matched conic parameters A = conic_parameters.A(beta, xi) th_conic = np.degrees(conic_parameters.theta_c(beta, xi)) c = Conic(A=A, th_conic=th_conic) t = c.make_t_array() x_con = c.x(t) y_con = c.y(t) # Hyperbola fit to tail th_tail = np.degrees(conic_parameters.theta_tail(beta, xi)) # First draw the asymptote D = (1 + np.sqrt(beta))/np.sqrt(beta) b_a = np.tan(np.radians(th_tail)) x_cone = np.linspace(-10*D, 10*D, 3) y_cone = -b_a*(x_cone - 0.5*(1 + np.sqrt(beta))*D) print(th_tail, b_a, x_cone, y_cone)
# Step 2: Initialize arrays print(CRW) beta = [5e-4, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1] sns.set_style("ticks") colors = sns.color_palette("Blues", len(beta)) inc = np.linspace(0, 75, 100) # print(inc) # step 3: Beta loop for plotting for b, c in zip(beta, colors): th_inf = theta_infty(b, Xi, CRW) imax = np.degrees(np.arctan(-1.0 / np.tan(th_inf))) imask = inc <= imax conic = Conic(A=A(b, Xi), th_conic=np.degrees(theta_c(b, Xi))) print(r"$\beta={}$".format(b), imax) q_prime = q(b) * conic.g(inc[imask]) A_prime = conic.Aprime(inc[imask]) plt.plot( q_prime, A_prime, linestyle="-", linewidth=2.0, color=c, label=r"$\beta={}${}$\theta_c={:.0f}^\circ$".format(b, "\n", np.degrees(theta_c(b, Xi))), ) every15 = np.zeros(q_prime.shape, dtype=bool) for thisinc in 0.0, 15.0, 30.0, 45.0, 60.0, 75.0: iclosest = np.argmin(np.abs(inc[imask] - thisinc)) every15[iclosest] = True