Beispiel #1
0
 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)
Beispiel #2
0
    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")
Beispiel #3
0
    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')
Beispiel #4
0
    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)
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
 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)