Example #1
0
    def add_satellite(self,satpot,sat,df_prop,integ=False,ftype='rotate',
                      rotFreq=1.,zsun='mean',tdep=True,method='slow'):

        turn_physical_off(satpot)
        sat.turn_physical_off()
        self.t= sat.time()

        #Check if the satellite has the same time array as the disc orbits
        if (len(self.t) != len(self.tt)) or (np.array(self.t)!=np.array(self.tt)).any():
            self.discOrb= self.integOrbits(self.t)
        else:
            pass

        if method!='slowest':

            if ftype=="static":
                force= self.statSatForce(satpot,sat,tdep,method=method)
            else:
                try:
                    if (rotFreq.unit==u.km/u.s/u.kpc):
                        rotFreq= rotFreq.value/27.5
                    else:
                        rotFreq= rotFreq.to(u.km/u.s/u.kpc)
                        rotFreq= rotFreq.value/27.5
                except:
                    pass
                force= self.rotSatForce(satpot,sat,rotFreq,tdep,method=method)

            self.add_force(force,self.t,df_prop,integ=integ,rotFreq=rotFreq,zsun=zsun,
                           tdep=tdep,method=method)

            return None
        elif method=='slowest':

            dJ= np.zeros([self.znpt,self.vnpt,len(self.t)])
            for i in tqdm.trange(self.znpt):
                #Calculate the force
                if ftype=="static":
                    force= self.statSatForce(satpot,sat,tdep,method=method,tstep=i)
                else:
                    try:
                        if (rotFreq.unit==u.km/u.s/u.kpc):
                            rotFreq= rotFreq.value/27.5
                        else:
                            rotFreq= rotFreq.to(u.km/u.s/u.kpc)
                            rotFreq= rotFreq.value/27.5
                    except:
                        pass
                    force= self.rotSatForce(satpot,sat,rotFreq,tdep,method=method)

                #Calculate deltaJ
                dJ[i]= self.calc_dJ(force,integ,tdep,method,tstep=i)

            self.deltaJ= dJ

            #calculate the perturbation (skip the add_force step)
            self.calc_pert(self.deltaJ,self.t,df_prop,integ=integ,rotFreq=rotFreq,zsun=zsun,
                           tdep=tdep,method=method)
            return None
Example #2
0
def MWPotentialSCFbar_nogrow(mbar,Acos,Asin,rs=1.,normalize=False,pat_speed=40.,fin_phi_deg=27.,t_stream_age=5.):
    
    a=rs/ro
    omegaP=pat_speed*(ro/vo)
    
    fin_phi= np.radians(fin_phi_deg)
    #init_phi= fin_phi - o_p*(tpal5age*Gyr_to_s)
    
    init_phi= fin_phi - omegaP*t_stream_age/bovy_conversion.time_in_Gyr(vo,ro)
    
    mrat=mbar/10.**10. #10^10 mass of bar used to compute Acos and Asin
    
    static_bar=potential.SCFPotential(amp=mrat,Acos=Acos,Asin=Asin,a=a,normalize=normalize)
    
    #Note only m=0 terms are considered 
    static_axi_bar=potential.SCFPotential(amp=mrat,Acos=np.atleast_3d(Acos[:,:,0]),a=a)
    
    barrot=potential.SolidBodyRotationWrapperPotential(pot=static_bar,omega=omegaP,ro=ro,vo=vo,pa=init_phi)
    
    if mbar <= 5.*10**9. :
        MWP2014SCFbar=[MWPotential2014[0],MiyamotoNagaiPotential(amp=(6.8-mrat)*10.**10*u.Msun,a=3./8.,b=0.28/8.),MWPotential2014[2],barrot]
        turn_physical_off(MWP2014SCFbar)
        #setup the corresponding axisymmetric bar
        MWP2014SCFnobar= [MWPotential2014[0],MiyamotoNagaiPotential(amp=(6.8-mrat)*10.**10*u.Msun,a=3./8.,b=0.28/8.),MWPotential2014[2],static_axi_bar]
        turn_physical_off(MWP2014SCFnobar)
        
    else : 
        MWP2014SCFbar=[MiyamotoNagaiPotential(amp=(6.8+0.5-mrat)*10.**10*u.Msun,a=3./8.,b=0.28/8.),MWPotential2014[2],barrot]
        turn_physical_off(MWP2014SCFbar)
        
        MWP2014SCFnobar= [MiyamotoNagaiPotential(amp=(6.8+0.5-mrat)*10.**10*u.Msun,a=3./8.,b=0.28/8.),MWPotential2014[2],static_axi_bar]
        turn_physical_off(MWP2014SCFnobar)
        
    return (MWP2014SCFbar,MWP2014SCFnobar)
Example #3
0
    def __init__(self,discpot,zlim,vlim,times=np.linspace(0,1,1001)*u.Gyr,zpt=31,vpt=31,zarray=False,varray=False):

        """
        NAME:
           __init__
        PURPOSE:
           Initialize a vertical disc in equilibrium
        INPUT:
           pot (galpy potential) - should be a 1-dimensional potential
           zlim (float) - maximum height of the galactic disc in kpc
           vlim (float) - maximum velocity of the galactic disc in km/s
        OPTIONAL INPUTS:
           times (array) - time array over which to integrate the disc orbits.
                    Otherwise, it defaults to 1001 timesteps over 5 Gyr.
           zpt (int) - number of phase-space points along the z-axis
           vpt (int) - number of phase-space points along the vz-axis
           zarray (boolean) - if True, zlim is an array specifying the points along the z-axis at which to calculte the perturbation
           varray (boolean) - if True, vlim is an array specifying the points along the vz-axis at which to calculte the perturbation
        OUTPUT:
           instance
        """

        turn_physical_off(discpot) #1-dimensional potential object from Galpy
        self.pot= discpot
        self.InternalUnits= get_physical(self.pot)
        if zarray:
            self.zmax=np.max(np.abs(zlim))
            self.znpt= len(zlim)
            self.z= zlim
        else:
            self.zmax= zlim/self.InternalUnits['ro']
            self.znpt= zpt
            self.z= np.linspace(-self.zmax,self.zmax,self.znpt) # in galpy internal units
        if varray:
            self.vmax=np.max(np.abs(vlim))
            self.vnpt= len(vlim)
            self.v= vlim
        else:
            self.vmax= vlim/self.InternalUnits['vo']
            self.vnpt= vpt
            self.v= np.linspace(-self.vmax,self.vmax,self.vnpt) # in galpy internal units

        self.tt= times

        self.Jz,self.Oz= self.calc_JO()
        self.integOrbits(self.tt)
Example #4
0
    def _coordinate_system(zmin_max, vmin_max, N, galactic_potential):
        """

        :param zmin_max:
        :param vmin_max:
        :param N:
        :param galactic_potential:
        :return:
        """
        _z = np.linspace(-zmin_max, zmin_max, N)
        _v = np.linspace(-vmin_max, vmin_max, N)

        turn_physical_off(galactic_potential)
        units = get_physical(galactic_potential)

        z_units_internal = _z / units['ro']
        v_units_internal = _v / units['vo']

        return z_units_internal, v_units_internal, galactic_potential, units
Example #5
0
def MWPotentialSCFbar_grow(mbar,
                           Acos,
                           Asin,
                           rs=1.,
                           normalize=False,
                           pat_speed=40.,
                           fin_phi_deg=27.,
                           t_on=-2.,
                           tgrow=2,
                           tstream=5.):
    '''
    SCFbar starts growing at -x Gyr

    tstream : age of the stream/max stripping time
    t_on: time in Gyr in the past at which the bar acquired full strength
    tgrow: no of bar periods it took the bar to grow to full strength starting at tform
            
    '''

    #setup the full strength bar and axisymmetric "bar"
    a = rs / ro
    omegaP = pat_speed * (ro / vo)

    fin_phi = np.radians(fin_phi_deg)

    Tbar = 2. * np.pi / np.abs(omegaP)  #bar period in galpy units.
    t_on = t_on / bovy_conversion.time_in_Gyr(vo, ro)
    tsteady = tgrow * Tbar
    tform = t_on - tsteady  #- because past is negative

    mrat = mbar / 10.**10.  #10^10 mass of bar used to compute Acos and Asin

    static_bar = mySCFPotential(amp=mrat,
                                Acos=Acos,
                                Asin=Asin,
                                a=a,
                                normalize=normalize)

    #Note only m=0 terms are considered
    static_axi_bar = mySCFPotential(amp=mrat,
                                    Acos=np.atleast_3d(Acos[:, :, 0]),
                                    a=a)

    barrot = potential.SolidBodyRotationWrapperPotential(pot=static_bar,
                                                         omega=omegaP,
                                                         ro=ro,
                                                         vo=vo,
                                                         pa=fin_phi)

    if mbar <= 5. * 10**9.:
        MWP2014SCFbar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)
        #setup the corresponding axisymmetric bar
        MWP2014SCFnobar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    else:
        MWP2014SCFbar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)

        MWP2014SCFnobar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    #if t_on >= t_stream, then stream sees the bar as always on
    if np.abs(t_on) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        return (MWP2014SCFbar, MWP2014SCFnobar)

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        print("tform > age of stream")

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) < tstream:

        MWbar_grow = DehnenWrap(amp=1.,
                                pot=MWP2014SCFbar,
                                tform=tform,
                                tsteady=tsteady)
        MWaxibar_destroy = DehnenWrap(amp=-1.,
                                      pot=MWP2014SCFnobar,
                                      tform=tform,
                                      tsteady=tsteady)

        growbarpot = [MWbar_grow, MWP2014SCFnobar, MWaxibar_destroy]

        turn_physical_off(growbarpot)

        return (growbarpot, MWP2014SCFnobar)
# Make the position arrays
grid_rpoints, grid_phipoints = ast1501.df.generate_grid_radial(
    r_range, phi_range, delta_r, delta_phi, delta_phi_in_arc=True)

# Make the potential
mwpot = potential.MWPotential2014
halo_a = 1.0
halo_phi = 0.0
halo_c = 1.0
trihalo = ast1501.potential.make_MWPotential2014_triaxialNFW(halo_b=halo_b,
                                                             halo_phi=halo_phi,
                                                             halo_c=halo_c)
tripot_grow = ast1501.potential.make_tripot_dsw(trihalo=trihalo,
                                                tform=t_form,
                                                tsteady=t_steady)
potential.turn_physical_off(tripot_grow)

# Action angle coordinates and the DF
qdf_aA = actionAngle.actionAngleAdiabatic(pot=potential.MWPotential2014,
                                          c=True)
qdf = df.quasiisothermaldf(hr=2 * apu.kpc,
                           sr=sigma_vR * (apu.km / apu.s),
                           sz=sigma_vZ * (apu.km / apu.s),
                           hsr=9.8 * (apu.kpc),
                           hsz=7.6 * (apu.kpc),
                           pot=potential.MWPotential2014,
                           aA=qdf_aA)

# ----------------------------------------------------------------------------

# Make the log
Example #7
0
def spiral_arms_potential(FR_frac=1.,
                          t_on=-5.,
                          tgrow=2,
                          tstream=5.,
                          axi_pot=MWPotential2014,
                          cos=True,
                          N=2,
                          pat_speed=24.5,
                          pitch_angle=9.9,
                          r_ref=8.,
                          Rs=7.,
                          phi0=26.,
                          H=0.3):

    phi0 = np.radians(phi0)
    omega = pat_speed * (ro / vo)
    alpha = numpy.radians(pitch_angle)
    r_ref /= ro
    Rs /= ro
    H /= ro

    # percentage of the radial force to set the amplitude of the spiral
    FR_frac = FR_frac * 0.01

    if cos:
        Cs = [8. / (3. * numpy.pi), 0.5, 8. / (15. * numpy.pi)]

    else:
        Cs = [1]

    #compute max radial force for amp=1
    pp = np.linspace(0., 2. * np.pi, 1000)
    FR_nonaxi = []
    spiral_pot_amp1 = SpiralArmsPotential(amp=1.,
                                          N=N,
                                          omega=omega,
                                          alpha=alpha,
                                          phi_ref=phi0,
                                          r_ref=r_ref,
                                          H=H,
                                          Rs=Rs,
                                          Cs=Cs)
    turn_physical_off(spiral_pot_amp1)

    for ii in range(len(pp)):
        FR_nonaxi.append(
            potential.evaluateRforces(spiral_pot_amp1,
                                      R=8. / ro,
                                      z=0.,
                                      phi=pp[ii],
                                      t=0.))

    interp_FR_nonaxi = interpolate.InterpolatedUnivariateSpline(pp, FR_nonaxi)

    #fmin, because radial force is negative
    max_phi = optimize.fmin(interp_FR_nonaxi, 0., disp=0)

    max_FR_nonaxi = interp_FR_nonaxi(max_phi)[0]

    #compute the radial force due to the axisymmetric potential
    FR_axi = potential.evaluateRforces(axi_pot, R=8. / ro, z=0., t=0.)

    #compute the correct amplitude
    amp = numpy.abs(FR_frac * FR_axi / max_FR_nonaxi)

    #setup spiral potential with correct amplitude
    spiralpot = SpiralArmsPotential(amp=amp,
                                    N=N,
                                    omega=omega,
                                    alpha=alpha,
                                    phi_ref=phi0,
                                    r_ref=r_ref,
                                    H=H,
                                    Rs=Rs,
                                    Cs=Cs)

    #grow the spirals

    Tspiral = 2. * np.pi / np.abs(omega)  #bar period in galpy units.
    t_on = t_on / bovy_conversion.time_in_Gyr(vo, ro)
    tsteady = tgrow * Tspiral
    tform = t_on - tsteady  #- because past is negative

    #if t_on >= t_pal5_age, then Pal 5 sees the spirals always on
    if np.abs(t_on) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        print('not growing spiral')
        MWspiralpot = axi_pot + [spiralpot]
        turn_physical_off(MWspiralpot)

        return (MWspiralpot)

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        print("tform > age of stream")

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) < tstream:
        print('growing spiral')

        spiralpot_grow = DehnenWrap(amp=1.,
                                    pot=spiralpot,
                                    tform=tform,
                                    tsteady=tsteady)
        turn_physical_off(spiralpot_grow)
        MWspiralpot = axi_pot + [spiralpot_grow]
        return MWspiralpot
Example #8
0
def MWPotentialSCFbar_invert(mbar,
                             Acos,
                             Asin,
                             rs=1.,
                             normalize=False,
                             pat_speed=40.,
                             fin_phi_deg=27.,
                             t_stream_age=5.,
                             t_on=2.,
                             tgrow=2):
    '''
    t_stream_age : age of the stream/max stripping time
    tform: time in Gyr in the past at which the bar started to form
    tgrow: no of bar periods it took the bar to grow to full strength starting at tform
    
        
    '''

    #setup the full strength bar and axisymmetric "bar"
    a = rs / ro
    omegaP = pat_speed * (ro / vo)

    fin_phi = np.radians(fin_phi_deg)

    mrat = mbar / 10.**10.  #10^10 mass of bar used to compute Acos and Asin

    static_bar = potential.SCFPotential(amp=mrat,
                                        Acos=Acos,
                                        Asin=Asin,
                                        a=a,
                                        normalize=normalize)

    #Note only m=0 terms are considered
    static_axi_bar = potential.SCFPotential(amp=mrat,
                                            Acos=np.atleast_3d(Acos[:, :, 0]),
                                            a=a)

    #pa = final phi and omega is negative since we are going back in time
    barrot = potential.SolidBodyRotationWrapperPotential(pot=static_bar,
                                                         omega=-omegaP,
                                                         ro=ro,
                                                         vo=vo,
                                                         pa=fin_phi)

    if mbar <= 5. * 10**9.:
        MWP2014SCFbar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)
        #setup the corresponding axisymmetric bar
        MWP2014SCFnobar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    else:
        MWP2014SCFbar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)

        MWP2014SCFnobar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    #setup Dehnen smooth growth wrapper for the bar

    #while going back, t_on = tform, then deconstruct the bar to no bar during tsteady
    tform = t_on / bovy_conversion.time_in_Gyr(vo, ro)

    Tbar = 2. * np.pi / omegaP
    tsteady = tgrow * Tbar

    MWaxibar_grow = DehnenWrap(amp=1.,
                               pot=MWP2014SCFnobar,
                               tform=tform,
                               tsteady=tsteady)
    MWbar_destroy = DehnenWrap(amp=-1.,
                               pot=MWP2014SCFbar,
                               tform=tform,
                               tsteady=tsteady)

    growbarpot_invert = [MWP2014SCFbar, MWaxibar_grow, MWbar_destroy]
    turn_physical_off(growbarpot_invert)

    return growbarpot_invert
