Пример #1
0
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

     
Пример #2
0
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
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)