Add adapt_to_depletion_and_bias_voltage!#612
Conversation
dd43303 to
fe61010
Compare
…and tests - Export `adapt_to_depletion_and_bias_voltage!`. - Add input validation: depletion and operating voltages must share the same (non-zero) sign and `abs(op) > abs(dep)` (detector over-depleted at bias). - Add a docstring describing the impurity-rescaling / superposition mechanism. - Add tests covering the round-trip (adapt then re-estimate), an in-place re-solve, and a comparison against a freshly built equivalent simulation.
fe61010 to
10e4637
Compare
|
Can you let me know once you’re done force pushing for me to look at this PR? 😅 |
|
Sorry Im done. Just some last minute naming changes for consistency |
fhagemann
left a comment
There was a problem hiding this comment.
This looks like a very useful function and I think it would be a nice addition to SSD.
I have some comments on the name of the function, the requirement of having to pass BOTH a target depletion and bias voltage, the docstring, and error handling in the tests :)
|
|
||
| See also [`estimate_depletion_voltage`](@ref). | ||
| """ | ||
| function adapt_to_depletion_and_bias_voltage!(sim::Simulation{T}, dep::RealQuantity, bias::RealQuantity; |
There was a problem hiding this comment.
I feel like we can probably find a better name to make clear that ONLY the electric potential (but e.g. not the electric field) is updated.
- Can we avoid the verb
adaptto avoid confusion withadaptfrom Adapt.jl? I know we usedadaptfor the internal function to map the grids of electric and weighting potentials, but for an exported function I would like to be a bit more careful with wording. - It would also be nice to have a method that doesn't expect a
biasand just lets thebiasremain whatever it was before. Same thing if someone were to just change the bias without planning on changing the depletion voltage. Would it make sense to split this into two functions (one called something likeupdate_electric_potential_to_match_depletion!and the other oneupdate_electric_potential_to_match_bias!-- these are probably not the best names to choose from), which are then called by this overall function that allows to change both if wanted? Not sure what's the best way to go here, so I'm open for suggestions.
There was a problem hiding this comment.
I am in favor of splitting it into update_electric_potential_to_match_depletion! and update_electric_potential_to_match_bias!. But I would not add a third function that calls both. I am happy with the names you chose
There was a problem hiding this comment.
I'm not sure I like the verb update, because that's usually the verb we use to actually run the SOR, and this is explicitly not doing that, though 😅
There was a problem hiding this comment.
So if there's any suggestion other than update or adapt, I'd be happy to discuss :)
| dep_target = 2000u"V" | ||
| bias_target = 2500u"V" | ||
| imp_model_before = sim.detector.semiconductor.impurity_density_model | ||
| adapt_to_depletion_and_bias_voltage!(sim, dep_target, bias_target, check_for_depletion = false, verbose = false) |
There was a problem hiding this comment.
Can you also add tests to show that the errors are thrown correctly?
| bias::T = _parse_value(T, bias, internal_voltage_unit) | ||
| @assert dep * bias > 0 "The depletion voltage ($(dep)$(internal_voltage_unit)) and operating voltage ($(bias)$(internal_voltage_unit)) must have the same (non-zero) sign." | ||
| @assert abs(bias) > abs(dep) "The operating voltage ($(bias)$(internal_voltage_unit)) must exceed the depletion voltage ($(dep)$(internal_voltage_unit)) in magnitude (the detector must be over-depleted)." | ||
| dep_sim = _parse_value(T, estimate_depletion_voltage(sim; contact_id = contact_id, verbose = verbose, kwargs...), internal_voltage_unit) |
There was a problem hiding this comment.
Would it make sense to allow the user to pass the expected depletion voltage also to the function? I can't judge how long estimate_depletion_voltage takes, especially if sim.electric_potential and sim.weighting_potentials[contact.id] are already defined on the same grid.
| verbose::Bool = true, | ||
| kwargs...) where {T <: AbstractFloat} | ||
| if ismissing(sim.weighting_potentials[contact_id]) || sim.weighting_potentials[contact_id].grid != sim.electric_potential.grid | ||
| _adapt_weighting_potential_to_electric_potential_grid!(sim, contact_id) |
There was a problem hiding this comment.
In _adapt_weighting_potential_to_electric_potential_grid!, we run update_till_convergence! and essentially change the weighting potential (grid + update till convergence).
This contradicts the docstring saying that it is not re-solving anything. Maybe make this clearer?
Summary
Added
adapt_to_depletion_and_bias_voltage!.adapt_to_depletion_and_bias_voltage!(sim, dep, bias)adapts aSimulationin place to a target depletion voltagedepand operating (bias) voltagebiasby rescaling the impurity density component of the electric potential (f = dep / dep_sim) and swapping in the bias contact potential via superposition — without re-solving the field. Note that the actualsim.detector.semiconductor.impurity_density_modelandsim.detector.contacts[id].potentialfields are also modified in place to reflect the change.Tests check that this is performed correctly, and that after
adapt_to_depletion_and_bias_voltage!is run on a simulation, a subsequentcalculate_electric_potential!returns compatible results.This is then compared to the manual way a user would have to do things: initializing a fresh simulation, modifying the
sim.detector.semiconductor.impurity_density_modelandsim.detector.contacts[id].potentialfields and then runningcalculate_electric_potential!.This function is useful when the user wants to modify the simulation on the fly to reflect real-world conditions: a different measured depletion voltage and changing operating voltages without having to recalculate the electric potential. Note that in this process the weighting potential will be calculated and populated in the simulation.
Note that this only works on depleted simulations. This check is done when
estimate_depletion_voltageis called internally.Changes
adapt_to_depletion_and_bias_voltage!.depandbiasmust share the same (non-zero) sign, andabs(bias) > abs(dep)(the detector must be over-depleted at the operating voltage). Both polarities are supported.test/test_depletion.jl:biasand the re-estimated depletion voltage ≈dep;bias) reproduces the same depletion voltage.Testing
test/test_depletion.jlpasses locally (11/11).