JuliaPhysics/SolidStateDetectors.jl

Charge density gradient translation

rjtayl opened this issue · 4 comments

When I create a tube object with a translation and apply a cylindrical charge density with a radial gradient the charge density it is assumed the gradient starts from the z-axis. For example:

image

Is it possible to translate the gradient so that it is centered on the object instead?

Not with the existing SSD source code, but it can easily be modified to fulfil your requirements.

As we are planning a major update on SolidStateDetectors, I would also avoid putting some work-around in the source code but rather provide a code example that you could use and modify. Once, we have refactored some parts of SSD, we will definitely take this into account and make this part of the config file read-in.

How to solve your issue (for now)

For now, I would suggest defining a new ChargeDensity, something like:

using SolidStateDetectors: AbstractChargeDensity, CartesianVector, AbstractCoordinatePoint
import SolidStateDetectors: get_charge_density

# new struct for translated charge densities
struct TranslatedChargeDensity{T} <: AbstractChargeDensity{T}
    charge_density_model::AbstractChargeDensity{T}
    translate::CartesianVector{T}
end

# add get_charge_density for the newly defined charge density model
function SolidStateDetectors.get_charge_density(tcdm::TranslatedChargeDensity{T}, pt::AbstractCoordinatePoint{T})::T where {T}
    translated_pt::CartesianPoint{T} = CartesianPoint(pt) - tcdm.translate
    return get_charge_density(tcdm.charge_density_model, translated_pt)
end

# override Base.+ function for easily constructing TranslatedChargeDensity
import Base.+
(+)(cdm::AbstractChargeDensity{T}, translate::CartesianVector{T}) where {T} = TranslatedChargeDensity(cdm, translate)
(+)(cdm::TranslatedChargeDensity{T}, translate::CartesianVector{T}) where {T} = TranslatedChargeDensity(cdm.charge_density_model, translate + cdm.translate)

This new struct allows translating any of the existing charge density models.

Minimum working example

How to implement this into your code?
Select the object in which the charge density model is saved and add the translate vector using the += syntax.

My simulation is called sim, has precision type T and has a cylindrical charge density.

T = Float64
sim = Simulation{T}("BEGE.json")
calculate_electric_potential!(sim, max_refinements = 2)
plot(sim.ρ, z = 0.02)

old_cd

If I want to translate the charge density from the bulk, which Is the first entry of the semiconductors list, I can use the += syntax:

translate = CartesianVector{T}(0,0.01,0)
sim.detector.semiconductors[1].charge_density_model += translate  # this translates the charge density
calculate_electric_potential!(sim, max_refinements = 2)
plot(sim.ρ, z = 0.02)

new_cd

Be careful not to call sim.detector.semiconductors[1].charge_density_model += translate multiple times if not intended.
Every call will translate the charge density by translate!

translate = CartesianVector{T}(0,0.01,0)
sim.detector.semiconductors[1].charge_density_model += translate  # calling this on the already translated charge density
calculate_electric_potential!(sim, max_refinements = 2)
plot(sim.ρ, z = 0.02)

new2_cd

Does that work for now?

Any comments from the SSD crew on implementing this in the source code before upgrading to v0.6?

lmh91 commented

Well, we can think about adding an origin and normal vector to our simple impurity density models (and also charge densities).

But in general, I think we should work on the documentation and advanced examples to show how one can define any density.

Does that work for now?

Yes, thank you.