Skip to content

xgp/nabsl computed with stale wavelength when accelerating voltage changes #12

@clfnd

Description

@clfnd

Hi Marc,

I think there might be an inconsistency when the accelerating voltage changes for example in mod_EBSDmaster: setV updates the voltage, but the wavelength isn’t recomputed unless CalcWaveLength is called explicitly which seems not done... Caveat: if there’s something I missed, please correct me and this issue will be closed.

Summary

When the accelerating voltage is changed via Diff%setV(...), the electron wavelength (self%Lambda) is not recomputed unless CalcWaveLength is called explicitly. Because CalcUcg_ uses self%Lambda to compute the absorption length:

xgp = 1.0/abs(Upmod)/self%Lambda

rlp%xgp (and thus nabsl) can be incorrect after a voltage change. This leads to wrong phase/attenuation factors downstream (e.g., in lambdaE(iE,iz) *= exp( ... / nabsl)) in mod_EBSDmaster.f90.

Steps to Reproduce

1.	Initialize Diffraction_T at voltage V1.
2.	Compute nabsl (via rlp%xgp) and store it.
3.	Change voltage to V2 with call Diff%setV(dble(V2)).
4.	Immediately call Diff%CalcUcg(cell,(/0,0,0/)) and read rlp%xgp.

Observed: xgp reflects the new U' but is divided by the old Lambda, yielding an inconsistent xgp.

Expected: After changing voltage, Lambda (and related relativistic factors) should match the new voltage before CalcUcg_ uses them.

Impact

•	Incorrect absorption length xgp → wrong nabsl → wrong exponential factor in depth-dependent quantities and phase terms.
•	Can bias any energy-dependent simulation (EBSD simulations for example).
•	Hard to spot because values are “close” but systematically off.

Minimal Fix

do iE=1,numEbins
  call Diff%setV(dble(Ekevs(iE)))
  call Diff%CalcWaveLength(cell)         ! <-- required
  call Diff%CalcUcg(cell, (/0,0,0/))
  rlp   = Diff%getrlp()
  nabsl = rlp%xgp
  ...
end do

Proposed Solutions

Option A :
• Always call CalcWaveLength(cell) immediately after setV.
• Pros: No API change.
• Cons: Easy to forget; bugs can reappear.

Option B (make setV_ eager):

recursive subroutine setV_(self, V, cell)
  class(Diffraction_T),INTENT(INOUT) :: self
  real(kind=dbl),INTENT(IN)          :: V
  type(Cell_T),INTENT(INOUT)         :: cell
  self%voltage = V
  call self%CalcWaveLength(cell)
end subroutine

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions