The SKIRT project
advanced radiative transfer for astrophysics
Public Member Functions | Protected Member Functions | Private Attributes | List of all members
SecondarySourceSystem Class Reference

#include <SecondarySourceSystem.hpp>

Inheritance diagram for SecondarySourceSystem:
Inheritance graph
[legend]

Public Member Functions

 SecondarySourceSystem (SimulationItem *parent)
 
void installLaunchCallBack (ProbePhotonPacketInterface *callback)
 
void launch (PhotonPacket *pp, size_t historyIndex) const
 
int numSources () const
 
bool prepareForLaunch (size_t numPackets)
 
- Public Member Functions inherited from SimulationItem
template<class T >
T * find (bool setup=true) const
 
template<class T >
T * interface (int levels=-999999, bool setup=true) const
 
virtual string itemName () const
 
void setup ()
 
string typeAndName () const
 
- Public Member Functions inherited from Item
 Item (const Item &)=delete
 
virtual ~Item ()
 
void addChild (Item *child)
 
const vector< Item * > & children () const
 
virtual void clearItemListProperty (const PropertyDef *property)
 
void destroyChild (Item *child)
 
virtual bool getBoolProperty (const PropertyDef *property) const
 
virtual vector< double > getDoubleListProperty (const PropertyDef *property) const
 
virtual double getDoubleProperty (const PropertyDef *property) const
 
virtual string getEnumProperty (const PropertyDef *property) const
 
virtual int getIntProperty (const PropertyDef *property) const
 
virtual vector< Item * > getItemListProperty (const PropertyDef *property) const
 
virtual ItemgetItemProperty (const PropertyDef *property) const
 
virtual string getStringProperty (const PropertyDef *property) const
 
int getUtilityProperty (string name) const
 
virtual void insertIntoItemListProperty (const PropertyDef *property, int index, Item *item)
 
Itemoperator= (const Item &)=delete
 
Itemparent () const
 
virtual void removeFromItemListProperty (const PropertyDef *property, int index)
 
virtual void setBoolProperty (const PropertyDef *property, bool value)
 
virtual void setDoubleListProperty (const PropertyDef *property, vector< double > value)
 
virtual void setDoubleProperty (const PropertyDef *property, double value)
 
virtual void setEnumProperty (const PropertyDef *property, string value)
 
virtual void setIntProperty (const PropertyDef *property, int value)
 
virtual void setItemProperty (const PropertyDef *property, Item *item)
 
virtual void setStringProperty (const PropertyDef *property, string value)
 
void setUtilityProperty (string name, int value)
 
virtual string type () const
 

Protected Member Functions

void setupSelfBefore () override
 
- Protected Member Functions inherited from SimulationItem
 SimulationItem ()
 
virtual bool offersInterface (const std::type_info &interfaceTypeInfo) const
 
virtual void setupSelfAfter ()
 
virtual void setupSelfBefore ()
 
- Protected Member Functions inherited from Item
 Item ()
 

Private Attributes

vector< ProbePhotonPacketInterface * > _callbackv
 
vector< size_t > _Iv
 
double _L
 
double _Lpp
 
Array _Lv
 
vector< SecondarySource * > _sources
 
vector< double > _wv
 
Array _Wv
 
double _xi
 

Detailed Description

SecondarySourceSystem is a helper class that handles much of the complexity involved with launching photon packets from secondary sources, i.e. the emission by dust and gas media.

The class offers an interface that somewhat resembles the interface of the SourceSystem class (which holds the primary sources), facilitating the implementation of the photon life cycle for both types of sources. Also, bundling this functionality in this class avoids adding everything to the already heavy MediumSystem class.

The SecondarySourceSystem class inherits SimulationItem so that, for example, it can easily use the find() template function, but it is not part of the configurable simulation item hierarchy. Instead, if secondary emission is enabled in the configuration, the MonteCarloSimulation class creates and holds a single instance of the SecondarySourceSystem class. Evidently, the SecondarySourceSystem object closely interacts with the MediumSystem object in the configuration, which actually holds the media representing the secondary sources, in addition to the radiation field obtained by tracing photon packets through these media.

The functions in this class other than those for constructing and setting up assume that a set of photon packets have already been launched for a prior simulation segment, and that radiation field information has been accumulated during the life cycles of these packets by calling the MediumSystem::storeRadiationField() function. Furthermore, the MediumSystem::communicateRadiationField() function must have been called. If this is not the case, the behavior of the functions in this class is undefined.

Media types

