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
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
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
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