A Union simulation is assembled from components of several distinct classes, always used in the same overall order:
Process components – define a scattering process (section 6.2.2).
Union_make_material – collect processes and an absorption cross section into a named material (section 6.2.3).
Geometry components – place a volume with a given material in the simulation (section 6.2.4).
Union_master – performs the actual ray tracing for all volumes defined since the previous master (section 6.2.5).
In addition, optional logger (section 6.2.7) and conditional (section 6.2.8) components can be placed to record detailed information about what happens inside a master component, and surface components (section 6.2.6) can be attached to geometries to add reflection/refraction effects at their boundaries.
Union components need no setup or cleanup components. Each one loads the Union library itself, and the library keeps the internal bookkeeping lists (of processes, materials, geometries, loggers, …) that the components communicate through, freeing them once the last Union component has finished.
An instrument that uses Union components must contain at least one Union_master; without one it fails to compile, with an error naming Union_components_need_a_Union_master_in_the_instrument. Union components placed after the last Union_master have no effect, and the simulation warns about each of them when it finishes.
Union_init and Union_stop, which older instruments place first and last among their Union components, are no longer needed. They are kept without effect, apart from a deprecation warning, so that such instruments still compile. For the same reason every Union component still accepts the string parameter init, which older instruments set to the name of their Union_init component; its value is ignored.
A process component has no physical shape of its own. It describes a single physical scattering mechanism: a function giving the inverse penetration depth (macroscopic cross section) as a function of incoming wavevector, and a function describing what happens to a ray in a scattering event. Table 6.1 lists the processes currently available; several are directly modelled on existing McStas sample components (e.g. Incoherent_process on Incoherent, Powder_process on PowderN, Single_crystal_process on Single_crystal), so users already familiar with those components will recognize most of the input parameters.
| Component | Description |
| Incoherent_process | Isotropic, elastic incoherent scattering. |
| Powder_process | Bragg scattering from a powder (based on PowderN). |
| Single_crystal_process | Bragg scattering from a single crystal (based on Single_crystal); twinning is achieved by combining two or more instances with different orientations. |
| Texture_process | Single crystal scattering with an orientation distribution (texture) rather than a single fixed orientation. |
| PhononSimple_process | A single acoustic phonon branch. |
| IncoherentPhonon_process | Incoherent one-phonon scattering. |
| AF_HB_1D_process | Antiferromagnetic \(S=1/2\) 1D Heisenberg chain. |
| Inhomogenous_incoherent_process | Incoherent scattering with a spatially varying cross section. |
| NCrystal_process | Bragg and thermal-diffuse scattering via the external NCrystal library. |
| Non_process | A placeholder process with zero scattering probability. |
| Template_process | Documented template for writing a new process. |
| Table 6.1.: | Scattering processes currently available for the Union components. |
Every process has an interact_fraction setting parameter, in the range \([0,1]\) or \(-1\) to disable. When a material combines several processes, this can be used to artificially force a certain fraction of scattering events to that process, which is useful for improving statistics on a process that would otherwise rarely be sampled (an importance-sampling technique, entirely analogous to p_interact discussed below); the resulting ray weight is corrected automatically so the simulation remains unbiased. If left at \(-1\) for every process in a material, the interact fractions default to the actual, physical scattering probabilities.
A minimal example defining an incoherent process for Vanadium:
1COMPONENT Vanadium_incoherent = Incoherent_process( 2 sigma=5.08, unit_cell_volume=13.827, packing_factor=1) 3AT (0,0,0) ABSOLUTE
A process component’s position in the instrument file is irrelevant to the physics (it has no shape); its name is what matters, since materials refer to processes by name.
A substantial set of further processes, ported from the MCViNE sample-scattering kernels, is contributed in the contrib component category rather than union (table 6.2); they follow the same Union process interface as the ones above and are used the same way. Each is paired with a standalone, non-Union component of the same name (without the _process suffix) sharing the same underlying kernel code.
| Component | Description |
| MCViNE_SQ_process | Elastic isotropic scatterer with structure factor \(S(|Q|)\) (expression or table). |
| MCViNE_SQE_process | Isotropic \(S(Q,E)\) scatterer from an analytic expression or grid, with optional final-energy focusing. |
| MCViNE_SvQ_process | Elastic scatterer with a vector structure factor \(S(Q_x,Q_y,Q_z)\) (expression or 3D grid). |
| MCViNE_E_Q_process | Isotropic dispersion: \(S(Q,E)=S(Q)\delta (E-E(Q))\) with analytic \(E(Q)\), \(S(Q)\). |
| MCViNE_E_vQ_process | Single-crystal dispersion: \(S(Q,E)=S(Q)\delta (E-E(Q))\) with analytic \(E(Q_x,Q_y,Q_z)\). |
| MCViNE_Broadened_E_Q_process | Isotropic dispersion \(E(Q)\) broadened by a Gaussian of \(Q\)-dependent width. |
| MCViNE_LorentzianBroadened_E_Q_process | Isotropic dispersion \(E(Q)\) broadened by a Lorentzian of \(Q\)-dependent width. |
| MCViNE_ConstantEnergyTransfer_process | Isotropic scatterer with a fixed energy transfer. |
| MCViNE_ConstantQE_process | Scatterer with fixed momentum transfer \(|Q|\) and energy transfer \(E\). |
| MCViNE_ConstantvQE_process | Scatterer with a fixed momentum-transfer vector \(Q\), weighted by a Gaussian in \(E\). |
| MCViNE_Phonon_CoherentInelastic_PolyXtal_process | Coherent one-phonon scattering from a powder, using a full phonon dispersion (energies and polarizations) on a grid. |
| MCViNE_Phonon_CoherentInelastic_SingleXtal_process | Coherent one-phonon scattering from a single crystal, using a full phonon dispersion on a grid. |
| MCViNE_Phonon_IncoherentElastic_process | Incoherent elastic scattering with a Debye-Waller factor. |
| MCViNE_Phonon_IncoherentInelastic_process | One-phonon incoherent inelastic scattering from a phonon density of states, optional final-energy focusing. |
| MCViNE_DGSSXRes_process | Resolution kernel for direct-geometry single-crystal spectrometers (aims at a pixel and time-of-flight window). |
| MCViNE_SANS2D_ongrid_process | SANS from a 2D \(S(Q_x,Q_y)\) map on a grid (beam along \(z\)). |
| Table 6.2.: | Processes contributed from MCViNE, in the contrib component category. |
A process does, however, use its rotation relative to ABSOLUTE to rotate its local frame. This can be used to create a small offset between two Single_crystal_process instances to describe a simple version of twinning. For that reason, always set the process rotation relative to ABSOLUTE.
Union_make_material collects one or more previously defined processes into a named material, together with the absorption cross section (as the inverse penetration depth at standard velocity, my_absorption, in m\(^{-1}\) at \(v_0=2200\) m/s):
1COMPONENT Al = Union_make_material( 2 my_absorption=100*4*0.231/66.4, 3 process_string="Al_incoherent,Al_powder") 4AT (0,0,0) ABSOLUTE
If process_string is left unset, all processes defined since the previous Union_make_material are collected automatically; giving it explicitly is recommended, since it makes the resulting material self-documenting. Two material names are reserved and always available without being explicitly defined: "Vacuum" (no processes, no absorption) and "Exit" (behaves like vacuum, but see section 6.2.4.0 below). Setting absorber=1 instead of giving a process_string creates a purely absorbing material with no scattering processes at all.
For the common case of a material that is purely NCrystal, with no other processes to combine it with, Union_NCrystal_material is a shortcut that creates the underlying NCrystal process and the material in a single component:
1COMPONENT Cu = Union_NCrystal_material(cfg="Cu_sg225.ncmat") 2AT (0,0,0) ABSOLUTE
Its absorption is derived automatically from the same NCrystal configuration string, so, unlike Union_make_material, it takes no my_absorption parameter. Use NCrystal_process together with Union_make_material instead whenever NCrystal scattering needs to be combined with other processes in the same material.
A geometry component places a volume of a given shape and material in the simulation, using the material name from Union_make_material and the ordinary AT/ROTATED keywords for position and orientation. The currently available shapes are Union_box, Union_cylinder, Union_sphere, Union_cone and Union_mesh (an arbitrary triangle mesh, for shapes not covered by the other primitives). No ray tracing happens in a geometry component itself – it only registers the volume with the following Union_master.
Every geometry component shares a common set of setting parameters, summarized in table 6.3, in addition to its own shape-specific dimensions (e.g. radius/yheight for Union_cylinder, xwidth/yheight/zdepth for Union_box).
| Parameter | Description |
| material_string | Name of a material from Union_make_material, or "Vacuum"/"Exit". |
| priority | Unique priority value; the volume with the highest priority wins where volumes overlap (section 6.1.1). |
| p_interact | Forces this probability [0-1] for a scattering event when a ray is inside the volume, regardless of path length (importance sampling; see note below). |
| visualize | Set to 0 to hide this volume in mcdisplay. |
| mask_string, mask_setting | Turn this volume into a mask restricting one or more other volumes (section 6.2.4.0). |
| number_of_activations | Number of subsequent Union_master components this volume should be simulated by (section 6.2.4.0). |
| surface_string parameters | Attach Union surface components (section 6.2.6) to this volume’s faces. The exact parameter names are shape-specific: Union_sphere has a single surface (plus cut_surface for internal cuts from being overlapped); Union_box and Union_cylinder instead expose one parameter per face (e.g. plus_x_surface/minus_x_surface/…for the box, curved_surface/top_surface/bottom_surface for the cylinder), plus a convenience all_face_surface to set every face at once. See the Component Manual for the exact list per shape. |
| target_index/ | Standard McStas focusing parameters, used by any process assigned to this volume’s material that supports focusing. |
| Table 6.3.: | Setting parameters common to all Union geometry components. |
1COMPONENT cryostat_wall = Union_cylinder( 2 radius=0.1, yheight=0.2, priority=10, material_string="Al") 3AT (0,0,0) RELATIVE sample_position 4 5COMPONENT cryostat_vacuum = Union_cylinder( 6 radius=0.09, yheight=0.2, priority=11, material_string="Vacuum") 7AT (0,0.01,0) RELATIVE sample_position
Here the vacuum cylinder (higher priority) hollows out the aluminium wall, and by displacing it 1 cm upward a solid bottom is left while the top stays open – a simple, direct application of the overlap-by-priority rule from section 6.1.1.
Unlike p_interact in an ordinary McStas sample component, p_interact on a Union volume applies at every step of the multiple scattering loop, not just once. Setting it to 50%, for instance, gives a 25% chance of two scattering events in that volume. It is therefore best kept well below 1; values close to 1 lead to very high probabilities of high-order multiple scattering and correspondingly large statistical weight corrections.
A mask volume restricts one or more other (masked) volumes: a ray only sees the masked volume’s material where the masked volume and the mask volume(s) both cover the same space. This gives additional geometric freedom beyond what overlap-by-priority alone provides, and often reduces the number of volumes needed for an intricate shape. A masked volume can have several masks; mask_setting ("All" or "Any", default "All") controls whether every mask or just any one of them must cover a point for the masked volume to apply there. A mask volume is set via mask_string (a comma-separated list of the geometry names it masks) rather than material_string.
Normally, once a ray enters the region of space covered by a Union_master, it stays inside the Union ray-tracing loop until it escapes all defined volumes. Sometimes it is useful to break out of this loop early – for example to place an ordinary McStas monitor or component somewhere inside an otherwise Union-simulated geometry (a detector inside a detector tank, say). Assigning a volume the special material "Exit" achieves this: once a ray enters an exit volume, the current master stops and the next McStas component in the instrument sequence runs as normal; the ray does not automatically return to the Union simulation afterwards.
number_of_activations (default 1) controls how many subsequent Union_master components will simulate a given volume, which is useful when a static piece of geometry (a magnet, say) should be present across more than one master section of the instrument without redefining it.
Union_master is where the actual ray tracing happens – it is the component that is placed into the ordinary linear McStas component sequence, and by default it simulates every volume defined since the previous master (or, for the first master, since the start of the instrument). If a volume is defined after the last Union_master in the file, it will never be simulated – remember to place a master after your geometry.
1COMPONENT sample = Union_master() 2AT (0,0,0) RELATIVE sample_position
Several of Union_master’s own setting parameters control the tagging system (section 6.2.9) and numerical safety limits; see its entry in the Component Manual’s Union chapter for the complete list. A GPU-enabled variant, Union_master_GPU, is available for use with the OpenACC build (see the User Manual’s chapter on running McStas, section on GPU acceleration); the regular Union_master does not run on GPU.
The SCATTER keyword is used internally, in a non-standard way, to mark every point where a ray moves from one volume to another, so that mcdisplay can show the resulting path. A variable number_of_scattering_events and an array scattered_flag (indexed by volume) are made available for use in an EXTEND block on the master, if you want to set your own custom flags based on where and how many times a ray scattered:
1COMPONENT sample = Union_master() 2AT (0,0,0) RELATIVE sample_position 3EXTEND 4%{ 5 if (number_of_scattering_events > 0) scattered_flag = 1; else scattered_flag = 0; 6%}
Surface components describe physics that happens at the boundary of a volume rather than throughout its bulk – reflection and refraction, as opposed to the scattering and absorption described by processes. Mirror_surface implements standard supermirror-style specular reflectivity (the same \(R_0\)/\(Q_c\)/\(\alpha \)/\(m\)/\(W\) parametrization, or a reflectivity data file, as used elsewhere in McStas); a Template_surface is provided for writing new surface types. A surface component is attached to a geometry’s surface parameter (its outer faces) or cut_surface parameter (faces created where the volume is cut by being overlapped by a higher-priority volume), by name, exactly like a process is attached to a material. Refraction and reflection handling are toggled globally on Union_master via its enable_refraction/enable_reflection parameters (both on by default).
Because so much of the simulation happens inside one master component, it is not possible to insert an ordinary McStas monitor inside the Union ray tracing to see what is going on there. Logger components fill this gap: attached to one or more volumes (and optionally further restricted to specific process names via target_process), a logger records information about every scattering event that happens there and writes it out as an ordinary McStas monitor data file. Leaving target_geometry empty logs all volumes, including ones not yet defined at the point the logger appears in the instrument file. Table 6.4 lists the currently available loggers; several further restrict what gets logged via an order_total/order_volume/order_volume_process parameter, so that only e.g. the first scattering event in a given volume is recorded.
| Component | Logs |
| Union_logger_1D | Time or \(|\mathbf {q}|\) in a 1D histogram. |
| Union_logger_2DQ | \((q_i,q_j)\) for a chosen pair of \(x,y,z\). |
| Union_logger_2D_kf | As above, but the components of the final wavevector. |
| Union_logger_2D_kf_time | As above, with an additional time axis. |
| Union_logger_2D_space | Scattering position, 2D projection. |
| Union_logger_2D_space_time | As above, with an additional time axis. |
| Union_logger_3D_space | Scattering position in full 3D. |
| Table 6.4.: | Logger components currently available for the Union components. |
A parallel set of absorption loggers (Union_abs_logger_1D_space, _2D_space, _1D_time, _event, _nD, and time-of-flight/ wavelength variants) record where and when absorption events happen instead of scattering events, which is often exactly what is needed for background studies of shielding and sample-environment components.
A logger on its own shows where scattering happens; a conditional component answers the complementary question of what ends up contributing to a particular part of the final result. A conditional modifies one or more named loggers (via target_loggers) so that they only actually record an event if the ray’s final state – once it finally leaves the Union simulation – satisfies some condition. Union_conditional_standard filters on final time and/or energy range and/or total scattering order; Union_conditional_PSD additionally requires the ray to intersect a virtual position-sensitive detector. Several conditionals can be applied to the same logger, in which case all of them must be satisfied. Setting master_tagging=1 instead applies the conditional to the tagging system (section 6.2.9) of the next master component, rather than to a specific logger.
Combining a position or scattering-vector logger with a conditional that filters, say, on a background region of the final detector signal, lets you directly inspect which volumes and processes actually contributed to that background – without having to re-run the simulation for each new question, as manual EXTEND-based tagging would require.
Independently of the logger system, Union_master can record a simple history for every ray: the ordered sequence of volumes entered and scattering processes undergone. All rays sharing the same sequence of volumes/processes count as the same history; histories are collected and, at the end of the simulation, written to a file (by default Union_history.dat) sorted by the total intensity they represent. An excerpt for a simple aluminium-can-with-powder setup:
1V0 : Surrounding vacuum 2V1 : powder_container Material: Al P0: Al_incoherent P1: Al_Powder 3V2 : powder_inside_container Material: Cu_powder P0: Cu_incoherent P1: Cu_powder 4----- Histories sorted after intensity ----- 512221626 I=4.188166E-06 V0 6 1882051 I=1.052731E-06 V0 -> V1 -> V2 -> V1 -> V0 7 1517013 I=6.213315E-07 V0 -> V1 -> V0 8 188661 I=8.043799E-08 V0 -> V1 -> V2 -> P0 -> V1 -> V0
VX refers to volume number X, PX to process number X within whatever volume precedes it in the string (so P0 after V1 and P0 after V2 are generally different physical processes, if V1 and V2 have different materials). This is invaluable for background investigations: to estimate how much intensity originates from scattering in a particular volume, search the history file for occurrences of "VX -> P"; to find only the part of that which reaches a particular detector, combine it with an exit volume placed there and search for histories ending in that volume’s number. Tagging is controlled by Union_master’s enable_tagging and history_limit parameters (the latter caps memory use by limiting the number of distinct histories retained).