Skip to content

Collisional excitation rate uses scups delta_energy in Boltzmann factor; IDL/ChiantiPy use observed elvlc energies (~6% G(T) discrepancy at low T) #448

@jacobdparker

Description

@jacobdparker

Summary

The contribution function computed by fiasco diverges from CHIANTI IDL (and ChiantiPy) at low temperatures — e.g. ~+6% at $T = 10^5$ K for the Fe IX 171.073 Å line in the IDL comparison gallery example. The cause is that fiasco uses the scups file de (the theoretical transition energy from the original scattering calculation) in the detailed-balance Boltzmann factor of the collisional excitation rate, whereas CHIANTI IDL and ChiantiPy both use the observed energy difference from the elvlc file there.

Details

All three codes agree on the Burgess–Tully descaling of the effective collision strength — the scups de is the correct energy for the scaled temperature, and fiasco uses it there (Ion.effective_collision_strength). The difference is only in the exponential converting the de-excitation rate to the excitation rate:

  • fiasco (Ion.electron_collision_excitation_rate, fiasco/ions.py):

    kBTE = np.outer(1./self.thermal_energy, self._scups['delta_energy'])
    return omega_upper / omega_lower * self.electron_collision_deexcitation_rate * np.exp(-kBTE)
  • CHIANTI IDL (level_population/ch_load_ion_rates.pro):

    ; ecmc contains the elvlc "best" energies (observed where available)
    kte=(hck*abs(ecmc[l1]-(ecmc[l2]-ip_cm))) # (1d0/temp)
    ...
    xx[ind_pos,*]=8.63e-6* exp(-kte[ind_pos,*]) * 1./(mult[l1[ind_pos]] # sqrt(t))  ; excitation
  • ChiantiPy (Ion.upsilonDescale) uses Scups['de'] for the descaling but recomputes the energy for the exponential from elvlc, observed-first:

    elvlc = np.where(eryd >= 0., eryd, erydth)
    ...
    de = np.abs(elvlc[l2idx] - elvlc[l1idx])
    ekt = (de*const.ryd2erg)/(const.boltzmann*temp)
    exRate[iscups] = const.collision*ups[iscups]*np.exp(-ekt)/(fmult1*np.sqrt(temp))

Magnitude for Fe IX 171.073 Å

For the 1 → 13 transition in CHIANTI v11.0.2:

quantity value
elvlc observed energy of level 13 584,546 cm⁻¹ = 5.3268 Ry
scups de (matches elvlc theoretical) 580,435 cm⁻¹ = 5.2893 Ry
difference δE/k 5,915 K

Since the 1P₁ upper level is populated almost entirely by direct excitation from the ground level at low temperature, the fiasco/IDL contribution function ratio should be ≈ exp(δE/kT). Comparing fiasco (main) against the cached IDL result (goft_26_9_171.073_v11.0.2.asdf) confirms this:

     T [K]  fiasco/IDL  exp(δE/kT)
 1.000e+05      1.0616      1.0615
 1.585e+05      1.0384      1.0383
 2.512e+05      1.0233      1.0240
 1.000e+06      1.0032      1.0060
 1.000e+07      0.9998      1.0006

This fully accounts for the low-temperature divergence visible in the goft comparison example (the same effect is reproduced when comparing fiasco against ChiantiPy, which rules out database differences).

Possible fix

In electron_collision_excitation_rate, compute ΔE from the level energies (observed with theoretical fallback, i.e. what Levels.energy exposes) rather than from self._scups['delta_energy'], keeping the scups de in effective_collision_strength for the descaling.

One note on proton rates: CHIANTI IDL uses the psplups de in its proton detailed-balance exponential (de=ABS(prot_struc[i].de) in ch_load_ion_rates.pro), so fiasco's current treatment of proton rates already matches IDL; ChiantiPy is the outlier there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions