secondaryEmitter

secondaryEmitter

This general secondary emitter emits (secondary) particles based on the absorption or emission of other (primary) particles. Typically, a secondary particle is emitted when a primary particle is absorbed by a ParticleSink; however, to allow correlated emission of different secondary species, the primary particle may be an emitted (rather than absorbed) particle. For example, suppose a primary ion incident upon an insulating surface has a certain probability of secondary-emitting an electron, and, for charge conservation, it is important to secondary-emit an ion at the same time (the secondary ion may remain immobile on the surface). A secondaryEmitter can be used to emit a secondary electron with appropriate probability when the primary ion hits the surface; another secondaryEmitter can then be used to emit a (possibly immobile) secondary ion whenever a secondary electron is produced, ensuring charge conservation (while it is possible to emit a secondary ion based on the same primary ion, if the emission probability is not 1, then there may be times when a secondary electron is emitted but not a secondary ion, and vice-versa). This secondaryEmitter allows great flexibility in determining the parameters of the secondary particle; hence it also requires a lengthy specification of the secondary particles’ properties.

N.B. Typically, the ptclAbsorber should only be of kind=:ref:abssavtricutcell and the same gridBoundary option should be used as in the ptclAbsorber. Using it with other absorbers is possible, but difficult.

While most other secondary emitters emit secondary particles at a randomly-chosen time within the given timestep, this emitter emits particles at the recorded absorption time.

This particle source is available with a VSimVE or VSimPD license.

Help with secondaryEmitter

The great flexibility of absorbers and secondaryEmitters sometimes means that getting secondaryEmitter to work as desired can be tricky.

First, in most cases secondaryEmitter should be used with a ptclAbsorber only of kind=:ref:abssavtricutcell, and the gridBoundary should be the same as in the ptclAbsorber.

Second, please note that <Expression velocityAndTag> specifies the velocity in a coordinate system rotated with respect to the emission surface.

If no particles are being secondary-emitted, here are some things to try. (1) Search the output for related warnings. (2) Verify that the ptclAbsorber is absorbing (primary) particles (e.g., using a speciesAbsPtclData2 History). (3) Check whether secondary particles might be emitted into or within an absorber (often a warning will be issued in that case), where they are absorbed before they can enter the simulation. (4) Verify that the secondary emitter bounds include the cells where primaries are absorbed. (5) If the suppressEnergy option is set, change it to -1 to see whether emission this is suppressing emission. (6) Set emitForPrimariesWithoutSurfaceNormal=true; if this results in secondary emission, that indicates that the primary particles are being absorbed at a location where the surface normal cannot be determined (this always happens if the absorber is not a cut-cell absorber, i.e., absSavTriCutCell). (7) Verify (in a short/small/serial simulation) that the sey is returning a (sufficiently large) positive value by enclosing the sey expression in a print() function (warning: this will print out the evaluated SEY for each absorbed particle, so if there are millions of absorbed particles, millions of lines will be printed out). Consider setting the sey to a larger value (depending on the weight of emitted particles; see the option ptclCountType).

secondaryEmitter Parameters

ptclAbsorber (string)

To emit secondaries from primary particles that are absorbed (or, more generally, that run into a ParticleSink), this option should specify the name of the ParticleSink (which must be of a kind that stores absorbed particles).

The ptclAbsorber should almost always be of kind=:ref:abssavtricutcell (with recordParticleData=true), since that is currently the only cut-cell absorber that records the exact time of absorption and the surface normal.

ptclSource (string)

(This option may be specified instead of ptclAbsorber.)

To emit secondaries from primary particles that are emitted from a ParticleSource, this option should specify the name of the particle source that emits the primary particles whose emission triggers secondary emission. If the ParticleSource emits a species other than the Species block that contains the ParticleSource, then sourceSpecies must also be specified. The ParticleSource block must specify recordParticleData=true because secondaries will be emitted based on the recorded particles.

This is typically used to allow secondary emission of a Species based on secondary emission of another Species. For example, if a primary particle should cause correlated emission of two secondary particles, the first secondary can be emitted (with some probability) base on the primary, and the second secondary can be emitted (with probability one) based on the first secondary. In this way, a neutral primary could result in secondary emission of an electron and an ion, or of neither (but never only an electron or only an ion).

sourceSpecies (string)

The name of the Species emitted by the ptclSource; this is required only if a ptclSource is specified that emits a Species other than the Species block containing the ParticleSource.

lowerBounds (integer vector, optional, default = global simulation bounds)

The lower (global cell) bounds within which a primary particle can produce secondaries.

upperBounds (integer vector, optional, default = global simulation bounds)

The upper (global cell) bounds within which a primary particle can produce secondaries.

gridBoundary (string, optional)

A gridBoundary specifying the surface from which secondaries are emitted; it is strongly recommended that this be the same gridBoundary at which primary particles are absorbed. The gridBoundary supplies the surface-normal where secondary emission occurs. If, in pathological cases, there is no surface in the cell where emission occurs, the normal will be taken to be opposite the primary particle’s velocity (cf. emitForPrimariesWithoutSurfaceNormal).

emissionDirection (vector, optional)

If no gridBoundary is specified, this gives the surface normal direction (in the direction of emission) for secondary emission.

depositCurrentFromCorner (boolean, optional, default = true)

This option should generally be true in electromagnetic simulations, especially for emission from metallic (conducting) surfaces; it avoids the creation of artificial immobile charges. In electromagnetic simulation, emitting a charge from the middle of a cell automatically creates (or rather, leads to electromagnetic fields that acts as if there were) an opposite charge that remains at the emission location forever. If this option is true, then electrical current will be deposited from a corner of the emission cell that is inside the absorber to the emission location. (Cf. emitIntoGridBoundaryInterior.)

emitIntoGridBoundaryInterior (boolean, optional, default = true)

N.B. This option has no effect on emission. It only affects the deposition of current when

depositCurrentFromCorner is true.

This should be set to true if secondary particles are supposed to be emitted into the interior of the gridBoundary (usually the case when primary particles are absorbed in the exterior), and false if secondaries are supposed to be emitted into the exterior of the gridBoundary.

If true (and depositCurrentFromCorner is true) then when a secondary particle is emitted, current will first be deposited from an exterior corner of the cell to the emission location. When false, current will be deposited from an interior corner of the cell to the emission location.

Typically the gridBoundary interior is the physical domain in which particles move, while the exterior absorbs particles (and this option should be true); If this is false, the ptclAbsorber should probably specify absorberIsInGridBoundary=true (currently, only ParticleSink absSavTriCutCell has that option).

functionVariables (vector of strings, optional, default = empty vector)

a list of quantities describing the primary particle that can be used as variables in the Expressions sey, velocityAndTag, and internVars. For example, if the sey depends on the the particle’s speed and/or kinetic energy, velocityMagnitude and/or physKineticEnergy should be included in this list and used in the sey expression.

There are many valid quantities that can be used; options are are the same as those listed under ptclAttributes in speciesBinning.

sey (block, required)

The expression <Expression sey> (see Introduction to UserFuncs and Expressions) that defines the secondary emission yield (SEY). It must be named sey, and can reference quantities listed in functionVariables that describe the particular primary particle. It must return a scalar value which is the (expected or average) number of physical secondary particles to be emitted for each physical primary particle. The interpretation of what to do if the SEY calls for a fractional secondary macroparticle, or multiple secondary macroparticles, depends on the ptclCountType option.

ptclCountType (string, optional, default = species dependent)

Describes how the emission of fractional or multiple secondary particles is handled. This parameter is optional; the default value is emitCounting for constant-weight species, and and vwCounting for variable-weight species. In the following, a primary macroparticle represents \(P\) physical particles and the expected number of secondary physical particles is \(S = P \times SEY\). Valid options are:

  • emitCounting (default for constant-weight secondaries)

    Emit multiple secondary macroparticles with default weight. I.e., if \(M\) is the default number of physical particles per secondary macroparticle, then either floor(\(S/M\)) or ceil(\(S/M\)) secondary macroparticles will be emitted, with a probability chosen so that on average \(S\) physical secondaries are emitted.

  • noCounting

    This is the same as emitCounting except that at most 1 macroparticle is emitted (i.e., either 0 or 1 secondary macroparticles). This gives the wrong result if \(S\) exceeds the default number of physical particles per secondary macroparticle. However, it may be appropriate if that situation is rare and one wants to avoid emitting a glut of secondary macroparticles on those rare occasions.

  • vwCounting (default for variable-weight secondaries)

    For variable-weight secondary species, emit a single macroparticle with weight set to represent \(S\) secondary physical particles.

autoGenerateTag (boolean, optional, default = true)

Whether a tag will be automatically generated for each secondary; if false then the velocityAndTag Expression must specify the tag.

<Expression velocityAndTag> (block, required)

(N.B.: the expression components are in a coordinate system rotated so the first coordinate is velocity normal to the emission surface. See below.)

An expression (see Introduction to UserFuncs and Expressions) that defines the velocity and (possibly) tag of the secondary particle. It must be named velocityAndTag, and can take arguments listed in functionVariables which depend on the particular primary particle. If autoGenerateTag is true then this must return 3 velocity components; if false then this must return 4 components, three velocities plus a tag for the secondary.

The tag is used only if the secondary Species is tagged.

The “velocity” components are actually the spatial four-velocity components in a coordinate system that depends on the emission surface and the primary particle. The first coordinate \(u_n\) is the component normal to the surface (and pointing out of the absorber; if gridBoundary is not specified, the direction is set by emissionDirection); the second is perpendicular to the first and in the plane of the primary particle’s velocity. The third coordinate is then normal to the first two, and in right-hand-rule order. If the primary particle is incident along the normal, then the third coordinate is the cardinal direction (e.g., +x, +y, or +z in cartesian systems) most perpendicular to the normal; and the second is then chosen normal to the first and third in right-hand order. In 2D, the third coordinate is always in the direction of the unsimulated direction, with its sign chosen so that the primary incident velocity and the cross product of the third and first coordinates are in the same drection.

(To set the velocity in the grid directions, rather than surface-oriented directions, one can use <Expression internVars>.)

The first coordinate direction, normal to the absorber surface, points out of the absorber (as defined by the absorber). Within an absSavTriCutCell absorber input block, the option absorberIsInGridBoundary determines whether the inside or the outside of the gridBoundary is considered to be the absorbing region.

<Expression velocityAndTag> will determine the internal variables (e.g., velocity, tag, weight) of the secondary particle. However, if <Expression internVars> is given, it will overwrite these internal variables. However, velocityAndTag must still be given because its results can be referenced by <Expression internVars> through the variables secInternVars_0, secInternVars_1, etc.

<Expression internVars> (block, optional)

An optional expression (see Introduction to UserFuncs and Expressions) that defines the final internal variables (e.g., velocity, tag, weight, etc.) of each secondary particle (this is an advanced feature that is rarely needed). It must be named internVars, and can reference any quantities listed in functionVariables.

In addition to quantities in functionVariables, the expression can reference the internal variables that were calcluated from :samp:<Expression velocityAndTag>, through the terms secInternVars_0, secInternVars_1, secInternVars_2, etc. (See the example below.) This can be useful because the secondary species may have internal variables other than velocity and tag, and these can only be set via <Expression internVars>, but setting the velocity directly can be painful, whereas <Expression velocityAndTag> makes it easy to use a surface-based coordinate system. This way, one can copy the results from velocityAndTag, and then modify any other internal variables.

This expression allows ultimate flexibility in setting the final internal variables of the secondary particle, but one must be very careful to understand exactly what those internal variables are.

emitForPrimariesWithoutSurfaceNormal (boolean, default = false)

Absorption of particles, especially at curved surfaces, can be complicated with finite precision computations. In pathological cases, particles may occasionally be absorbed in such a way that the surface normal (at absorption location) is unknown; that is usually because the particles are not absorbed at a surface. For example, a particle may be (intentionally or not) loaded inside an absorber, i.e., so that a particle may be absorbed without crossing the surface of the absorber. If this option is true then secondaries will still be emitted even for primaries for which no surface normal is known (in this case, the emission location is probably not the surface of the absorber, but may be deep in the bulk absorber). Typically the only reason for this to be true is if the failure to emit a secondary would result in a systematic conservation error.

suppressEnergy (float, optional, default = -1.)