Example #9
0
def MWPotentialSCFbar(mbar,
                      Acos,
                      Asin,
                      rs=1.,
                      normalize=False,
                      pat_speed=40.,
                      fin_phi_deg=27.,
                      t_stream_age=5.,
                      t_on=2.,
                      tgrow=2):
    '''
    t_stream_age : age of the stream/max stripping time
    t_on: time in Gyr in the past at which the bar acquired full strength
    tgrow: no of bar periods it took the bar to grow to full strength starting at tform
            
    '''

    #setup the full strength bar and axisymmetric "bar"
    a = rs / ro
    omegaP = pat_speed * (ro / vo)

    fin_phi = np.radians(fin_phi_deg)

    t_stream_age = t_stream_age / bovy_conversion.time_in_Gyr(vo, ro)

    Tbar = 2. * np.pi / omegaP  #bar period in galpy units.
    t_on = t_on / bovy_conversion.time_in_Gyr(vo, ro)
    tsteady = tgrow * Tbar
    tform = t_on + tsteady

    init_phi = fin_phi - omegaP * t_stream_age / bovy_conversion.time_in_Gyr(
        vo, ro)

    mrat = mbar / 10.**10.  #10^10 mass of bar used to compute Acos and Asin

    static_bar = SCFPotential(amp=mrat,
                              Acos=Acos,
                              Asin=Asin,
                              a=a,
                              normalize=normalize)

    #Note only m=0 terms are considered
    static_axi_bar = SCFPotential(amp=mrat,
                                  Acos=np.atleast_3d(Acos[:, :, 0]),
                                  a=a)

    barrot = potential.SolidBodyRotationWrapperPotential(pot=static_bar,
                                                         omega=omegaP,
                                                         ro=ro,
                                                         vo=vo,
                                                         pa=init_phi)

    if mbar <= 5. * 10**9.:
        MWP2014SCFbar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)
        #setup the corresponding axisymmetric bar
        MWP2014SCFnobar = [
            MWPotential2014[0],
            MiyamotoNagaiPotential(amp=(6.8 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    else:
        MWP2014SCFbar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2], barrot
        ]
        turn_physical_off(MWP2014SCFbar)

        MWP2014SCFnobar = [
            MiyamotoNagaiPotential(amp=(6.8 + 0.5 - mrat) * 10.**10 * u.Msun,
                                   a=3. / 8.,
                                   b=0.28 / 8.), MWPotential2014[2],
            static_axi_bar
        ]
        turn_physical_off(MWP2014SCFnobar)

    #setup Dehnen smooth growth wrapper for the bar
    #convert to galpy units

    #if t_on >= t_pal5_age, then Pal 5 sees the bar as always on
    if t_on >= t_stream_age:
        return (MWP2014SCFbar, MWP2014SCFnobar)

    elif tform >= t_stream_age:
        print("tform > age of Pal 5 stream")

    elif tform < t_stream_age:

        #change tform in the past, i.e. instead of from today, to time in the future from 5 Gyr in the past
        tform = t_stream_age - tform
        MWbar_grow = DehnenWrap(amp=1.,
                                pot=MWP2014SCFbar,
                                tform=tform,
                                tsteady=tsteady)
        MWaxibar_destroy = DehnenWrap(amp=-1.,
                                      pot=MWP2014SCFnobar,
                                      tform=tform,
                                      tsteady=tsteady)

        growbarpot = [MWbar_grow, MWP2014SCFnobar, MWaxibar_destroy]

        turn_physical_off(growbarpot)

        return (growbarpot, MWP2014SCFnobar)