The SecondarySourceSystem class supports secondary emission from dust and/or gas medium components depending on the configured simulation mode. The DustAndGasEmission simulation mode allows emission from both media types; the DustEmission mode allows emission from dust and ignores emission from any other media types; and the GasEmission mode allows emission from gas and ignores emission from any other media types. In the current implementation, electron media types never have any secondary emission.

For a medium component to support dust emission, it must be configured with a material mix for which the MaterialMix::materialType() function returns MaterialType::Dust. The current implementation assumes that all material mixes returning this type support secondary emission and use the same wavelength grid for discretizing the continuum emission spectrum. Specifically, the implementation assumes that for these material mixes, the MaterialMix::hasContinuumEmission() function returns true and the MaterialMix::emissionWavelengthGrid() function returns the same wavelength grid as the one returned by the Configuration::dustEmissionWLG() function. This allows combining all dust components into a single secondary source. In other words, for each spatial cell, a single aggregate dust emission spectrum is calculated reflecting all dust contents of the cell, and photon packets are emitted from this aggregate spectrum.

For a medium component to support gas emission, it must be configured with a material mix that is a subclass of the abstract EmittingGasMix base class and that further adheres to the following requirements: the MaterialMix::materialType() function returns MaterialType::Gas (the default value implemented by EmittingGasMix) and at least one of the MaterialMix::hasContinuumEmission() and MaterialMix::hasLineEmission() functions returns true. Each emitting gas component is handled as a separate secondary source; in other words gas medium components are not aggregated.

Spatial cell libraries for dust emission

To accelerate processing in cases where the calculation of the secondary emission spectra is overly resource intensive, the SecondarySourceSystem class optionally supports a library mechanism as described by Baes et al. (2011, ApJS, 196, 22). This library mechanism is limited to emission from dust media.

If so configured by the user, instead of calculating the emission spectrum individually for every spatial cell in the system, a library is constructed and template spectra from this library are used. Obviously, the templates in the library should be chosen/constructed in such a way that they can reasonably approximate the whole range of actual secondary emission spectra encountered in the simulation. Different subclasses of the SpatialCellLibrary class achieve this goal to different degrees of sophistication. Specifically, a SpatialCellLibrary subclass calculates a mapping from each spatial cell \(m\) to the corresponding library entry \(n\) using a particular heuristic, given the current state of the simulation (i.e. the stored radiation field and/or media state).

Important note: The calculation of the template spectrum for each library entry assumes that all cells mapped to the entry have the same material mix (for each medium component). As a result, employing a library scheme other than the AllCellsLibrary (which implements the identity mapping and hence essentially no library) does not make much sense in simulations with spatially varying material mixes.

Supporting the library mechanism complicates the procedure described below for distributing photon packets over cells. After obtaining the mapping from spatial cells to library entries, the prepareForLaunch() function sorts the cells so that all cells mapped to the same library entry are consecutive. This allows the launch() function, in turn, to calculate and cache information relevant for each library entry and reuse that information for subsequent cells as long as they map to the same library entry.

The launch() function allocates a private DustCellEmission object for each execution thread. When presented with a new library entry, this object first determines the average radiation field for all spatial cells mapped to the entry. Then, it calls on the DustEmissivity object held by the media system to actually calculate the emissivities corresponding to the library entry. If the medium system contains multiple dust components \(h\), each with its own material mix, the emissivity \(\varepsilon_{n,h,\ell}\) is calculated for each medium component \(h\) seperately, and the results are combined into the complete emission spectrum for a spatial cell \(m\) through

\[ j_{m,\ell} = \sum_{h=0}^{N_{\text{comp}}-1} \rho_{m,h} \, \varepsilon_{n,h,\ell} \]

where \(\ell\) is the wavelength index. Finally, this spectrum is normalized to unity. Since the densities \(\rho_{m,h}\) differ for each spatial cell, the result must be calculated and stored for each cell separately. If the medium system has only a single dust component, the above formula reduces to \(j_{m,\ell} =\rho_m\, \varepsilon_{n,\ell}\), so that the normalized emission spectrum is identical for all spatial cells that map to a certain library entry.

Distributing photon packets

One key task of the SecondarySourceSystem object is to distribute photon packet launches across the secondary dust and/or gas sources and across the spatial grid used to discretize the media in the simulation. In principle, this should/could be achieved by randomly selecting a source and a spatial cell for each launch through sampling from an appropriate probability distribution. However, similar to the situation with some primary sources (see the documentation of the SourceSystem class), a deterministic approach allows significant performance optimizations. Because the number of photon packets should be and usually is substantially larger than the number of sources and spatial cells, a deterministic approach can be considered to be equivalent to the randomized procedure.

