def get_rlp(self, rlp): """ responds to list of rlp components and returns the values of data at the components :param rlp: array of (r,l,p) components to be probed :return: array of values coorosponding to the (r,l,p) components provided """ xyz = algc.sphere_to_cart(r=rlp[0], lam=rlp[1], phi=rlp[2]) return self.get_xyz(xyz=xyz)
def plot_shell_field_lines(self, lshell, num_lines=10): assert isinstance(lshell, ls.LShell) if isinstance(lshell.lines, dict): print("We have {} retained lines.".format( lshell.get_number_of_traces())) keys = lshell.lines.keys() keys = sorted(keys) for key in keys: if lshell.lines[key][0] is not None: l1 = lshell.lines[key][0] k = lshell.k b = lshell.b assert isinstance(l1, fl.FieldLine) gap = l1.__get_min_b_gap__(b=b, k=k) if gap > l1.error_tol: color = 'r' else: color = 'k' self.addFieldLine(lshell.lines[key][0], color=color, label="LShell Line") if lshell.lines[key][1] is not None: l1 = lshell.lines[key][1] k = lshell.k b = lshell.b assert isinstance(l1, fl.FieldLine) gap = l1.__get_min_b_gap__(b=b, k=k) if gap > l1.error_tol: color = 'r' else: color = 'k' self.addFieldLine(lshell.lines[key][1], color=color, label="LShell Line") else: print("Generating Drift Trajectory Plot") self.add_title( "Drift Trajectory for $B_{{mirror}} = {}$, $K = {}$".format( lshell.b, lshell.k)) drift_shell = lshell.get_drift_trajectory(num_lines) for line in drift_shell: self.addFieldLine(line=fl.FieldLine( data=lshell.data, start=algc.sphere_to_cart( r=line[0], lam=line[1], phi=line[2]))) self.ax.scatter(lshell.start[0], lshell.start[1], lshell.start[2], c='r', label="Start Point")
def __bisection_model(self): import scipy.interpolate as interp import ghostpy.algorithms.common as algc from ghostpy.algorithms import DipoleField as dpf ds = np.linspace(start=1.0, stop=55, num=2000) B = [] Ls = [] for L in ds: dipole_L = L Ls.append(dipole_L) loc = algc.sphere_to_cart(r=dipole_L, lam=0, phi=0) B.append(algc.mag(dpf.dipole_field(x=loc[0], y=loc[1], z=loc[2]))) B = np.array(B, dtype=np.float_) return interp.interp1d(B, Ls, kind='cubic')
def get_drift_trajectory_cart(self, res=100): assert res > 1, "Trajectory Resolution must be greater than 1." if len(self.lines) == 0: return None phis = np.linspace(start=0, stop=2 * np.pi, num=res - 1, endpoint=False) traj = [] for phi in phis: rlam = self.__lambda_at_phi__(phi=phi, get_r=True) # print ("rlam: {} for phi: {}".format(rlam, phi)) lam = rlam[1] r = rlam[0] # print ("Returned {} for phi = {}".format(lam, phi)) assert lam is not None, ("phi = {} returned None.".format(phi)) traj.append(np.array(algc.sphere_to_cart(r=r, lam=lam, phi=phi))) return np.array(traj)
def __search_B__(self, outerRE=15.0, innerRE=None, phi=0, direction=1): count = 0 eps = np.finfo(np.float32).eps # * 10 start_re = self.l_star(res=100) start_loc = algc.sphere_to_cart(r=start_re, lam=0, phi=phi) newLine = self.__trace_from_location__(loc=start_loc) assert newLine is not None, "No Line retrieved" ol = self.l_star(res=10) ib = self.data.get_trace_boundary() dob = 4.5 * ol dib = 0.25 * ol if dib < ib: dib = ib # print ("Epsilon: {}".format(eps)) # print ("Start RE: {}".format(start_re)) # print ("Footprint: {}".format(start_line.get_footprint_rlp(re=3.0))) # print ("Bottom South: {}".format(algc.cart_to_sphere(start_line.trace_s[-1]))) # print ("Bottom North: {}".format(algc.cart_to_sphere(start_line.trace_n[-1]))) # b = start_line.get_b(k=self.k) newRE = 0 if innerRE is None: innerRE = self.data.get_trace_boundary() innerRE = dib outerRE = dob innerRE = np.float32(innerRE) outerRE = np.float32(outerRE) orig_outerRE = outerRE orig_innerRE = innerRE outerLine = None innerLine = None outerGap = None innerGap = None post_found = False # print ("InnerRE: {}".format(innerRE)) # print ("OuterRE: {}".format(outerRE)) search_inner = False gap = None lw_old = 0 lw = -1 while outerRE - innerRE > eps: lw_old = lw # print ("LW OLD: {}".format(lw_old)) count += 1 # print ("Loop: {}".format(count)) if search_inner: newRE += 0.05 else: if outerGap is not None and innerGap is not None: ob = outerGap + self.b ib = innerGap + self.b # try: # ow = self.BL(ob) # iw = self.BL(ib) # cw= self.BL(self.b) # # except ValueError: ow = 1.0 iw = 0.0 cw = 0.5 # print ("OW: {}".format(ow)) # print ("CW: {}".format(cw)) # print ("IW: {}".format(iw)) safe = 1.0 lw = ((cw - iw) / (ow - iw)) * safe if np.isclose(lw, lw_old, atol=5e-2, rtol=0): lw = 0.5 if lw > 1: lw = 0.9 # # if count > 28: # lw = 0.5 # elif lw < 0.1: # lw = 0.1 # print ("LW: {}".format(lw)) newRE = innerRE + (outerRE - innerRE) * lw else: newRE = (outerRE + innerRE) / 2 # print ("newRE: {}".format(newRE)) # print("GAP: {}".format(gap)) if newRE < self.data.get_trace_boundary() and not search_inner: newRE = self.data.get_trace_boundary() * 1.05 search_inner = True newLoc = algc.sphere_to_cart(r=newRE, lam=0, phi=phi) newLine = self.__trace_from_location__(loc=newLoc) # newB = newLine.get_b(k=self.k) # print ("New B: {}".format(newB)) # # if newLine.m_trace is not None: # trace_m_idx = np.nanargmax(newLine.m_trace_re) # trace_coord = newLine.m_trace[trace_m_idx] # print("Trace Coordinate: {}".format(trace_coord)) # line_trace_coord = newLine.start # print ("Start Line: {}".format(line_trace_coord)) gap = newLine.__get_min_b_gap__(k=self.k, b=self.b) if gap is not None and np.isclose( gap, 0.0, atol=self.error_tol, rtol=0.0): print("Iterations to converge: {}".format(count)) return newLine, newLine # print ("Searching...") if gap is None: line_status = newLine.valid_code # print ("Line Status: {}".format(line_status)) if line_status == -2: outerRE = newRE newLine = None continue else: if gap < 0: outerRE = newRE newLine = None else: innerRE = newRE newLine = None continue elif gap > 0: innerRE = newRE if innerGap is None or gap < innerGap: # Move out innerLine = newLine newLine = None innerGap = gap else: outerRE = newRE if gap > outerGap: outerLine = newLine newLine = None outerGap = gap # Reverse Search Failed to get Value if gap is None and np.isclose(newRE, orig_outerRE, atol=eps, rtol=0): print("Line Failure: Outer Boundary for phi = {}".format(phi)) print("Inner Gap: {}".format(innerGap)) print("Outer Gap: {}".format(outerGap)) return None, None # Forward Search Failed to get Value if gap is None and np.isclose(newRE, orig_innerRE, atol=eps, rtol=0): print("Line Failure: Inner Boundary for phi = {}".format(phi)) print("Inner Gap: {}".format(innerGap)) print("Outer Gap: {}".format(outerGap)) return None, None # Check to see if point was bounded if outerGap is None or innerGap is None: print("Line Failure: No Bounds for phi = {}".format(phi)) print("Inner Gap: {}".format(innerGap)) print("Outer Gap: {}".format(outerGap)) return None, None print("Inner Gap: {}".format( innerLine.__get_min_b_gap__(k=self.k, b=self.b))) print("Outer Gap: {}".format( outerLine.__get_min_b_gap__(k=self.k, b=self.b))) print("Iterations to converge: {}".format(count)) return innerLine, outerLine
def __search_B_adaptive__(self, outerRE=30, innerRE=None, phi_0=0, ref_r=None, debug=False, tol=1e-4): ol = algc.mag(self.start) # ol = self.l(res=10) ib = self.data.get_trace_boundary() dob = 1.85 * ol dib = 0.65 * ol if dib < ib: dib = ib print("================") # initial values phi_in = phi_out = phi_c = self.normalize_phi(phi_0) eps = np.finfo(np.float32).eps newfp = self.get_raw_path() lam_0 = 0 # # if len(newfp) > 0: # lam_0 = 0.75 * newfp[0][1] # else: # return None, None print(lam_0) if ref_r is None: r_0 = r_c = self.l_star(res=100) else: r_0 = ref_r if debug is not None: stats = {} stats['tau_in'] = [] stats['tau_out'] = [] stats['tau'] = [] stats['loc_t'] = [] r_in = dib r_out = dob tau_in = None tau_out = None gap_out = None gap_in = None r_gap = r_out - r_in initcount = 0 while tau_in is None or tau_out is None and r_gap > eps: # print ("Main Bounds Loop") loc_t = algc.sphere_to_cart(r=r_c, lam=lam_0, phi=phi_c) tau = self.__trace_from_location__(loc_t) # if we don't have a returning trace, try again. if len(tau.trace_n) == 0 or not algc.mag( tau.trace_n[-1]) < tau.safe_boundry: if tau_out is not None: r_in = r_c else: r_out = r_c r_c = (r_in + r_out) / 2 initcount += 1 if initcount > 90: print("Out on init Count 1") break continue # check the footprint tau_fp = tau.get_footprint_rlp(re=self.calc_boundary) # check valid footprint if tau_fp is None or np.any(np.isnan(tau_fp)): # print ("Foot Print: {}".format(tau_fp)) # print ("Find out why a valid line is not giving a Foot print") return None, None # assert False # check phi_tau from both directions phi_gap, phi_tau = self.get_phi_gap(phi_0, tau_fp) # print("Phi Gap: {}".format(phi_gap)) if False: #not np.isclose(phi_gap, 0.0, rtol=0, atol=tol): if phi_gap > 0: phi_g_u = self.normalize_phi(phi_tau + phi_gap) phi_g_l = self.normalize_phi(phi_tau - phi_gap) else: phi_g_l = self.normalize_phi(phi_tau + phi_gap) phi_g_u = self.normalize_phi(phi_tau - phi_gap) pcount = 0 cthresh = 90 while not np.isclose(phi_gap, 0.0, rtol=0, atol=tol) and pcount < cthresh: # print ("Phi Loop 1") phi_c = self.normalize_phi((phi_g_l + phi_g_u) / 2) loc_t = algc.sphere_to_cart(r=r_c, lam=lam_0, phi=phi_c) tau = self.__trace_from_location__(loc=loc_t) tau_fp = tau.get_footprint_rlp(re=self.calc_boundary) phi_gap, phi_tau = self.get_phi_gap(phi_0, tau_fp) if phi_gap < 0: phi_g_l += phi_gap phi_g_l = self.normalize_phi(phi_g_l) else: phi_g_u += phi_gap phi_g_u = self.normalize_phi(phi_g_u) pcount += 1 if pcount > cthresh: print("Maximum Itterations on Initial Phi Search") break else: b_gap_tau = tau.__get_min_b_gap__(k=self.k, b=self.b) # print ("B Gap Initial: {}".format(b_gap_tau)) if b_gap_tau is not None and np.isclose( b_gap_tau, 0.0, rtol=0, atol=self.error_tol): print("Out with match.") return tau, tau if b_gap_tau is None: if gap_out is not None: # print ("No gap, moving back out") r_in = r_c elif gap_in is None and gap_out is None: # print ("Moving outer boundary in, searching for a valid point") r_out = r_c else: r_out = r_c if b_gap_tau > 0: if r_out >= dob: dob *= 1.5 r_out = dob r_in = 0.95 * r_c if r_in < ib: r_in = ib r_c = (r_in + r_out) / 2 print("Moving outer boundary out") continue r_in = r_c tau_in = tau gap_in = b_gap_tau elif b_gap_tau is not None: if r_in <= dib: dib *= 0.5 r_in = dib r_out = 1.1 * r_c if r_in < ib: r_in = ib r_c = (r_in + r_out) / 2 print("Moving inner boundary in") continue r_out = r_c tau_out = tau gap_out = b_gap_tau r_c = (r_in + r_out) / 2 r_gap = r_out - r_in # print("R Gap: {}".format(r_gap)) initcount += 1 # print ("Bounds Loop Count: {}".format(initcount)) if r_gap < eps: print("Out on EPS convergence") return None, None # break r_out = r_out #* 2.5 r_gap = r_out - r_in conv_count = 0 nan_count = 0 while r_gap > eps: # print ("Main Search Loop") r_c = (r_out + r_in) / 2 loc_t = algc.sphere_to_cart(r=r_c, lam=lam_0, phi=phi_c) tau = self.__trace_from_location__(loc=loc_t) tau_fp = tau.get_footprint_rlp(re=self.calc_boundary) phi_gap, phi_tau = self.get_phi_gap(phi_0, tau_fp) if False: # not np.isclose(phi_gap, 0.0, rtol=0, atol=tol): if phi_gap > 0: phi_g_u = self.normalize_phi(phi_tau + phi_gap) phi_g_l = self.normalize_phi(phi_tau - phi_gap) else: phi_g_l = self.normalize_phi(phi_tau + phi_gap) phi_g_u = self.normalize_phi(phi_tau - phi_gap) pcount = 0 while not np.isclose(phi_gap, 0.0, rtol=0, atol=tol): phi_c = self.normalize_phi((phi_g_l + phi_g_u) / 2) loc_t = algc.sphere_to_cart(r=r_c, lam=lam_0, phi=phi_c) tau = self.__trace_from_location__(loc=loc_t) tau_fp = tau.get_footprint_rlp(re=self.calc_boundary) phi_gap, phi_tau = self.get_phi_gap(phi_0, tau_fp) if phi_gap < 0: phi_g_l += (0.6 * phi_gap) phi_g_l = self.normalize_phi(phi_g_l) else: phi_g_u += (0.6 * phi_gap) phi_g_u = self.normalize_phi(phi_g_u) pcount += 1 if pcount > 90: # print ("Out on pcount") break b_gap_tau = tau.__get_min_b_gap__(k=self.k, b=self.b) # print ("sB_gap: {}".format(b_gap_tau)) if b_gap_tau is not None and np.isclose( b_gap_tau, 0.0, atol=self.error_tol): # print ("Returning on good find") # print("Relative B Error: {}".format(b_gap_tau)) return tau, tau if b_gap_tau is None or np.isnan(b_gap_tau): print("Bad Tau. Moving in.") r_out = (r_in + r_out) / 2 conv_count += 1 nan_count += 1 if nan_count > 50: # print ("NaN Count: {}".format(nan_count)) break continue if b_gap_tau >= 0: # print("Looking at Tau > 0") # print("gap_in: {}".format(gap_in)) # print("gap_out: {}".format(gap_out)) if b_gap_tau < gap_in: # print ("Saving Tau in with Gap: {}".format(b_gap_tau)) tau_in = tau gap_in = b_gap_tau if debug: stats['tau'].append(tau) else: pass # print ("Tau: {}".format(b_gap_tau)) r_in = r_c else: # print ("Looking at Tau < 0") # print("gap_in: {}".format(gap_in)) # print("gap_out: {}".format(gap_out)) if b_gap_tau > gap_out: # print ("Saving Tau Out with Gap: {}".format(b_gap_tau)) tau_out = tau gap_out = b_gap_tau if debug: stats['tau'].append(tau) else: pass # print ("Tau: {}".format(b_gap_tau)) r_out = r_c r_gap = r_out - r_in conv_count += 1 if debug: stats['tau_in'].append(tau_in) stats['tau_out'].append(tau_out) if conv_count > 150: print("Out on conv count") break if debug: return stats print("Relative B Error (IN): {}".format(gap_in)) print("Relative B Error (OUT): {}".format(gap_out)) return tau_in, tau_out
def get_rlp(self, rlp): xyz = algc.sphere_to_cart(r=rlp[0], lam=rlp[1], phi=rlp[2]) return self.get_xyz(xyz=xyz)