Wiki

Clone wiki

Sunrise / SunriseSpecialOccasions

Introduction

If you want to use Sunrise to do something more specialized than just run hydro snapshots, the standard executables won't work. In this case, you need to use Sunrise as a library and manually set up source distributions, build the grid, and set up the cameras. This is the way most of the examples in the /test directory works.

The structure for running such a case is in the file analytic_case.h. To define a setup, the user has to include that file and define the following:

  • A function add_custom_options that adds the required command-line options to a boost::program_options description.
  • A function print_custom_options that prints out the options defined above. (This is just so the parameters are output when the job is run.)
  • A function description that returns a string describing the problem setup.
  • A factory class that defines the structure of the octree and the dust densities in the cells.
  • A setup function that creates the grid_factory, dust_model, emission, and emergence objects.
  • An (optional) pre_shoot function which can do analysis on the realized grid

The factory class

A factory class needs to expose these methods:

  • bool refine_cell_p(const T_cell_tracker&)
  • bool unify_cell_p(const T_cell_tracker&, const T_racc&)
  • T_data get_data(const T_cell_tracker&)
  • int n_threads()

The types are defined in the analytic_case.h file. The cell_tracker is the grid traversal object that points to a cell. It defines getmin(), getmax() and getsize() for the cell pointed to. You can get the refinement level of the cell from the Hilbert code object you get with code(), and the pointer to the actual cell with cell().

The refine/unify predicates are supposed to return whether a given cell should be refined or unified. The T_racc object is a refinement_accuracy_data which contains the sum and sum of squares of the subcells that may be unified. From this you can, for example, calculate the standard deviation of the densities in the cells and decide whether unifying them is acceptable.

The get_data() method is called for all leaf cells. It's supposed to return the data object in the cell. The T_data type is a typedef for cell_data<T_emitter, T_absorber> and the salient part is that the density member of the absorber should be set to the dust density in the cells.

The n_threads method just determines how many threads the parallel grid build will run on.

These methods are the ways in which the grid building functionality will use the factory class. It can do whatever is necessary to accomplish this task. The user creates the object in the setup method below, so other methods can be called freely from there. Note that the factory object must be thread safe, as these methods will be called for different cells from any number of threads.

The setup function

The setup function has signature

void setup (po::variables_map& opt)
The variables_map object contains the command-line options. The job of setup is to ultimately call the function run_case, which has the following signature:
template<typename T_factory>
void run_case(po::variables_map opt, 
          T_factory& factory,
          const T_unit_map& units,
          const array_1& lambda,
          vec3d gridmin,
          vec3d gridmax,
          T_emission& emission,
          T_emergence& cameras,
          T_dust_model& model);

It's thus supposed to create the objects necessary to call run_case. The factory object has already been explained. The units defines the units of the problem. The lambda array defines the wavelengths used in the calculation. gridmin and gridmax are 3-vectors defining the extent of the octree root node, i.e., the calculation volume. The T_emission object represents the primary source of radiation. (There are many different emission objects, like point sources and a uniform external illumination, defined in emission.h). T_emergence is a typedef for full_sed_emergence and defines the location, resolution, etc of the cameras used to record the radiation. Finally, the T_dust_model object specifies the type of dust in the cells.

The other functions

The other functions just define the parameters used in the problem. It should be straightforward to figure out how to do it by looking at an existing case.

An example

To see an example of how all this works, look at ir_thick_test.cc in the /test directory. This defines the simplest possible case: a central blackbody point source embedded in a constant-density sphere with a specified optical depth.

Updated