The idea is to iterate through the sources, and for each source through the spatial cells, and launch consecutive photon packets from each. The implementation can now construct and cache relevant data structures (such as the emission spectrum and the corresponding cumulative distribution) for each source/spatial cell combination, and release the information as soon as the iteration moves on to the next combination. Because photon packets can (and often are) launched in parallel, these data structures must be allocated in thread-local storage, but that is only a minor complication.

For each secondary emission segment (i.e. a sequence of photon packet launches) in the simulation, the MonteCarloSimulation object uses the following procedure. It first determines the number of photon packets to be launched from the simulation configuration. This number \(N\) is passed to the SecondarySourceSystem::prepareForLaunch() function in serial mode. Subsequently, the MonteCarloSimulation object launches \(N\) photon packets in (potentially) parallel mode, labeling each of the packets with a history index in the range \(0,...,N-1\). While parallel execution threads are working on photon packets in various chunks of this range, each thread handles photon packets with consecutive history indices within a given chunk.

To achieve the goals described above, the SecondarySourceSystem::prepareForLaunch() function maps consecutive history index ranges to each of the source/spatial cell combinations. In a first step, the number of photon packets allocated to each secondary source is determined as follows:

\[ N_s = \left[ (1-\xi) \frac{w_s L_s}{\sum_s w_s L_s} + \xi \frac{w_s}{\sum_s w_s} \right] N \]

where \(N\) is the total number of photon packets to be launched, \(N_s\) is the number of photon packets to be launched by source \(s\), \(L_s\) is the bolometric luminosity of source \(s\), \(w_s\) is the sourceWeight property value for source \(s\), and \(\xi\) is the sourceBias property value of the secondary source system. For the purposes of this calculation, all dust emission is aggregated into a single source and each emitting gas component is handled individually, as explained above. The sourceWeight \(w_s\) for the aggregated dust emission is configured in DustEmissionOptions, while for each gas component this option is configured with the corresponding EmittingGasMix material mix. The sourceBias \(\xi\) of the secondary source system is configured in SecondaryEmissionOptions.

Once the photon packets have been distributed across the sources, the number of photon packets allocated to each spatial cell for source \(s\) is determined as follows:

\[ N_m = \left[ (1-\xi) \frac{L_m}{\sum_m L_m} + \frac{\xi}{M} \right] N_s \]

where \(N_s\) is the total number of photon packets to be launched for the source, \(N_m\) is the number of photon packets to be launched for this source by spatial cell with index \(m\), \(L_m\) is the bolometric luminosity for this source of cell \(m\), \(M\) is the total number of spatial cells, and \(\xi\) is the spatialBias property value configured in SecondaryEmissionOptions.

Constructor & Destructor Documentation

◆ SecondarySourceSystem()

SecondarySourceSystem::SecondarySourceSystem ( SimulationItem parent)
explicit

This constructor creates a SecondarySourceSystem object; it should be invoked only if the simulation configuration includes a MediumSystem object and secondary emission is enabled. Before the constructor returns, the newly created object is hooked up as a child to the specified parent in the simulation hierarchy (so it will automatically be deleted), and its setup() function has been called.

Member Function Documentation

◆ installLaunchCallBack()

void SecondarySourceSystem::installLaunchCallBack ( ProbePhotonPacketInterface callback)

This function installs the specified interface as photon packet launch call-back. The function probePhotonPacket() provided by the interface will be called for each photon packet that is ready to be launched.

◆ launch()

void SecondarySourceSystem::launch ( PhotonPacket pp,
size_t  historyIndex 
) const

This function causes the photon packet pp to be launched from one of the secondary sources, depending on the specified history index. The photon packet's contents is fully (re-)initialized so that it is ready to start its lifecycle.

◆ numSources()

int SecondarySourceSystem::numSources ( ) const

This function returns the number of secondary sources in the secondary source system.

◆ prepareForLaunch()

bool SecondarySourceSystem::prepareForLaunch ( size_t  numPackets)

This function prepares the mapping of history indices to sources and tells all sources to prepare their individual mapping of history indices to spatial cells. The function returns false if the total bolometric luminosity of the secondary sources is zero (which means no photon packets can be launched), and true otherwise.

◆ setupSelfBefore()

void SecondarySourceSystem::setupSelfBefore ( )
overrideprotectedvirtual

This function constructs a secondary source object for each enabled secondary source in the simulation, and stores these objects in a list for later use.

Reimplemented from SimulationItem.


The documentation for this class was generated from the following file: