Skip to content

Simulation

nsoblath edited this page May 21, 2014 · 3 revisions

At this point, we have almost-completely setup the geometry, including defining the different shapes that will be used, and placing them with respect to one another in the arrangement that we need, as well as adding "extended" information to those geometry elements, such as colors for visualization and boundary conditions and meshing details for the electromagnetic simulations.

Now we'll complete the geometry, and define everything that we need to simulate, and how it gets put together.

Some Initial Details

The config file, QuadrupoleTrapSimulation.xml, begins with some administrative details:

  • defining directories for log files to be output to, and to look in for included configuration files,
  • setting the verbosity of the terminal and log output from different parts of Kassiopeia.

The config_path value is particularly important if you are including other configuration files (as is done in this example). You must specify the directory in which they are found.

<define name="log_path" value="/Users/nsoblath/My_Documents/KATRIN/MC/Kasper/install/log/Kassiopeia/QuadrupoleTrap"/>
<define name="config_path" value="/Users/nsoblath/My_Documents/KATRIN/MC/Kasper/install/config/Kassiopeia/QuadrupoleTrap"/>

<messages>
    <file path="[log_path]" base="QuadrupoleTrapLog.txt"/>
    <message key="k_file" terminal="normal" log="warning"/>
    <message key="k_initialization" terminal="normal" log="warning"/>
    <message key="kg_core" terminal="normal" log="warning"/>
    <message key="kg_shape" terminal="normal" log="warning"/>
    <message key="kg_mesh" terminal="normal" log="warning"/>
    <message key="kg_axial_mesh" terminal="normal" log="warning"/>
    <message key="ks_object" terminal="normal" log="normal"/>
    <message key="ks_operator" terminal="normal" log="normal"/>
    <message key="ks_field" terminal="normal" log="normal"/>
    <message key="ks_generator" terminal="normal" log="normal"/>
    <message key="ks_trajectory" terminal="normal" log="normal"/>
    <message key="ks_interaction" terminal="normal" log="normal"/>
    <message key="ks_terminator" terminal="normal" log="normal"/>
    <message key="ks_writer" terminal="normal" log="normal"/>
    <message key="ks_navigator" terminal="normal" log="normal"/>
    <message key="ks_main" terminal="normal" log="normal"/>
    <message key="ks_run" terminal="normal" log="normal"/>
    <message key="ks_event" terminal="normal" log="normal"/>
    <message key="ks_track" terminal="normal" log="normal"/>
    <message key="ks_step" terminal="normal" log="normal"/>
</messages>

For the verbosity settings, you can independently set the verbosity that you see in the terminal and the verbosity that is put into log files. Furthermore, you can do that for each different part of Kassiopeia. That way, for example, if you want a lot of detail on what's happening in the navigation routines, you can increase the verbosity from only that part of Kassiopeia, without being flooded with messages from everything else.

Final Geometry Setup

Next we take the final step in setting up the geometry. We include the QuadrupoleTrapExtendedGeometry.xml file (which itself includes QuadrupoleTrapSimpleGeometry.xml), define the space that will make up the "world" of the simulation, and place the entire trap assembly inside that world space.

<include path="[config_path]" base="QuadrupoleTrapExtendedGeometry.xml"/>

<geometry>

    <cylinder_space name="world_space" z1="-200.0e-3" z2="200.0e-3" r="200.0e-3"/>

    <space name="world" node="world_space">
        <space name="quadrupole_trap" tree="quadrupole_trap_assembly">
            <transformation rotation_axis_angle="{60.} {90.} {90.}"/>
            <transformation rotation_axis_angle="{45.} {0.} {0.}"/>
            <transformation displacement="{5.e-3} {-5.e-3} {7.e-3}"/>
        </space>
    </space>

</geometry>

Start Defining your Simulation!

And then, we begin to tell Kassiopeia exactly what we want to simulate with the kassiopeia tag:

<kassiopeia>

Magnetic and Electric Fields

First we want to setup the solvers for the electric and magnetic fields.

Magnetic Fields

We need a field solver for the solenoid magnet. We tell it about all of the spaces that have been tagged with magnet_tag in the geometry configuration. The results of the field calculations will be cached in the file QuadrupoleTrapMagnets.kbd.

    <electromagnet_field_solver
        name="kemfield_b"
        file="QuadrupoleTrapMagnets.kbd"
        system="world/quadrupole_trap"
        spaces="world/quadrupole_trap/@magnet_tag"
    >
        <zonal_harmonic_field_solver
            number_of_bifurcations="-1"
            convergence_ratio=".99"
            convergence_parameter="1.e-15"
            proximity_to_sourcepoint="1.e-12"
            number_of_central_coefficients="500"
            use_fractional_central_sourcepoint_spacing="false"
            central_sourcepoint_spacing="2.e-5"
            central_sourcepoint_start="-50.e-3"
            central_sourcepoint_end="50.e-3"
            number_of_remote_coefficients="200"
            remote_sourcepoint_start="-1.e-1"
            remote_sourcepoint_end="1.e-1"
        />
    </electromagnet_field_solver>

Inside of the electromagnet_field_solver tags we specify the particular type of field solver that we want to use. In this case, the zonal_harmonic_field_solver.

Electric Fields

For the electric fields, we use the electrostatic_field_solver tag, again specifying the set of geometry objects tagged with electrode_tag, and caching the results of the charge density and field calculations in QuadupoleTrapElectrodes.kbd.

    <electrostatic_field_solver
        name="kemfield_e"
        file="QuadrupoleTrapElectrodes.kbd"
        system="world/quadrupole_trap"
        surfaces="world/quadrupole_trap/@electrode_tag"
        symmetry="axial"
    >
        <robin_hood_bem_solver
            tolerance="1.e-10"
            check_sub_interval="100"
            display_interval="1"
            cache_matrix_elements="true"
        />
        <zonal_harmonic_field_solver
            number_of_bifurcations="-1"
            convergence_ratio=".99"
            convergence_parameter="1.e-15"
            proximity_to_sourcepoint="1.e-12"
            number_of_central_coefficients="500"
            use_fractional_central_sourcepoint_spacing="false"
            central_sourcepoint_spacing="2.e-6"
            central_sourcepoint_start="-3.3e-3"
            central_sourcepoint_end="3.3e-3"
            number_of_remote_coefficients="200"
            remote_sourcepoint_start="-1.e-1"
            remote_sourcepoint_end="1.e-1"
        />
    </electrostatic_field_solver>

We set up two solvers, the robin_hood_bem_solver for calculating charge densities, and the zonal_harmonic_field_solver for calculating field values.

A Particle is Born: Generators

We need to tell Kassiopeia about how to generate the electrons that will be tracked. When generating a particle, there are four important initial parameters:

  • Energy -- what is the initial energy of the electron?
  • Position -- what is the initial position of the electron?
  • Direction -- in what direction is the electron traveling?
  • Time -- how is the production of electrons distributed in time during the simulation?

In this case, we'll use a "composite" generator, which takes separate components that will determine the energy, position, direction, and time parameters. For each component, there are different ways that you can choose the parameter, and several examples are used here:

For energy, we choose a fixed value. Every electron generated will have the same energy.

    <ksgen_value_fix name="val_energy_fix" value="10."/>
    <ksgen_composite_energy
        name="gen_composite_energy"
        energy_value="val_energy_fix"
    />

For position, we choose to randomly distribute the electrons in the cylindrical volume within the world/quadupole_trap (defined above). We specify start and stop values for the radial and azimuthal angle coordinates, and fix the axial coordinate.

    <ksgen_value_set name="val_r_set" value_start="2.e-4" value_stop="1.e-3" value_count="3"/>
    <ksgen_value_set name="val_phi_set" value_start="30" value_stop="360" value_count="12"/>
    <ksgen_value_fix name="val_z_fix" value="-2.5e-3"/>
    <ksgen_composite_position_cylindrical
        name="gen_composite_position_cylindrical"
        space="world/quadrupole_trap"
        r_value="val_r_set"
        phi_value="val_phi_set"
        z_value="val_z_fix"
    />

For the direction, we fix both the polar (theta) angle and the azimuthal (phi) angle:

    <ksgen_value_fix name="val_theta_fix" value="90."/>
    <ksgen_value_fix name="val_phi_fix" value="0."/>
    <ksgen_composite_direction
        name="gen_composite_direction"
        space="world/quadrupole_trap"
        theta_value="val_theta_fix"
        phi_value="val_phi_fix"
    />

All electrons will be generated with the same start times.

    <ksgen_value_fix name="val_time_fix" value="0."/>
    <ksgen_composite_time
        name="gen_composite_time"
        time_value="val_time_fix"
    />

Finally, we put the components of the composite generator together:

    <ksgen_composite_generator
        name="gen_composite_generator"
        energy="gen_composite_energy"
        position="gen_composite_position_cylindrical"
        direction="gen_composite_direction"
        time="gen_composite_time"
    />

Particle Tracking: Trajectories, Navigators, and Interactions

There are several components to tracking particles: calculating the particle trajectory, navigating amongst the geometry objects, and dealing with interactions in volumes and on surfaces. In these sections we'll define the tools that will be applied to particular regions in the simulation below in the configuration file.

Trajectories

    <kstraj_trajectory_exact name="trajectory_exact"/>
    <kstraj_interpolator_fast name="interpolator_fast"/>
    <kstraj_integrator_rk8 name="integrator_rk8"/>
    <kstraj_term_propagation name="term_propagation"/>
    <kstraj_control_cyclotron name="control_cyclotron_1_16" fraction="{1. / 16.}"/>
    <kstraj_control_cyclotron name="control_cyclotron_1_64" fraction="{1. / 64.}"/>

Navigators

We need navigators for both spaces and surfaces.

    <ksnav_space name="nav_space" time_tolerance="1.e-6" length_tolerance="1.e-6"/>
    <ksnav_surface name="nav_surface"/>

"Space" Interactions

Some interactions take place within volumes. In this case, the relevant interaction is scattering off of a gas with a constant density and cross section.

    <ksint_density_constant name="int_density_constant" temperature="300." pressure="3.e0"/>    
    <ksint_calculator_constant name="int_calculator_constant" cross_section="1.e-18"/>
    <ksint_scattering name="int_scattering" density="int_density_constant" calculator="int_calculator_constant"/>

"Surface" Interactions

Surface interactions occur when the track of a particle passes through a surface.

    <ksint_surface_specular name="int_surface_specular" probability=".01" reflection_loss="0." transmission_loss="0."/>
    <ksint_surface_diffuse name="int_surface_diffuse" probability=".01" reflection_loss="0." transmission_loss="0."/>

How to Kill a Particle: Terminators

The end of a particle's life is dealt with in the simulation by terminators. The terminators active at any given point of the simulation determine the conditions that might stop a particle.

In this case we define an arbitrary terminator simply called ksterm_death, a terminator that acts based on the maximum number of steps a particle can take, a terminator that stops a particle if it gets too far in the z direction, and a terminator that stops a particle if its energy drops below a particular threshold.

    <ksterm_death name="term_death"/>
    <ksterm_max_steps name="term_max_steps" steps="16000000"/>
    <ksterm_max_z name="term_max_z" z="1.e-5"/>
    <ksterm_min_energy name="term_min_energy" energy="2."/>

Getting your Data out: Writers and Output

Writers

We define which writers we want to have available. Writers are responsible for taking data from the simulation and writing it to a file. In this case we want to output a ROOT file that will contain a TTree. Another useful writer that is available is kswrite_vtk, which writes VTP files that are viewable in ParaView.

    <kswrite_root
        name="write_root"
        base="QuadrupoleTrapSimulation.root"
    />

Output

The output tags define what values from the simulation are put in the output file(s). The object attribute specifies which simulations objects the data comes from, and the field attribute specifies the value that is taken. The name attribute determines what the value will be called in the output file (e.g. in a ROOT file, the name of the TLeaf in the output TTree).

    <ks_output name="step_final_particle" field="final_particle" object="step"/>
    <ks_output name="position" field="position" object="step_final_particle"/>
    <ks_output name="electric_potential" field="electric_potential" object="step_final_particle"/>

    <ks_group name="output_step_world_group">
        <ks_output name="step_id" field="step_id" object="step"/>
        <ks_output name="continuous_time" field="continuous_time" object="step"/>
        <ks_output name="continuous_length" field="continuous_length" object="step"/>
        <ks_output name="time" field="time" object="step_final_particle"/>
        <ks_output name="position" field="position" object="step_final_particle"/>
        <ks_output name="momentum" field="momentum" object="step_final_particle"/>
        <ks_output name="magnetic_field" field="magnetic_field" object="step_final_particle"/>
        <ks_output name="electric_field" field="electric_field" object="step_final_particle"/>
        <ks_output name="electric_potential" field="electric_potential" object="step_final_particle"/>
        <ks_output name="kinetic_energy" field="kinetic_energy_ev" object="step_final_particle"/>
    </ks_group>

    <ks_group name="output_step_cell_group">
        <ks_output name="polar_angle_to_z" field="polar_angle_to_z" object="step_final_particle"/>
        <ks_output name="polar_angle_to_b" field="polar_angle_to_b" object="step_final_particle"/>
        <ks_output name="guiding_center_position" field="guiding_center_position" object="step_final_particle"/>
        <ks_output name="orbital_magnetic_moment" field="orbital_magnetic_moment" object="step_final_particle"/>
    </ks_group>

What Happens, and Where?

One of the unique capabilities of Kassiopeia is the facility for seamlessly adding and removing the components, or "commands" that make up the simulation depending on where a particle is located.

    <ks_group name="command_world_group">
        <ks_command parent="root_generator" field="set_generator" child="gen_composite_generator"/>
        <ks_command parent="root_magnetic_field" field="add_magnetic_field" child="kemfield_b"/>
        <ks_command parent="root_electric_field" field="add_electric_field" child="kemfield_e"/>
        <ks_command parent="root_trajectory" field="set_trajectory" child="trajectory_exact"/>
        <ks_command parent="trajectory_exact" field="set_integrator" child="integrator_rk8"/>
        <ks_command parent="trajectory_exact" field="set_interpolator" child="interpolator_fast"/>
        <ks_command parent="trajectory_exact" field="add_term" child="term_propagation"/>
        <ks_command parent="trajectory_exact" field="add_control" child="control_cyclotron_1_16"/>
        <ks_command parent="root_space_navigator" field="set_space_navigator" child="nav_space"/>
        <ks_command parent="root_surface_navigator" field="set_surface_navigator" child="nav_surface"/>
        <ks_command parent="root_terminator" field="add_terminator" child="term_max_steps"/>
        <ks_command parent="root_writer" field="add_writer" child="write_vtk"/>
        <ks_command parent="write_vtk" field="set_point" child="position"/>
        <ks_command parent="write_vtk" field="set_data" child="electric_potential"/>
    </ks_group>
    <space name="nav_world" spaces="world" object="command_world_group"/>

    <ks_group name="command_cell_group">
        <ks_command parent="trajectory_exact" field="remove_control" child="control_cyclotron_1_16"/>
        <ks_command parent="trajectory_exact" field="add_control" child="control_cyclotron_1_64"/>
        <!--
        <ks_command parent="write_root_trees" field="add_step_output" child="output_step_cell_group"/>
        -->
    </ks_group>
    <space name="nav_cell" spaces="world/quadrupole_trap/cell" object="command_cell_group"/>

    <ks_group name="command_stop_group">
        <ks_command parent="root_terminator" field="add_terminator" child="term_death"/>
    </ks_group>
    <surface name="nav_stop" surfaces="world/quadrupole_trap/stop" object="command_stop_group"/>

Finally Running the Simulation!

There are a few more important details left to specify:

  • Random number seed -- be careful with this, especially if you're combining the results of multiple simulations!
  • The run number is an identifier you can choose.
  • You should tell the simulation how many events to generate --- note that this is the number of "physics" events that are started, not necessarily the number of electrons that end up in your detector (if you had one in your simulation).
  • The geometry space in which the simulation will take place.
    <simulation
        seed="51385"
        run="1"
        events="1"
        space="world"
    />

</kassiopeia>

And that's it! We close the specification of the simulation with the close-kassiopeia tag.

Visualization Window

By adding the vtk_window tag we enable a VTK window that will open when the simulation is complete. We add the vtk_geometry_painter and the vtk_track_painter to draw the geometry and tracks, respectively.

<vtk_window 
    name="vtk_window"
    enable_display="true"
    enable_write="true"
    frame_title="KGeoBag Visualization"
    frame_size_x="1024"
    frame_size_y="768"
    frame_color_red=".2"
    frame_color_green=".2"
    frame_color_blue=".2"
    view_angle="45"
    eye_angle="0.5"
    multi_samples="4"
    depth_peeling="10"
>
    <vtk_geometry_painter 
        name="geometry_painter" 
        surfaces="world/quadrupole_trap/#"
    />
    <vtk_track_painter
        name="track_painter"
        writer="write_vtk"
        color="electric_potential"
    />
</vtk_window>