Beispiel #1
0
def viscous(settings):
    """
    Generates a surface density profile derived from a self-similarity solution
    for a viscous disk, according to:
    
        sigma ~ r^-gamma exp(-r^(2-gamma))
        
    Where r is a dimensionless radius and gamma is a constant less than 2.
    Rd (disk radius) is defined as the radius containing 95% of the disk mass
    
    **ARGUMENTS**
    
    settings : IC settings
        settings like those contained in an IC object (see ICgen_settings.py)
        
    **RETURNS**
    
    R : SimArray
        Radii at which sigma is calculated
    sigma : SimArray
        Surface density profile as a function of R
    """
    Rd = settings.sigma.Rd
    rin = settings.sigma.rin
    rmax = settings.sigma.rmax
    n_points = settings.sigma.n_points
    gamma = settings.sigma.gamma
    m_disk = settings.sigma.m_disk

    # Define the fraction of mass contained within Rd
    A = 0.95
    # Normalization for r
    R1 = Rd / (np.log(1 / (1 - A))**(1 / (2 - gamma)))
    Rmax = rmax * Rd
    Rin = rin * Rd

    R = np.linspace(0, Rmax, n_points)
    r = (R / R1).in_units('1')
    sigma = (r**-gamma) * np.exp(-r**(2 - gamma)) * (
        m_disk / (2 * np.pi * R1 * R1)) * (2 - gamma)
    # Deal with infinities at the origin with a hard cut off
    sigma[0] = sigma[1]

    # Apply interior cutoff
    cut_mask = R < Rin
    if np.any(cut_mask):

        sigma[cut_mask] *= isaac.smoothstep(r[cut_mask],
                                            degree=21,
                                            rescale=True)

    return R, sigma
Beispiel #2
0
def viscous(settings):
    """
    Generates a surface density profile derived from a self-similarity solution
    for a viscous disk, according to:
    
        sigma ~ r^-gamma exp(-r^(2-gamma))
        
    Where r is a dimensionless radius and gamma is a constant less than 2.
    Rd (disk radius) is defined as the radius containing 95% of the disk mass
    
    **ARGUMENTS**
    
    settings : IC settings
        settings like those contained in an IC object (see ICgen_settings.py)
        
    **RETURNS**
    
    R : SimArray
        Radii at which sigma is calculated
    sigma : SimArray
        Surface density profile as a function of R
    """
    Rd = settings.sigma.Rd
    rin = settings.sigma.rin
    rmax = settings.sigma.rmax
    n_points = settings.sigma.n_points
    gamma = settings.sigma.gamma
    m_disk = settings.sigma.m_disk
    
    # Define the fraction of mass contained within Rd
    A = 0.95
    # Normalization for r
    R1 = Rd / (np.log(1/(1-A))**(1/(2-gamma)))
    Rmax = rmax * Rd
    Rin = rin * Rd
    
    R = np.linspace(0, Rmax, n_points)
    r = (R/R1).in_units('1')
    sigma = (r**-gamma) * np.exp(-r**(2-gamma)) * (m_disk/(2*np.pi*R1*R1)) * (2-gamma)   
    # Deal with infinities at the origin with a hard cut off
    sigma[0] = sigma[1]
    
    # Apply interior cutoff
    cut_mask = R < Rin
    if np.any(cut_mask):
        
        sigma[cut_mask] *= isaac.smoothstep(r[cut_mask],degree=21,rescale=True)
    
    
    return R, sigma
Beispiel #3
0
def powerlaw(settings, T=None):
    """
    Generates a surface density profile according to a powerlaw sigma ~ 1/r
    with a smooth interior cutoff and smooth exterior exponential cutoff.
    
    **ARGUMENTS**
    
    settings : IC settings
        settings like those contained in an IC object (see ICgen_settings.py)
    T : callable function
        Function that returns temperature of the disk as a function of radius
        IF none, a powerlaw temperature is assumed
    
    **RETURNS**
    
    R : SimArray
        Radii at which sigma is calculated
    sigma : SimArray
        Surface density profile as a function of R
    """
    # Parse settings
    Rd = settings.sigma.Rd
    rin = settings.sigma.rin
    rmax = settings.sigma.rmax
    cutlength = settings.sigma.cutlength
    Mstar = settings.physical.M
    Qmin = settings.sigma.Qmin
    n_points = settings.sigma.n_points
    m = settings.physical.m
    power = settings.sigma.power

    if T is None:
        # If no callable object to calculate Temperature(R) is provided,
        # default to a powerlaw T ~ R^-q

        T0 = SimArray([129.0], 'K')  # Temperature at 1 AU
        R0 = SimArray([1.0], 'au')
        q = 0.59

        def T(x):

            return T0 * np.power((x / R0).in_units('1'), -q)

    Rd = isaac.match_units(pynbody.units.au, Rd)[1]
    Mstar = isaac.match_units(pynbody.units.Msol, Mstar)[1]
    # Molecular weight
    m = isaac.match_units(m, pynbody.units.m_p)[0]
    # Maximum R to calculate sigma at (needed for the exponential cutoff region)
    Rmax = rmax * Rd

    # Q calculation parameters:
    G = SimArray([1.0], 'G')
    kB = SimArray([1.0], 'k')

    # Initialize stuff
    A = SimArray(1.0, 'Msol') / (2 * np.pi * np.power(Rd, 2))
    R = np.linspace(0, Rmax, n_points)
    r = np.array((R / Rd).in_units('1'))

    # Calculate sigma
    # Powerlaw
    #sigma = A/r
    #dflemin3 edit 06/10/2015: Try powerlaw of the form sigma ~ r^power
    sigma = A * np.power(r, power)
    sigma[0] = 0.0
    # Exterior cutoff
    sigma[r > 1] *= np.exp(-(r[r > 1] - 1)**2 / (2 * cutlength**2))
    # Interior cutoff
    sigma[r < rin] *= isaac.smoothstep(r[r < rin], degree=21, rescale=True)

    # Calculate Q
    Q = np.sqrt(Mstar * kB * T(R) / (G * m * R**3)) / (np.pi * sigma)
    Q.convert_units('1')

    # Rescale sigma to meet the minimum Q requirement
    sigma *= Q.min() / Qmin

    # Calculate Q
    Q = np.sqrt(Mstar * kB * T(R) / (G * m * R**3)) / (np.pi * sigma)
    Q.convert_units('1')
    return R, sigma
Beispiel #4
0
def powerlaw(settings, T = None):
    """
    Generates a surface density profile according to a powerlaw sigma ~ 1/r
    with a smooth interior cutoff and smooth exterior exponential cutoff.
    
    **ARGUMENTS**
    
    settings : IC settings
        settings like those contained in an IC object (see ICgen_settings.py)
    T : callable function
        Function that returns temperature of the disk as a function of radius
        IF none, a powerlaw temperature is assumed
    
    **RETURNS**
    
    R : SimArray
        Radii at which sigma is calculated
    sigma : SimArray
        Surface density profile as a function of R
    """
    # Parse settings
    Rd = settings.sigma.Rd
    rin = settings.sigma.rin
    rmax = settings.sigma.rmax
    cutlength = settings.sigma.cutlength
    Mstar = settings.physical.M
    Qmin = settings.sigma.Qmin
    n_points = settings.sigma.n_points
    m = settings.physical.m

    if T is None:
        # If no callable object to calculate Temperature(R) is provided, 
        # default to a powerlaw T ~ R^-q
        
        T0 = SimArray([129.0],'K') # Temperature at 1 AU
        R0 = SimArray([1.0],'au')
        q = 0.59
        def T(x):
            
            return T0 * np.power((x/R0).in_units('1'),-q)
        
    Rd = isaac.match_units(pynbody.units.au, Rd)[1]
    Mstar = isaac.match_units(pynbody.units.Msol, Mstar)[1]
    # Molecular weight
    m = isaac.match_units(m, pynbody.units.m_p)[0]
    # Maximum R to calculate sigma at (needed for the exponential cutoff region)
    Rmax = rmax*Rd
    
    # Q calculation parameters:
    G = SimArray([1.0],'G')
    kB = SimArray([1.0],'k')
    
    # Initialize stuff
    A = SimArray(1.0,'Msol')/(2*np.pi*np.power(Rd,2))
    R = np.linspace(0,Rmax,n_points)
    r = np.array((R/Rd).in_units('1'))
    
    # Calculate sigma
    # Powerlaw
    sigma = A/r
    sigma[0] = 0.0
    # Interior cutoff
    sigma[r>1] *= np.exp(-(r[r>1] - 1)**2 / (2*cutlength**2))
    # Exterior cutoff
    sigma[r<rin] *= isaac.smoothstep(r[r<rin],degree=21,rescale=True)
    
    # Calculate Q
    Q = np.sqrt(Mstar*kB*T(R)/(G*m*R**3))/(np.pi*sigma)
    Q.convert_units('1')
    
    # Rescale sigma to meet the minimum Q requirement
    sigma *= Q.min()/Qmin
    
    # Calculate Q
    Q = np.sqrt(Mstar*kB*T(R)/(G*m*R**3))/(np.pi*sigma)
    Q.convert_units('1')
    
    return R, sigma