def getStellarsrcTemplates(grid=None, ppar=None): """ Function to calculate the stellar density for a continuous starlike source when modeling a viscous accretion disk The stellar template can be defined in two ways: 1) by Tstar, Rstar, Mstar assuming it radiates as a blackbody In this case, similar to the definitions in the stars.inp file the temperature has to be a negative number. 2) by a full frequency-dependent spectru given in erg / sec / Hz / gram-of-star . So multiply this by the stellar density in units of gram-of-star / cm^3, and divide by 4*pi to get the stellar source function in units of erg / src / Hz / cm^3 / steradian. The model setup functions (problemSetupDust() and problemSetupGas()) will check the sign of the first element with indices (0,0) of the array returned by this function to decide which way the stellar template is defined. If the first element is negative, the template is defined by Tstar, Rstar, Mstar, while if it is positive the returned array contains frequency dependent spectra. Parameters ---------- grid : radmc3dGrid An instance of the radmc3dGrid class containing the spatial and frequency/wavelength grid ppar : dictionary A dictionary containing all parameters of the model mandatory keys for an accretion disk: 'mstar' - stellar mass 'rstar' - stellar radius 'accrate' - accretion rate NOTE, that for the calculation of the effective disk temperature only the first star is used if more than one values are given in mstar and rstar. Returns ------- Returns an array with the stellar templates If the stellar template is defined by the temperature, radius and mass of the stars the returned array must have a dimensions [Ntemplate, 3]. The [i,0], [i,1] and [i,2] elements of the array contain the stellar temperature, radius and mass of the ith template, respectively. NOTE, that in this case the stellar temperatures needs to be negative! If the stellar template is defined by the full frequency dependent spectra the returned array should have [Ntemplate, Nwavelength] dimension. """ src = analyze.radmc3dRadSources(ppar=ppar, grid=grid) src.incl_accretion = True src.getAccdiskStellarTemplates(ppar=ppar) dum = np.zeros([src.cststar.shape[0], 3], dtype=float) dum[:,0] = src.cststar dum[:,1] = 1.0 dum[:,2] = 1.0 return dum
def getStellarsrcDensity(grid=None, ppar=None): """ Function to calculate the stellar density for a continuous starlike source when modeling a viscous accretion disk The stellar density is defined as: L_nu / (4*pi) = St_temp * rho_stellar * dV where L_nu is the frequency dependent luminosity of a grid cell St_temp is the stellar template (as given by getStellarsrcTemplates()) rho_stellar is the stellar density dV is the volume of the cell Parameters ---------- grid : radmc3dGrid An instance of the radmc3dGrid class containing the spatial and frequency/wavelength grid ppar : dictionary A dictionary containing all parameters of the model mandatory keys for an accretion disk: 'mstar' - stellar mass 'rstar' - stellar radius 'accrate' - accretion rate NOTE, that for the calculation of the effective disk temperature only the first star is used if more than one values are given in mstar and rstar. """ src = analyze.radmc3dRadSources(ppar=ppar, grid=grid) src.incl_accretion = True src.getAccdiskStellarDensity(ppar=ppar) return src.csdens
def problemSetupGas(model='', fullsetup=False, binary=True, writeGasTemp=False, dfunc=None, dfpar=None, **kwargs): """ Function to set up a gas model for RADMC-3D Parameters ---------- model : str Name of the model that should be used to create the density structure the file should be in a directory from where it can directly be imported (i.e. the directory should be in the PYTHON_PATH environment variable, or it should be the current working directory) and the file name should be 'MODELNAME.py', where MODELNAME stands for the string that should be specified in this variable fullsetup : bool, optional If False only the files related to the gas simulation is written out (i.e. no grid, stellar parameter file and radmc3d master command file is written) assuming that these files have already been created for a previous continuum simulation. If True the spatial and wavelength grid as well as the input radiation field and the radmc3d master command file will be (over)written. binary : bool, optional If True input files will be written in binary format, if False input files are written as formatted ascii text. writeGasTemp : bool, optional If True a separate gas_temperature.inp/gas_tempearture.binp file will be written under the condition that the model contains a function get_gas_temperature() dfunc : function, optional Decision function for octree-like amr tree building. It should take linear arrays of cell centre coordinates (x,y,z) and cell half-widhts (dx,dy,dz) in all three dimensions, a radmc3d model, a dictionary with all parameters from problem_params.inp and an other keyword argument (**kwargs). It should return a boolean ndarray of the same length as the input coordinates containing True if the cell should be resolved and False if not. An example for the implementation of such decision function can be found in radmc3dPy.analyze module (radmc3dPy.analyze.gdensMinMax()). dfpar : dictionary Dicionary of keyword arguments to be passed on to dfunc. These parameters will not be written to problem_params.inp. Parameters can also be passed to dfunc via normal keyword arguments gathered in **kwargs, however all keyword arguments in **kwargs will be written to problem_params.inp **kwargs : Any varible name in problem_params.inp can be used as a keyword argument. At first all variables are read from problem_params.in to a dictionary called ppar. Then if there is any keyword argument set in the call of problem_setup_gas the ppar dictionary is searched for such key. If found the value belonging to that key in the ppar dictionary is changed to the value of the keyword argument. If no such key is found then the dictionary is simply extended by the keyword argument. Finally the problem_params.inp file is updated with the new parameter values. Any additional keyword argument for the octree AMR mesh generation should also be passed here. Notes ----- Files written by problemSetupGas() * lines.inp : Line mode master command file. * numberdens_xxx.inp : Number density of molecule/atomic species 'xxx' * gas_velocity.inp : Gas velocity * microturbulence.inp : The standard deviation of the Gaussian line profile caused by turbulent broadening. * gas_temperature.inp : Gas temperature (which may be different from the dust temperature). If tgas_eq_tdust is set to zero in radmc3d.inp the gas temperature in this file will be used instead of the dust temperature. If fullsetup is set to True the following additional files will be created * amr_grid.inp : Spatial grid. * wavelength_micron.inp : Wavelength grid. * stars.inp : Input radiation field. * radmc3d.inp : Parameters for RADMC-3D (e.g. Nr of photons to be used, scattering type, etc). """ # Read the parameters from the problem_params.inp file modpar = analyze.readParams() # Make a local copy of the ppar dictionary ppar = modpar.ppar if not ppar: print 'ERROR' print 'problem_params.inp was not found' return # -------------------------------------------------------------------------------------------- # If there is any additional keyword argument (**kwargs) then check # if there is such key in the ppar dictionary and if is change its value that of # the keyword argument. If there is no such key in the ppar dictionary then add the keyword # to the dictionary # -------------------------------------------------------------------------------------------- if binary: modpar.setPar(['rto_style', '3', '', '']) if kwargs: for ikey in kwargs.keys(): modpar.ppar[ikey] = kwargs[ikey] if type(kwargs[ikey]) is float: modpar.setPar([ikey, ("%.7e"%kwargs[ikey]), '', '']) elif type(kwargs[ikey]) is int: modpar.setPar([ikey, ("%d"%kwargs[ikey]), '', '']) elif type(kwargs[ikey]) is str: modpar.setPar([ikey, kwargs[ikey], '', '']) elif type(kwargs[ikey]) is list: dum = '[' for i in range(len(kwargs[ikey])): if type(kwargs[ikey][i]) is float: dum = dum + ("%.7e"%kwargs[ikey][i]) elif type(kwargs[ikey][i]) is int: dum = dum + ("%d"%kwargs[ikey][i]) elif type(kwargs[ikey][i]) is str: dum = dum + (kwargs[ikey][i]) else: print ' ERROR ' print ' Unknown data type in '+ikey print kwargs[ikey][i] if i<len(kwargs[ikey])-1: dum = dum + ', ' dum = dum + (']') modpar.setPar([ikey, dum, '', '']) modpar.writeParfile() ppar = modpar.ppar # -------------------------------------------------------------------------------------------- # Try to get the specified model # -------------------------------------------------------------------------------------------- try: import os imp_path = os.getcwd() mdl = __import__(model) except: try: mdl = __import__('radmc3dPy.models.'+model, fromlist=['']) except: print 'ERROR' print ' '+model+'.py could not be imported' print ' The model files should either be in the current working directory or' print ' in the radmc3d python module directory' return # -------------------------------------------------------------------------------------------- # If the current working directory is empty (i.e. no dust setup is present) then # we must make a complete setup and dump the spatial and wavelength grids as well # as the parameters in the radmc3d.inp file # -------------------------------------------------------------------------------------------- if fullsetup: # -------------------------------------------------------------------------------------------- # Create the grid # -------------------------------------------------------------------------------------------- # # Check if AMR is activated or not # if ppar['grid_style'] == 1: grid = analyze.radmc3dOctree() # Pass all parameters from dfpar to ppar if dfpar is not None: for ikey in dfpar.keys(): ppar[ikey] = dfpar[ikey] # Spatial grid grid.makeSpatialGrid(ppar=ppar, dfunc=dfunc, model=model, **kwargs) else: grid = analyze.radmc3dGrid() # Spatial grid grid.makeSpatialGrid(ppar=ppar) # Wavelength grid grid.makeWavelengthGrid(ppar=ppar) # -------------------------------------------------------------------------------------------- # Create the input radiation field (stars at this point) # -------------------------------------------------------------------------------------------- radSources = analyze.radmc3dRadSources(ppar=ppar, grid=grid) radSources.getStarSpectrum(tstar=ppar['tstar'], rstar=ppar['rstar']) # Check if the model has functions to set up continuous starlike sources if ppar.has_key('incl_accretion'): stellarsrcEnabled = ppar['incl_accretion'] else: stellarsrcEnabled = False if dir(mdl).__contains__('getStellarsrcDensity'): if callable(getattr(mdl, 'getStellarsrcDensity')): if dir(mdl).__contains__('getStellarsrcTemplates'): if callable(getattr(mdl, 'getStellarsrcTemplates')): stellarsrcEnabled = True else: stellarsrcEnabled = False else: stellarsrcEnabled = False else: stellarsrcEnabled = False else: stellarsrcEnabled = False if stellarsrcEnabled: dum = mdl.getStellarsrcTemplates(grid=grid, ppar=ppar) if dum[0,0]<0.: radSources.csntemplate = dum.shape[0] radSources.cstemp = [] radSources.cstemptype = 1 radSources.cststar = dum[:,0] radSources.csrstar = dum[:,1] radSources.csmstar = dum[:,2] else: radSources.csntemplate = dum.shape[0] radSources.cstemp = dum radSources.cstemptype = 2 radSources.cststar = [] radSources.csrstar = [] radSources.csmstar = [] radSources.csdens = mdl.getStellarsrcDensity(grid=grid, ppar=ppar) # -------------------------------------------------------------------------------------------- # Now write out everything # -------------------------------------------------------------------------------------------- #Frequency grid grid.writeWavelengthGrid() #Spatial grid grid.writeSpatialGrid() #Input radiation field radSources.writeStarsinp(ppar=ppar) # Continuous starlike sources if stellarsrcEnabled: radSources.writeStellarsrcTemplates() radSources.writeStellarsrcDensity(binary=binary) print '-------------------------------------------------------------' print 'Luminosities of radiation sources in the model :' totlum = radSources.getTotalLuminosities(readInput=True) print 'As calculated from the input files :' print 'Stars : ' print (" Star #%d + hotspot : %.6e"%(0, totlum['lnu_star'][0])) for istar in range(1,radSources.nstar): print (" Star #%d : %.6e"%(istar, totlum['lnu_star'][istar])) print ("Continuous starlike source : %.6e"%totlum['lnu_accdisk']) print ' ' print '-------------------------------------------------------------' #radmc3d.inp writeRadmc3dInp(ppar=ppar) # -------------------------------------------------------------------------------------------- # If the current working directory contains already a dust setup then we can use the # already existing grid files # -------------------------------------------------------------------------------------------- else: grid=analyze.readGrid() # -------------------------------------------------------------------------------------------- # Create the gas density distribution # -------------------------------------------------------------------------------------------- # Create the data structure data = analyze.radmc3dData(grid) # Calculate the gas density and velocity # NOTE: the density function in the model sub-modules should provide the gas volume density # in g/cm^3 but RADMC-3D needs the number density in 1/cm^3 so we should convert the # output of the get_density() function to number density using ppar['gasspecMolAbun'] # which is the abundance of the gas species with respect to hydrogen divided by the # mean molecular weight if dir(mdl).__contains__('getGasDensity'): if callable(getattr(mdl, 'getGasDensity')): if ppar['grid_style'] == 1: data.rhogas = mdl.getGasDensity(grid=grid, ppar=ppar) else: print 'WARNING' print ' '+model+'.py does not contain a getGasDensity() function, therefore, ' print ' numberdens_***.inp cannot be written' return # -------------------------------------------------------------------------------------------- # Create the molecular abundance # -------------------------------------------------------------------------------------------- #if ppar.has_key('gasspec_mol_abun'): #data.rhogas = data.rhogas * ppar['gasspec_mol_abun'] #else: if dir(mdl).__contains__('getGasAbundance'): if callable(getattr(mdl, 'getGasAbundance')): for imol in range(len(ppar['gasspec_mol_name'])): gasabun = mdl.getGasAbundance(grid=grid, ppar=ppar, ispec=ppar['gasspec_mol_name'][imol]) data.ndens_mol = data.rhogas / (2.4 * mp) * gasabun # Write the gas density if ppar['grid_style'] == 1: data.writeGasDens(ispec=ppar['gasspec_mol_name'][imol], binary=binary, octree=True) else: data.writeGasDens(ispec=ppar['gasspec_mol_name'][imol], binary=binary) if abs(ppar['lines_mode'])>2: for icp in range(len(ppar['gasspec_colpart_name'])): gasabun = mdl.getGasAbundance(grid=grid, ppar=ppar, ispec=ppar['gasspec_colpart_name'][icp]) data.ndens_mol = data.rhogas / (2.4*mp) * gasabun # Write the gas density data.writeGasDens(ispec=ppar['gasspec_colpart_name'][icp], binary=binary) else: print 'WARNING' print ' '+model+'.py does not contain a getGasAbundance() function, and no "gasspec_mol_abun" ' print ' parameter is found in the problem_setup.inp file. numberdens_***.inp cannot be written' return # -------------------------------------------------------------------------------------------- # Get the gas velocity field # -------------------------------------------------------------------------------------------- if dir(mdl).__contains__('getVelocity'): if callable(getattr(mdl, 'getVelocity')): data.gasvel = mdl.getVelocity(grid=grid, ppar=ppar) # Write the gas velocity if ppar['grid_style'] == 1: data.writeGasVel(binary=binary, octree=True) else: data.writeGasVel(binary=binary) else: print 'WARNING' print ' '+model+'.py does not contain a getVelocity() function, therefore, ' print ' gas_velocity.inp cannot be written' return # -------------------------------------------------------------------------------------------- # Get the kinetik gas temperature # -------------------------------------------------------------------------------------------- # Write the gas temperature if specified if writeGasTemp: if dir(mdl).__contains__('getGasTemperature'): if callable(getattr(mdl, 'getGasTemperature')): data.gastemp = mdl.getGasTemperature(grid=grid, ppar=ppar) # Write the gas temperature if ppar['grid_style'] == 1: data.writeGasTemp(binary=binary, octree=True) else: data.writeGasTemp(binary=binary) else: print 'WARNING' print ' '+model+'.py does not contain a getGasTemperature() function, therefore, ' print ' gas_temperature.inp cannot be written' return # -------------------------------------------------------------------------------------------- # Get the turbulent velocity field # -------------------------------------------------------------------------------------------- if dir(mdl).__contains__('getVTurb'): if callable(getattr(mdl, 'getVTurb')): data.vturb = mdl.getVTurb(grid=grid, ppar=ppar) # Write the turbulent velocity field if ppar['grid_style'] == 1: data.writeVTurb(binary=binary, octree=True) else: data.writeVTurb(binary=binary) else: data.vturb = np.zeros([grid.nx, grid.ny, grid.nz], dtype=float64) data.vturb[:,:,:] = 0. data.writeVTurb(binary=binary) # -------------------------------------------------------------------------------------------- # Write the line RT control file # -------------------------------------------------------------------------------------------- # Write the lines.inp the main control file for the line RT writeLinesInp(ppar=ppar)
def problemSetupDust(model='', binary=True, writeDustTemp=False, old=False, dfunc=None, dfpar=None, **kwargs): """ Function to set up a dust model for RADMC-3D Parameters ---------- model : str Name of the model that should be used to create the density structure. The file should be in a directory from where it can directly be imported (i.e. the directory should be in the PYTHON_PATH environment variable or it should be in the current working directory) and the file name should be 'model_xxx.py', where xxx stands for the string that should be specified in this variable binary : bool, optional If True input files will be written in binary format, if False input files are written as formatted ascii text. writeDustTemp : bool, optional If True a separate dust_temperature.inp/dust_tempearture.binp file will be written under the condition that the model contains a function getDustTemperature() old : bool, optional If set to True the input files for the old 2D version of radmc will be created dfunc : function, optional Decision function for octree-like amr tree building. It should take linear arrays of cell centre coordinates (x,y,z) and cell half-widhts (dx,dy,dz) in all three dimensions, a radmc3d model, a dictionary with all parameters from problem_params.inp and an other keyword argument (**kwargs). It should return a boolean ndarray of the same length as the input coordinates containing True if the cell should be resolved and False if not. An example for the implementation of such decision function can be found in radmc3dPy.analyze module (radmc3dPy.analyze.gdensMinMax()). dfpar : dictionary Dicionary of keyword arguments to be passed on to dfunc. These parameters will not be written to problem_params.inp. Parameters can also be passed to dfunc via normal keyword arguments gathered in **kwargs, however all keyword arguments in **kwargs will be written to problem_params.inp **kwargs : Any varible name in problem_params.inp can be used as a keyword argument. At first all variables are read from problem_params.in to a dictionary called ppar. Then if there is any keyword argument set in the call of problem_setup_dust the ppar dictionary is searched for this key. If found the value belonging to that key in the ppar dictionary is changed to the value of the keyword argument. If no such key is found then the dictionary is simply extended by the keyword argument. Finally the problem_params.inp file is updated with the new parameter values. Notes ----- Files written by problemSetupDust() for RADMC-3D * dustopac.inp : Dust opacity master file. * wavelength_micron.inp : Wavelength grid. * amr_grid.inp : Spatial grid. * stars.inp : Input radiation field (discrete stellar sources). * stellarsrc_density.inp : Input radiation field (continuous stellar sources). * stellarsrc_templates.inp : Input radiation field (continuous stellar sources). * dust_density.inp : Dust density distribution. * radmc3d.inp : Parameters for RADMC-3D (e.g. Nr of photons to be used, scattering type, etc). """ # Read the parameters from the problem_params.inp file modpar = analyze.readParams() # Make a local copy of the ppar dictionary ppar = modpar.ppar if model=='': print 'ERROR' print 'No model name is given' return if not ppar: print 'problem_params.inp was not found' return if ppar['grid_style'] != 0: if old: print 'ERROR' print 'problemSetupDust was called with the old switch, meaning to create a model setup' print 'for the predecessor radmc code, and with the AMR activated' print 'radmc does not support mesh refinement' return # -------------------------------------------------------------------------------------------- # If there is any additional keyword argument (**kwargs) then check # if there is such key in the ppar dictionary and if is change its value that of # the keyword argument. If there is no such key in the ppar dictionary then add the keyword # to the dictionary # -------------------------------------------------------------------------------------------- if binary: modpar.setPar(['rto_style', '3', '', '']) if kwargs: for ikey in kwargs.keys(): modpar.ppar[ikey] = kwargs[ikey] if type(kwargs[ikey]) is float: modpar.setPar([ikey, ("%.7e"%kwargs[ikey]), '', '']) elif type(kwargs[ikey]) is int: modpar.setPar([ikey, ("%d"%kwargs[ikey]), '', '']) elif type(kwargs[ikey]) is str: modpar.setPar([ikey, kwargs[ikey], '', '']) elif type(kwargs[ikey]) is list: dum = '[' for i in range(len(kwargs[ikey])): if type(kwargs[ikey][i]) is float: dum = dum + ("%.7e"%kwargs[ikey][i]) elif type(kwargs[ikey][i]) is int: dum = dum + ("%d"%kwargs[ikey][i]) elif type(kwargs[ikey][i]) is str: dum = dum + (kwargs[ikey][i]) else: print ' ERROR ' print ' Unknown data type in '+ikey print kwargs[ikey][i] if i<len(kwargs[ikey])-1: dum = dum + ', ' dum = dum + (']') modpar.setPar([ikey, dum, '', '']) modpar.writeParfile() ppar = modpar.ppar # -------------------------------------------------------------------------------------------- # Create the grid # -------------------------------------------------------------------------------------------- # # Check if AMR is activated or not # if ppar['grid_style'] == 1: grid = analyze.radmc3dOctree() # Pass all parameters from dfpar to ppar if dfpar is not None: for ikey in dfpar.keys(): ppar[ikey] = dfpar[ikey] # Spatial grid grid.makeSpatialGrid(ppar=ppar, dfunc=dfunc, model=model, **kwargs) else: grid = analyze.radmc3dGrid() # Spatial grid grid.makeSpatialGrid(ppar=ppar) # Wavelength grid grid.makeWavelengthGrid(ppar=ppar) # -------------------------------------------------------------------------------------------- # Dust opacity # -------------------------------------------------------------------------------------------- if ppar.has_key('dustkappa_ext'): opac=analyze.radmc3dDustOpac() #Master dust opacity file opac.writeMasterOpac(ext=ppar['dustkappa_ext'], scattering_mode_max=ppar['scattering_mode_max'], old=old) if old: #Frequency grid grid.writeWavelengthGrid(old=old) # Create the dust opacity files opac.makeopacRadmc2D(ext=ppar['dustkappa_ext']) else: #if old: #print 'ERROR' #print 'Calculating dust opacities for radmc (2D version) is not yet implemented)' opac=analyze.radmc3dDustOpac() # Calculate the opacities and write the master opacity file opac.makeOpac(ppar=ppar,old=old) # -------------------------------------------------------------------------------------------- # Try to get the specified model # -------------------------------------------------------------------------------------------- try: mdl = __import__(model) except: try: mdl = __import__('radmc3dPy.models.'+model, fromlist=['']) except: print 'ERROR' print ' '+model+'.py could not be imported' print ' The model files should either be in the current working directory or' print ' in the radmc3d python module directory' return # -------------------------------------------------------------------------------------------- # Create the input radiation field (stars at this point) # -------------------------------------------------------------------------------------------- radSources = analyze.radmc3dRadSources(ppar=ppar, grid=grid) radSources.getStarSpectrum(tstar=ppar['tstar'], rstar=ppar['rstar']) # Check if the model has functions to set up continuous starlike sources if ppar.has_key('incl_cont_stellarsrc'): stellarsrcEnabled = ppar['incl_cont_stellarsrc'] if stellarsrcEnabled: if dir(mdl).__contains__('getStellarsrcDensity'): if callable(getattr(mdl, 'getStellarsrcDensity')): if dir(mdl).__contains__('getStellarsrcTemplates'): if callable(getattr(mdl, 'getStellarsrcTemplates')): stellarsrcEnabled = True else: stellarsrcEnabled = False else: stellarsrcEnabled = False else: stellarsrcEnabled = False else: stellarsrcEnabled = False else: stellarsrcEnabled = False if stellarsrcEnabled: dum = mdl.getStellarsrcTemplates(grid=grid, ppar=ppar) if dum[0,0]<=0.: radSources.csntemplate = dum.shape[0] radSources.cstemp = [] radSources.cstemptype = 1 radSources.cststar = dum[:,0] radSources.csrstar = dum[:,1] radSources.csmstar = dum[:,2] else: radSources.csntemplate = dum.shape[0] radSources.cstemp = dum radSources.cstemptype = 2 radSources.cststar = [] radSources.csrstar = [] radSources.csmstar = [] radSources.csdens = mdl.getStellarsrcDensity(grid=grid, ppar=ppar) # -------------------------------------------------------------------------------------------- # Create the dust density distribution # -------------------------------------------------------------------------------------------- data = analyze.radmc3dData(grid) if dir(mdl).__contains__('getDustDensity'): if callable(getattr(mdl, 'getDustDensity')): data.rhodust = mdl.getDustDensity(grid=grid, ppar=ppar) else: print 'WARNING' print ' '+model+'.py does not contain a getDustDensity() function, therefore, ' print ' dust_density.inp cannot be written' return else: print 'WARNING' print ' '+model+'.py does not contain a getDustDensity() function, therefore, ' print ' dust_density.inp cannot be written' return # -------------------------------------------------------------------------------------------- # Create the dust temperature distribution if the model has such function # -------------------------------------------------------------------------------------------- if writeDustTemp: if dir(mdl).__contains__('getDustTemperature'): if callable(getattr(mdl, 'getDustTemperature')): data.dusttemp = mdl.getDustTemperature(grid=grid, ppar=ppar) else: print 'WARNING' print ' '+model+'.py does not contain a getDustTemperature() function, therefore, ' print ' dust_temperature.dat cannot be written' return else: print 'WARNING' print ' '+model+'.py does not contain a getDustTemperature() function, therefore, ' print ' dust_temperature.dat cannot be written' return #data.rhodust = mdl.get_temperature(grid=grid, ppar=ppar) * ppar['dusttogas'] # -------------------------------------------------------------------------------------------- # Now write out everything # -------------------------------------------------------------------------------------------- if ppar['grid_style'] == 1: #Frequency grid grid.writeWavelengthGrid() #Spatial grid grid.writeSpatialGrid() else: #Frequency grid grid.writeWavelengthGrid(old=old) #Spatial grid grid.writeSpatialGrid(old=old) #Input radiation field radSources.writeStarsinp(ppar=ppar, old=old) # Continuous starlike sources if stellarsrcEnabled: radSources.writeStellarsrcTemplates() radSources.writeStellarsrcDensity(binary=binary) #totlum = radSources.getTotalLuminosities() print '-------------------------------------------------------------' print 'Luminosities of radiation sources in the model :' totlum = radSources.getTotalLuminosities(readInput=True) print 'As calculated from the input files :' print 'Stars : ' print (" Star #%d + hotspot : %.6e"%(0, totlum['lnu_star'][0])) for istar in range(1,radSources.nstar): print (" Star #%d : %.6e"%(istar, totlum['lnu_star'][istar])) print ("Continuous starlike source : %.6e"%totlum['lnu_accdisk']) print ' ' print '-------------------------------------------------------------' #Dust density distribution if ppar['grid_style'] == 1: data.writeDustDens(binary=binary, octree=True) else: data.writeDustDens(binary=binary, old=old) #Dust temperature distribution if writeDustTemp: if ppar['grid_style'] == 1: data.writeDustTemp(binary=binary, octree=True) else: data.writeDustTemp(binary=binary) #radmc3d.inp if not old: writeRadmc3dInp(modpar=modpar) else: writeRadmcInp(modpar=modpar)
def simpleRadmc3Dmodel(envelope=True, disk=True, isrf=False, shisrf=False, G=1.7): # Read the parameters from the problem_params.inp file modpar = analyze.readParams() # Make a local copy of the ppar dictionary ppar = modpar.ppar # Write out the important used parameters: # Stellar properties: print "\nStellar properties:\n" print "T_star = ", ppar['tstar'][0], "K" print "R_star = ", ppar['rstar'][0] / rs, "Rsol" print "L_star = ", (ppar['rstar'][0] / rs)**2 * (ppar['tstar'][0] / 5772.)**4, "L_sol" # Grid parameters print "\nGrid parameters:\n" print "coordinate system:", ppar['crd_sys'] print "x coordinate boundaries:", np.array(ppar['xbound']) / au, "in au" print "nx = ", ppar['nx'] print "y coordinate boundaries:", ppar['ybound'] print "ny = ", ppar['ny'] if ppar.has_key('zbound'): print "z coordinate boundaries:", ppar['zbound'] print "nz = ", ppar['nz'] else: print "z coordinate is not activated (2D model)!" if ppar.has_key('xres_nlev'): print "Refinement along x axis:" print "in ", ppar['xres_nstep'], "steps" # Wavelength grid print "\nWavelength grid:\n" print "Wavelength ranges", ppar['wbound'], "in micron" print "Bin number in range", ppar['nw'] # Envelope parameters: print "\nEnvelope parameters:\n" if envelope == True: print "Envelope is included in the model!" print "Density at 1 AU = ", ppar['rho0Env'] print "Density power law index = ", ppar['prhoEnv'] print "Opening angle [deg] = ", ppar['thetac_deg'] print "Truncation radius [au] = ", ppar['rTrunEnv'] / au else: print "*NO* envelope is included!" # Disk parameters: print "\nDisk parameters:\n" if disk == True: print "Disk is included in the model!" print "Mdisk (dust+gas) [MS] = ", ppar['mdisk'] / ms print "Rin [au] = ", ppar['rin'] / au print "Rdisk [au] = ", ppar['rdisk'] / au print "H(rdisk) = ", ppar['hrdisk'] print "Power law of H = ", ppar['plh'] print "Power law of surface density = ", ppar['plsig1'] print "Dust-to-gas = ", ppar['dusttogas'] else: print "*NO* disk is included!" # -------------------------------------------------------------------------------------------- # Create the grid # -------------------------------------------------------------------------------------------- # create the radmc3dGrid object: grid = analyze.radmc3dGrid() # create the wavelength grid grid.makeWavelengthGrid(ppar=ppar) # create the spatial grid grid.makeSpatialGrid(ppar=ppar) # -------------------------------------------------------------------------------------------- # Create the input stellar radiation field # -------------------------------------------------------------------------------------------- radSources = analyze.radmc3dRadSources(ppar=ppar, grid=grid) radSources.getStarSpectrum(tstar=ppar['tstar'], rstar=ppar['rstar']) # -------------------------------------------------------------------------------------------- # Create the dust density distribution # -------------------------------------------------------------------------------------------- # Create a radmc3dData object, this will contain the density data = analyze.radmc3dData(grid) # Creat a grid for the xx, yy = np.meshgrid(grid.x, np.pi / 2. - grid.y) xx = xx.swapaxes(0, 1) yy = yy.swapaxes(0, 1) #======================== Backgroud density =========================# rho_bg = np.zeros([grid.nx, grid.ny, grid.nz, 1], dtype=np.float64) + (ppar['bgdens'] * ppar['dusttogas']) #============ Envelope density + Cavity + Cut off radius ============# rho_env = np.zeros([grid.nx, grid.ny, grid.nz, 1], dtype=np.float64) #array for the envelope density if envelope == True: thetac = np.deg2rad(90) - np.deg2rad( ppar['thetac_deg']) #convert from degrees to radian for iz in range(grid.nz): for iy in range(grid.ny): for ix in range(grid.nx): if np.abs(yy[ix, iy]) <= np.abs(thetac) and xx[ ix, iy] >= ppar['rTrunEnv']: rho_env[ix, iy, iz, 0] = ppar['rho0Env'] * 1. / ( 1. + (xx[ix, iy] / ppar['rTrunEnv'])**ppar['prhoEnv']) #========================= Flarring disk ============================# # set up the arrays containing the disk density rho_disk_tot = np.zeros([grid.nx, grid.ny, grid.nz, 1], dtype=np.float64) # gas + dust rho_disk_dust = np.zeros([grid.nx, grid.ny, grid.nz, 1], dtype=np.float64) # only dust if disk == True: # 1) first make the gas and dust disk (i.e. total mass) rr, th = np.meshgrid(grid.x, grid.y) z0 = np.zeros([grid.nx, grid.nz, grid.ny], dtype=np.float64) zz = rr * np.cos(th) rcyl = rr * np.sin(th) # Calculate the pressure scale height as a function of r, phi hp = np.zeros([grid.nx, grid.ny, grid.nz], dtype=np.float64) dum = ppar['hrdisk'] * (rcyl / ppar['rdisk'])**ppar['plh'] * rcyl dum = dum.swapaxes(0, 1) for iz in range(grid.nz): # copy the (x,y) grid to each z coordinates hp[:, :, iz] = dum # We assume that sig0 is 1 and calculate the surface density profile: sigma = np.zeros([grid.nx, grid.ny, grid.nz], dtype=np.float64) dum1 = 1.0 * (rcyl / ppar['rdisk'])**ppar['plsig1'] # Adding the smoothed inner rim if (ppar.has_key('srim_rout') & ppar.has_key('srim_plsig')): sig_srim = 1.0 * (ppar['srim_rout'] * ppar['rin'] / ppar['rdisk'])**ppar['plsig1'] dum2 = sig_srim * ( rcyl / (ppar['srim_rout'] * ppar['rin']))**ppar['srim_plsig'] p = -5.0 dum = (dum1**p + dum2**p)**(1. / p) else: dum = dum1 dum = dum.swapaxes(0, 1) for iz in range(grid.nz): # copy the (x,y) grid to each z coordinates sigma[:, :, iz] = dum # setting the disk surface density to 0 outside of the rin and rdisk range: for iy in range(grid.ny): ii = (rcyl[iy, :] < ppar['rin']) | (rcyl[iy, :] > ppar['rdisk']) sigma[ii, iy, :] = 0.0 # We calculate the disk density using the above surface density profile: for iz in range(grid.nz): for iy in range(grid.ny): rho_disk_tot[:,iy,iz,0] = sigma[:,iy,iz] / \ (hp[:,iy,iz] * np.sqrt(2.0*np.pi)) * \ np.exp(-0.5 * ((zz[iy,:])-z0[:,iz,iy]) * \ ((zz[iy,:])-z0[:,iz,iy]) / \ (hp[:,iy,iz]*hp[:,iy,iz])) # Now we calculate the mass in rho_disk_tot and scale the density to get back the # desired disk mass (['mdisk'] parameter): if ppar.has_key('mdisk') and ppar['mdisk'] != 0.: # Calculate the volume of each grid cell vol = grid.getCellVolume() mass = (rho_disk_tot[:, :, :, 0] * vol).sum(0).sum(0).sum(0) rho_disk_tot = rho_disk_tot * (ppar['mdisk'] / mass) # 2) Now calculate the dust density by scaling the disk mass with the dust/gas ratio: rho_disk_dust = np.array(rho_disk_tot) * ppar['dusttogas'] #============== Adding up the density contributions =================# data.rhodust = rho_env + rho_disk_dust + rho_bg # -------------------------------------------------------------------------------------------- # Now write out everything # -------------------------------------------------------------------------------------------- print "\n Writing the input files:\n" #Frequency grid grid.writeWavelengthGrid(old=False) #Spatial grid grid.writeSpatialGrid(old=False) #Input radiation field radSources.writeStarsinp(ppar=ppar, old=False) # Write the external radiation field input file if needed ISradField(G, grid=grid, ppar=ppar, show=shisrf, write=isrf) #Dust density distribution data.writeDustDens(binary=False, old=False) #radmc3d.inp radmc3dPy.setup.writeRadmc3dInp(modpar=modpar) #Master dust opacity file opac = analyze.radmc3dDustOpac() opac.writeMasterOpac(ext=ppar['dustkappa_ext'], scattering_mode_max=ppar['scattering_mode_max'], old=False)