If negative, this has no effect on emission. If this is zero, then emission does not occur if the electric force on the particle (at emission location) points back toward the surface, regardless of the secondary particle’s energy. If this is positive, then emission does not occur if the electric field forces the particle back toward the surface and the electric force is sufficiently strong. Specifically, the electric force on the particle, projected onto the surface normal, will be calculated; if the force is away from the surface, there is no effect (the secondary particle will be emitted). If the force is back toward the surface, then secondary emission is suppressed if the (projected) force times the cell diagonal (in Joules) exceeds (or equals) suppressEnergy. E.g., if suppressEnergy is zero, then emission will be suppressed whenever the electric force points toward the emission surface. If suppressEnergy is 1.6e-19, then emission will be suppressed (for an electron or singly-charged ion) if the electric field times the cell-diagonal-length is greater than 1 V; i.e., an emitted electron with less than 1 eV could not travel a cell-diagonal before being turned back toward the surface. If suppressEnergy is very large, then emission will not be suppressed, just as if suppressEnergy is negative. Note that the calculation of whether secondary emission is suppressed has nothing to do with the energy of primary or secondary particles, but depends only on the local electric field at the location of the primary particle. If non-negative, suppressEnergy is typically set to zero to emit only when the electric force points away from the surface, or it may set to a value on the order of typical secondary particle energy, ensuring that emission will be suppressed only if the electric force would prevent typical particles from traveling a cell-diagonal.

Example secondaryEmitter Blocks

The following secondaryEmitter emits a secondary particle with probability 1 (always), always normal to the surface with a tenth the speed of light (roughly: the spatial part of the 4-velocity is one tenth the speed of light). It also generates a tag for the secondary (applicable only if the secondary species is tagged) of 1.3.:

<ParticleSource coneSecEmitter>
  kind = secondaryEmitter
  recordParticleData = true
  gridBoundary = coneSurf
  ptclAbsorber = coneSurfSink
  functionVariables = []

  <Expression sey>
    kind = expression
    expression = 1.0
  </Expression>

  autoGenerateTag = false

  <Expression velocityAndTag>
    kind = expression
    expression = vector(0.1*299792458.0,0.,0.,1.3)
  </Expression>

  ptclCountType = emitCounting
  depositCurrentFromCorner = true
</ParticleSource>

The following secondaryEmitter emits a secondary particle, with 90 percent probability, that is specularly reflected with respect to the incident primary particle. This sets the tag of each secondary to -1. Here the internVars expression is used just as a demonstration; it doesn’t change the secondary particle properties. (Note that the first velocity component is the 4-velocity of the primary particle projected onto the surface normal pointing into the absorber; this component represents the secondary’s 4-velocity projected onto the surface normal pointing out of the absorber—i.e., the secondary’s velocity is the primary’s reflected about the surface.):

<ParticleSource specSecEmitter>
  kind = secondaryEmitter
  gridBoundary = specSurf
  ptclAbsorber = specSurfSink
  functionVariables = ['gammaVelocity_0'  'gammaVelocity_1' \
           'gammaVelocity_2'  'surfaceNormalIntoAbsorber_0' \
           'surfaceNormalIntoAbsorber_1'  'surfaceNormalIntoAbsorber_2' \
           'surfaceTangent1_0'  'surfaceTangent1_1'  'surfaceTangent1_2' \
           'surfaceTangent2_0'  'surfaceTangent2_1'  'surfaceTangent2_2']

  <Expression sey>
    kind = expression
    expression = 0.9
  </Expression>

  autoGenerateTag = false

  <Expression velocityAndTag>
    kind = expression
    expression = vector( \
     (gammaVelocity_0*surfaceNormalIntoAbsorber_0+ \
      gammaVelocity_1*surfaceNormalIntoAbsorber_1+ \
      gammaVelocity_2*surfaceNormalIntoAbsorber_2), \
    (gammaVelocity_0*surfaceTangent1_0+ \
     gammaVelocity_1*surfaceTangent1_1+ \
     gammaVelocity_2*surfaceTangent1_2), \
    (gammaVelocity_0*surfaceTangent2_0+ \
     gammaVelocity_1*surfaceTangent2_1+ \
     gammaVelocity_2*surfaceTangent2_2),\
    -1.)
  </Expression>

  <Expression internVars>
    kind = expression
    expression = vector(\
      secInternVars_0,secInternVars_1,secInternVars_2,secPtclWeight)
  </Expression>

  ptclCountType = vwCounting
  depositCurrentFromCorner = true
</ParticleSource>