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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions