m.star.temperature = tsun m.star.luminosity = lsun # Set up disk d = m.add_flared_disk() d.rmin = 10 * rsun d.rmax = 30. * au d.mass = 0.01 * msun d.p = -1 d.beta = 1.25 d.r_0 = 10. * au d.h_0 = 0.4 * au d.dust = 'kmh_lite.hdf5' # Set up grid m.set_spherical_polar_grid_auto(400, 100, 1) # Don't compute temperatures m.set_n_initial_iterations(0) # Don't re-emit photons m.set_kill_on_absorb(True) # Use raytracing (only important for source here, since no dust emission) m.set_raytracing(True) # Compute images using monochromatic radiative transfer m.set_monochromatic(True, wavelengths=[1.]) # Set up image i = m.add_peeled_images()
cavity = envelope.add_bipolar_cavity() cavity.power = 1.5 cavity.theta_0 = 20 cavity.r_0 = envelope.rmax cavity.rho_0 = 5e4 * 3.32e-24 cavity.rho_exp = 0. cavity.dust = 'kmh_lite.hdf5' # Use raytracing to improve s/n of thermal/source emission m.set_raytracing(True) # Use the modified random walk m.set_mrw(True, gamma=2.) # Set up grid m.set_spherical_polar_grid_auto(399, 199, 1) # Set up SED sed = m.add_peeled_images(sed=True, image=False) sed.set_viewing_angles(np.linspace(0., 90., 10), np.repeat(45., 10)) sed.set_wavelength_range(150, 0.02, 2000.) # Set number of photons m.set_n_photons(initial=1e6, imaging=1e6, raytracing_sources=1e4, raytracing_dust=1e6) # Set number of temperature iterations and convergence criterion m.set_n_initial_iterations(10) m.set_convergence(True, percentile=99.0, absolute=2.0, relative=1.1) # Write out file
disk.rmin = 10 * m.star.radius disk.rmax = 200 * au disk.r_0 = m.star.radius disk.h_0 = 0.01 * disk.r_0 disk.p = -1.0 disk.beta = 1.25 disk.dust = 'kmh_lite.hdf5' # Use raytracing to improve s/n of thermal/source emission m.set_raytracing(True) # Use the modified random walk m.set_mrw(True, gamma=2.) # Set up grid m.set_spherical_polar_grid_auto(399, 199, 1) # Set up SED for 10 viewing angles sed = m.add_peeled_images(sed=True, image=False) sed.set_viewing_angles(np.linspace(0., 90., 10), np.repeat(45., 10)) sed.set_wavelength_range(150, 0.02, 2000.) sed.set_track_origin('basic') # Set number of photons m.set_n_photons(initial=1e5, imaging=1e6, raytracing_sources=1e4, raytracing_dust=1e6) # Set number of temperature iterations m.set_n_initial_iterations(5)
envelope.mass = 0.001 * msun # Envelope mass envelope.rmin = au # Inner radius envelope.rmax = 10000 * au # Outer radius envelope.power = -2 # Radial power envelope.r_0 = au # Inner density radius #dust disk.dust = 'www003.hdf5' envelope.dust = 'kmh.hdf5' #cavity.dust = 'kmh_hdf5' #coordinates n_r = 200 n_theta = 200 n_phi = 1 m.set_spherical_polar_grid_auto(n_r, n_theta, n_phi) #viewing angles image = m.add_peeled_images(image=False) # Set number of viewing angles n_view = 10 # Generate the viewing angles theta = np.linspace(0., 90., n_view) phi = np.repeat(45., n_view) # Set the viewing angles image.set_viewing_angles(theta, phi) #sed interval n_wav=250 wav_min=0.1 wav_max=1000
def ShellThree_Only(dust_file_name, fnu, nu, stellar_luminoisity, stellar_temperature, stellar_radius, total_shell_mass, uant_distance, expansion_velocity, MaxCSE_outer_rad, Photon_Number, CPU_Number): # Initalize the model model = AnalyticalYSOModel() #We use the YSO model with modified parameters to match an AGB star with a detached shell # Set the stellar parameters model.star.spectrum = (nu, fnu) model.star.luminosity = stellar_luminoisity #model.star.mass = 2 * msun #Guesstimate 1.3 - 3 Msun #Not needed for RT modelling normally. Very difficult to estimate. model.star.radius = stellar_radius #Power-law spherically symmetric envelope - Only Detached Shell - Need to add constant outflow envelope on top of this to account for the ML after the thermal pulse. envelope_shell = model.add_power_law_envelope() envelope_shell.mass = total_shell_mass envelope_shell.rmin = (41.5 * uant_distance) * au # Shell 3 inner radius converted to au - from GD+2001&2003 AND M2010 envelope_shell.rmax = (44.5 * uant_distance) * au # Shell 3 outer radius converted to au - from GD+2001&2003 AND M2010 envelope_shell.r_0 = envelope_shell.rmin envelope_shell.power = -2 # Radial power #Constant Outflow envelope envelope_shell.dust = dust_file_name #Using a standard Hyperion Dust model. Needs to be modified a lot for U Ant envelope_CSE_Max = (MaxCSE_outer_rad * uant_distance) * au # Outer radius- estimating the total emission will be ~ this radius - pre&post thermal pulse. Units = cm # Set up grid to run the model on model.set_spherical_polar_grid_auto(100, 1, 1) #(n_r, n_theta, n_phi) - in a spherical envelope theta and phi are uniform and 1. n_r = number of r radii to seperate the grid to. # Use raytracing to improve s/n of thermal/source emission model.set_raytracing(raytracing=True) # Set up SED - Get SED output sed = model.add_peeled_images(sed=True, image=False) sed.set_uncertainties(uncertainties=True) sed.set_viewing_angles([45], [45]) #(np.linspace(0., 90., 10), np.repeat(45., 10)) #Veiw the source at 45degrees from the pole and theta = 45 sed.set_wavelength_range(100, 0.3, 1200.) #(n_wav, wav_min, wav_max) #Get the SED from 1micron to 2000micron in 100 wavelengths #Set up Image - Get image output - RT calculated for bins of wavelengths - PACS 70 image_70 = model.add_peeled_images(sed=False, image=True) image_70.set_uncertainties(uncertainties=True) image_70.set_viewing_angles([45], [45]) #(np.linspace(0., 90., 10), np.repeat(45., 10)) #Veiw the source at 45degrees from the pole and theta = 45 image_70.set_wavelength_range(30, 60, 90) #(n_wav, wav_min, wav_max) - PACS 70 filter profile limits 60 - 90 and get 30 image cube to get images at ~1 micron per image image_70.set_image_size(400, 400) #Size of image in pixels image_70.set_image_limits(-1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max, -1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max) #Set up Image - Get image output - RT calculated for bins of wavelengths - PACS 160 image_160 = model.add_peeled_images(sed=False, image=True) image_160.set_uncertainties(uncertainties=True) image_160.set_viewing_angles([45], [45]) #(np.linspace(0., 90., 10), np.repeat(45., 10)) #Veiw the source at 45degrees from the pole and theta = 45 image_160.set_wavelength_range(30, 130, 220) #(n_wav, wav_min, wav_max) - PACS 160 filter profile limits 130 - 220 and get 30 image cube to get images at ~3 micron per image image_160.set_image_size(400, 400) #Size of image in pixels image_160.set_image_limits(-1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max, -1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max) #Set up Image - Get image output - RT calculated for bins of wavelengths - SCUBA-2 450 image_450 = model.add_peeled_images(sed=False, image=True) image_450.set_uncertainties(uncertainties=True) image_450.set_viewing_angles([45], [45]) #(np.linspace(0., 90., 10), np.repeat(45., 10)) #Veiw the source at 45degrees from the pole and theta = 45 image_450.set_wavelength_range(30, 410, 480) #(n_wav, wav_min, wav_max) - - SCUBA-2 450 filter profile limits 790 - 940 and get 30 image cube to get images at ~2 micron per image image_450.set_image_size(400, 400) #Size of image in pixels image_450.set_image_limits(-1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max, -1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max) #Set up Image - Get image output - RT calculated for bins of wavelengths - SCUBA-2 850 image_850 = model.add_peeled_images(sed=False, image=True) image_850.set_uncertainties(uncertainties=True) image_850.set_viewing_angles([45], [45]) #(np.linspace(0., 90., 10), np.repeat(45., 10)) #Veiw the source at 45degrees from the pole and theta = 45 image_850.set_wavelength_range(30, 790, 940) #(n_wav, wav_min, wav_max) - SCUBA-2 850 filter profile limits 790 - 940 and get 30 image cube to get images at ~5 micron per image image_850.set_image_size(400, 400) #Size of image in pixels image_850.set_image_limits(-1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max, -1.5 * envelope_CSE_Max, 1.5 * envelope_CSE_Max) # Set number of photons model.set_n_photons(initial=Photon_Number, imaging=Photon_Number, raytracing_sources=Photon_Number, raytracing_dust=Photon_Number) # Set number of temperature iterations and convergence criterion model.set_n_initial_iterations(5) model.set_convergence(True, percentile=99.0, absolute=2.0, relative=1.1) # Write out file Input_ShellThree_Only = 'Model_ShellThree_Only.rtin' #File which saves all the input above so that fortran can run internally for RT modelling Output_ShellThree_Only = 'Model_ShellThree_Only.rtout' model.write(Input_ShellThree_Only) model.run(Output_ShellThree_Only, mpi=True, n_processes=CPU_Number) return Input_ShellThree_Only, Output_ShellThree_Only
def setup_model(parfile, output, imaging=True): # Read in model parameters par = read_parfile(parfile, nested=True) # Find all dust files dust_files = {} for par_name in par: if 'dust' in par[par_name]: dust_file = par[par_name]['dust'] dust_files[dust_file] = SphericalDust(dust_file) # Find dimensionality of problem: if 'disk' in par: ndim = 2 optimize = False elif 'cavity' in par: ndim = 2 optimize = False elif 'envelope' in par and 'rc' in par['envelope']: ndim = 2 optimize = False else: ndim = 1 optimize = True # Set up model m = AnalyticalYSOModel(output) if not 'star' in par: raise Exception("Cannot compute a model without a central source") # Set radius and luminosity m.star.radius = par['star']['radius'] * rsun m.star.luminosity = 4. * pi * (par['star']['radius'] * rsun) ** 2. \ * sigma * par['star']['temperature'] ** 4. # Interpolate and set spectrum nu, fnu = interp_atmos(par['star']['temperature']) m.star.spectrum = (nu, fnu) subtract_from_ambient = [] if 'disk' in par: # Add the flared disk component disk = m.add_flared_disk() # Basic parameters disk.mass = par['disk']['mass'] * msun disk.rmax = par['disk']['rmax'] * au disk.p = par['disk']['p'] disk.beta = par['disk']['beta'] disk.h_0 = par['disk']['h100'] * au disk.r_0 = 100. * au # Set inner and outer walls to be spherical disk.cylindrical_inner_rim = False disk.cylindrical_outer_rim = False # Set dust disk.dust = dust_files[par['disk']['dust']] # Inner radius if 'rmin' in par['disk']: disk.rmin = par['disk']['rmin'] * OptThinRadius(TSUB) else: disk.rmin = OptThinRadius(TSUB) # Settling if 'eta' in par['disk']: raise Exception("Dust settling not implemented") # Accretion luminosity if 'lacc' in par['disk']: raise Exception("Accretion luminosity not implemented") # m.setup_magnetospheric_accretion(par['disk']['lacc'] * lsun, # par['disk']['rtrunc'], # par['star']['fspot'], disk) subtract_from_ambient.append(disk) if 'envelope' in par: if 'rc' in par['envelope']: # Ulrich envelope envelope = m.add_ulrich_envelope() envelope.rho_0 = par['envelope']['rho_0'] envelope.rc = par['envelope']['rc'] * au elif 'power' in par['envelope']: # Power-law envelope envelope = m.add_power_law_envelope() envelope.power = par['envelope']['power'] envelope.rho_0 = par['envelope']['rho_0'] envelope.r_0 = 1000. * au # Set dust envelope.dust = dust_files[par['envelope']['dust']] # Inner radius if 'rmin' in par['envelope']: envelope.rmin = par['envelope']['rmin'] * OptThinRadius(TSUB) else: envelope.rmin = OptThinRadius(TSUB) subtract_from_ambient.append(envelope) if 'cavity' in par: if not 'envelope' in par: raise Exception("Can't have a bipolar cavity without an envelope") # Add the bipolar cavity component cavity = envelope.add_bipolar_cavity() # Basic parameters cavity.power = par['cavity']['power'] cavity.r_0 = 10000 * au cavity.theta_0 = par['cavity']['theta_0'] cavity.rho_0 = par['cavity']['rho_0'] cavity.rho_exp = 0. # Very important is that the cavity density should not be *larger* than # the envelope density. cavity.cap_to_envelope_density = True # Set dust cavity.dust = dust_files[par['cavity']['dust']] subtract_from_ambient.append(cavity) if 'ambient' in par: # Add the ambient medium contribution ambient = m.add_ambient_medium(subtract=subtract_from_ambient) # Set the density, temperature, and dust properties ambient.rho = par['ambient']['density'] ambient.temperature = par['ambient']['temperature'] ambient.dust = dust_files[par['ambient']['dust']] # If there is an envelope, set the outer radius to where the # optically thin temperature would transition to the ambient medium # temperature if 'envelope' in par: # Find radius where the optically thin temperature drops to the # ambient temperature. We can do this only if we've already set # up all the sources of emission beforehand (which we have) rmax_temp = OptThinRadius(ambient.temperature).evaluate(m.star, envelope.dust) # Find radius where the envelope density drops to the ambient density rmax_dens = envelope.outermost_radius(ambient.rho) # If disk radius is larger than this, use that instead if 'disk' in par: if disk.rmax > rmax_dens: rmax_dens = disk.rmax # Pick the largest if rmax_temp < rmax_dens: print("Setting envelope outer radius to that where rho(r) = rho_amb") envelope.rmax = rmax_dens else: print("Setting envelope outer radius to that where T_thin(r) = T_amb") envelope.rmax = OptThinRadius(ambient.temperature) ambient.rmax = envelope.rmax else: if 'disk' in par: # Find radius where the optically thin temperature drops to the # ambient temperature. We can do this only if we've already set # up all the sources of emission beforehand (which we have) rmax_temp = OptThinRadius(ambient.temperature).evaluate(m.star, ambient.dust) # Find outer disk radius rmax_dens = disk.rmax # Pick the largest if rmax_temp < rmax_dens: print("Setting ambient outer radius to outer disk radius") ambient.rmax = rmax_dens else: print("Setting ambient outer radius to that where T_thin(r) = T_amb") ambient.rmax = OptThinRadius(ambient.temperature) else: ambient.rmax = OptThinRadius(ambient.temperature) # The inner radius for the ambient medium should be the largest of # the inner radii for the disk and envelope if 'envelope' in par and 'rmin' in par['envelope']: if 'disk' in par and 'rmin' in par['disk']: ambient.rmin = max(par['disk']['rmin'], \ par['envelope']['rmin']) \ * OptThinRadius(TSUB) else: ambient.rmin = par['envelope']['rmin'] * OptThinRadius(TSUB) elif 'disk' in par and 'rmin' in par['disk']: ambient.rmin = par['disk']['rmin'] * OptThinRadius(TSUB) else: ambient.rmin = OptThinRadius(TSUB) # The ambient medium needs to go out to sqrt(2.) times the envelope # radius to make sure the slab is full (don't need to do sqrt(3) # because we only need a cylinder along line of sight) ambient.rmax *= np.sqrt(2.) # Make sure that the temperature in the model is always at least # the ambient temperature m.set_minimum_temperature(ambient.temperature) else: # Make sure that the temperature in the model is always at least # the CMB temperature m.set_minimum_temperature(2.725) if 'envelope' in par: raise Exception("Can't have an envelope without an ambient medium") # Use raytracing to improve s/n of thermal/source emission m.set_raytracing(True) # Use the modified random walk m.set_mrw(True, gamma=2.) # Use the partial diffusion approximation m.set_pda(True) # Improve s/n of scattering by forcing the first interaction m.set_forced_first_scattering(True) # Set up grid. if ndim == 1: m.set_spherical_polar_grid_auto(400, 1, 1) else: m.set_spherical_polar_grid_auto(400, 300, 1) # Find the range of radii spanned by the grid rmin, rmax = m.radial_range() # Set up SEDs image = m.add_peeled_images(sed=True, image=False) image.set_wavelength_range(200, 0.01, 5000.) if 'ambient' in par: image.set_aperture_range(20, rmin, rmax / np.sqrt(2.)) else: image.set_aperture_range(20, rmin, rmax) image.set_output_bytes(8) image.set_track_origin(True) image.set_uncertainties(True) image.set_stokes(True) if ndim == 1: # Viewing angle does not matter image.set_viewing_angles([45.], [45.]) else: # Use stratified random sampling to ensure that all models # contain a viewing angle in each bin, but also ensure we have a # continuum of viewing angles over all models xi = np.random.uniform(0., 90./float(NVIEW), NVIEW) theta = xi + np.linspace(0., 90. * (1. - 1./float(NVIEW)), NVIEW) image.set_viewing_angles(theta, np.repeat(45., NVIEW)) if 'ambient' in par: # take a slab to avoid spherical geometrical effects w = ambient.rmax / np.sqrt(2.) image.set_depth(-w, w) else: # don't need to take a slab, as no ambient material or envelope image.set_depth(-np.inf, np.inf) # Set number of photons if imaging: n_imaging=1e6 n_raytracing_sources=10000 n_raytracing_dust=1e6 else: n_imaging=0 n_raytracing_sources=0 n_raytracing_dust=0 if ndim == 1: m.set_n_photons(initial=100, imaging=n_imaging, raytracing_sources=n_raytracing_sources, raytracing_dust=n_raytracing_dust) else: m.set_n_photons(initial=1000000, imaging=n_imaging, raytracing_sources=n_raytracing_sources, raytracing_dust=n_raytracing_dust) # Set physical array output to 32-bit m.set_output_bytes(4) # Set maximum of 10^8 interactions per photon m.set_max_interactions(1e8) # Only request certain arrays to be output m.conf.output.output_density = 'none' m.conf.output.output_specific_energy = 'last' m.conf.output.output_n_photons = 'none' m.conf.output.output_density_diff = 'last' # Set number of temperature iterations and convergence criterion m.set_n_initial_iterations(10) m.set_convergence(True, percentile=99.0, absolute=2.0, relative=1.1) # Don't copy the full input into the output files m.set_copy_input(False) # Check whether the model is very optically thick mf = m.to_model() if 'envelope' in par: from hyperion.model.helpers import tau_to_radius surface = tau_to_radius(mf, tau=1., wav=5e3) rtau = np.min(surface) if rtau > rmin and optimize: log.warn("tau_5mm > 1 for all (theta,phi) values - truncating " "inner envelope from {0:.3f}au to {1:.3f}au".format(mf.grid.r_wall[1] / au, rtau / au)) for item in mf.grid['density']: item.array[mf.grid.gr < rtau] = 0. # Write out file mf.write(copy=False, absolute_paths=False, physics_dtype=np.float32, wall_dtype=float)
def initModel(self): ### Use Tracy parameter file to set up the model self.dust_gen(self.dustfile,self.dustfile_out) mi = AnalyticalYSOModel() mi.star.temperature = self.T mi.star.mass = self.M_sun mi.star.luminosity = self.L_sun mi.star.radius=np.sqrt(mi.star.luminosity/(4.0*np.pi*sigma*mi.star.temperature**4)) #m.star.luminosity = 4.0*np.pi*m.star.radius**2*sigma*m.star.temperature**4 print mi.star.luminosity/lsun self.luminosity=mi.star.luminosity/lsun if self.disk=="Flared": print "Adding flared disk" disk = mi.add_flared_disk() disk.dust=self.d if self.dustfile == 'd03_5.5_3.0_A.hdf5': disk.mass=self.disk_mass/100. else: disk.mass=self.disk_mass disk.rmin=OptThinRadius(1600) #self.disk_rmin print "disk.rmin = ",disk.rmin,disk.rmin/au disk.rmax=self.disk_rmax disk.r_0 = self.disk_rmin disk.h_0 = disk.r_0/10. #self.disk_h_0*au disk.beta=self.beta disk.p = -1. elif self.disk=="Alpha": print "Adding alpha disk" disk = mi.add_alpha_disk() disk.dust=self.d if self.dustfile == 'd03_5.5_3.0_A.hdf5': disk.mass=self.disk_mass/100. else: disk.mass=self.disk_mass disk.rmin=OptThinRadius(1600) disk.rmax=self.disk_rmax disk.r_0 = self.disk_rmin disk.h_0 = disk.r_0/10. #self.disk_h_0*au disk.beta=1.1 disk.p = -1 disk.mdot=self.mdot disk.star = mi.star #print 'Disk density:',disk.rho_0 if self.env==True and self.env_type=='power': envelope=mi.add_power_law_envelope() envelope.dust=self.d_out envelope.r_0=self.env_rmin #envelope.r_0 = OptThinRadius(1600) if self.dustfile_out == 'd03_5.5_3.0_A.hdf5': envelope.mass=self.env_mass/100. else: envelope.mass=self.env_mass envelope.rmin=self.env_rmin envelope.rmax=self.env_rmax envelope.power=self.env_power #print 'Envelope rho:',envelope.rho_0 elif self.env==True and self.env_type=='ulrich': envelope=mi.add_ulrich_envelope() envelope.dust=self.d_out envelope.mdot=1e-6*msun/yr # has little impact on the fluxes, so fixed envelope.rc=self.rc envelope.rmin=self.env_rmin envelope.rmax=self.env_rmax if self.env==True: self.env_rho_0 = envelope.rho_0 print 'Envelope rho:',envelope.rho_0 #print "Rho_0 = ",envelope.rho_0 if self.cav==True: cavity=envelope.add_bipolar_cavity() cavity.dust=self.d_out cavity.power=1.5 cavity.cap_to_envelope_density=True ### prevents the cavity density to go above the envelope's density cavity.r_0=self.cav_r0 cavity.theta_0=self.cav_theta cavity.rho_0=self.cav_rho_0 #in g/cm^3 cavity.rho_exp=0.0 # if self.env==True: # ambient=mi.add_ambient_medium(subtract=[envelope,disk]) # if self.dustfile_out == 'd03_5.5_3.0_A.hdf5': # ambient.rho=self.amb_dens/100. # else: ambient.rho=self.amb_dens # ambient.rmin=OptThinRadius(1600.) # ambient.rmax=self.env_rmax # ambient.dust=self.d_out '''*** Grid parameters ***''' mi.set_spherical_polar_grid_auto(199,49,1) # Specify that the specific energy and density are needed mi.conf.output.output_specific_energy = 'last' mi.conf.output.output_density = 'last' '''**** Output Data ****''' image = mi.add_peeled_images(sed=True,image=False) image.set_wavelength_range(150,1,3000) #image.set_image_size(self.Npix,self.Npix) #image.set_image_limits(-self.limval,self.limval,-self.limval,self.limval) image.set_aperture_range(1,100000.*au,100000.*au) image.set_viewing_angles(self.angles,self.angles2) #image.set_track_origin('detailed') image.set_uncertainties(True) ''' Use the modified random walk *** Advanced ***' YES = DIFFUSION = Whether to use the diffusion ''' if self.env==True: #mi.set_pda(True) mi.set_mrw(True) else: mi.set_pda(False) mi.set_mrw(False) # Use raytracing to improve s/n of thermal/source emission mi.set_raytracing(True) '''**** Preliminaries ****''' mi.set_n_initial_iterations(5) mi.set_n_photons(initial=1e6,imaging=1e6,raytracing_sources=1e5,raytracing_dust=1e6) mi.set_convergence(True, percentile=99.0, absolute=2.0, relative=1.1) self.m = mi