diff --git a/examples/example_config_files/ThermalDiffusionLithiumDensity/Thermal_Diffusion_Config.yml b/examples/example_config_files/ThermalDiffusionLithiumDensity/Thermal_Diffusion_Config.yml new file mode 100644 index 000000000..a15522bcd --- /dev/null +++ b/examples/example_config_files/ThermalDiffusionLithiumDensity/Thermal_Diffusion_Config.yml @@ -0,0 +1,19 @@ +model: ThermalDiffusionLithiumDensity +material: HPGe + +impurity_density_profile: + annealing_temperature_ranges: + low_T: + T_min: 473K + T_max: 873K + D0: 2.5e-7m^2/s + H: 11800cal + high_T: + T_min: 873K + T_max: 1273K + D0: 1.3e-7m^2/s + H: 10700cal + +experimental_parameters: + a: 21.27 + b: 2610 \ No newline at end of file diff --git a/src/ImpurityDensities/ThermalDiffusionLithiumDensity.jl b/src/ImpurityDensities/ThermalDiffusionLithiumDensity.jl index 1b68c5af0..59390750b 100644 --- a/src/ImpurityDensities/ThermalDiffusionLithiumDensity.jl +++ b/src/ImpurityDensities/ThermalDiffusionLithiumDensity.jl @@ -31,24 +31,49 @@ struct ThermalDiffusionLithiumDensity{T <: SSDFloat} <: AbstractImpurityDensity{ lithium_diffusivity_in_germanium::T end -function calculate_lithium_diffusivity_in_germanium(lithium_annealing_temperature::T)::T where {T <: SSDFloat} +struct LithiumDiffusionBranch{T <: SSDFloat} + T_min::T + T_max::T + D0::T + H::T +end + +struct LithiumDiffusionParameters{T <: SSDFloat} + lowT::LithiumDiffusionBranch{T} + highT::LithiumDiffusionBranch{T} +end + +struct LithiumSaturationParameters{T <: SSDFloat} + a::T + b::T +end + +struct ThermalDiffusionLithiumDensityParameters{T <: SSDFloat} + diffusion::LithiumDiffusionParameters{T} + saturation::LithiumSaturationParameters{T} +end + +include("ThermalDiffusionLithiumDensityParameters.jl") + +function calculate_lithium_diffusivity_in_germanium(lithium_annealing_temperature::T,parameters)::LithiumDiffusionParameters::T where {T <: SSDFloat} # D0 [m^2*s^-1] # H [cal] - D0::T, H::T = ifelse(lithium_annealing_temperature <= 873, T.((2.5e-7, 11800)), T.((1.3e-7, 10700))) + D0::T, H::T = ifelse(lithium_annealing_temperature <= parameters.lowT.T_max, T.((parameters.lowT.D0, parameters.lowT.H)), T.((parameters.highT.D0, parameters.highT.H))) D0 * exp(-H/(R_gas*lithium_annealing_temperature)) end -function calculate_lithium_saturated_density(lithium_annealing_temperature::T)::T where {T <: SSDFloat} - exp10(27.27 - 2610.0/lithium_annealing_temperature) +function calculate_lithium_saturated_density(lithium_annealing_temperature::T,parameters::LithiumSaturationParameters)::T where {T <: SSDFloat} + exp10(parameters.a - parameters.b/lithium_annealing_temperature) end function ThermalDiffusionLithiumDensity{T}( + modelParameters::ThermalDiffusionLithiumDensityParameters{T} = ThermalDiffusionLithiumParameters(), lithium_annealing_temperature::T, lithium_annealing_time::T, contact_with_lithium_doped::G, inactive_contact_id::Int; distance_to_contact::Function = pt::AbstractCoordinatePoint{T} -> ConstructiveSolidGeometry.distance_to_surface(pt, contact_with_lithium_doped), - lithium_density_on_contact::T = calculate_lithium_saturated_density(lithium_annealing_temperature), - lithium_diffusivity_in_germanium::T = calculate_lithium_diffusivity_in_germanium(lithium_annealing_temperature), + lithium_density_on_contact::T = calculate_lithium_saturated_density(lithium_annealing_temperature,modelParameters.saturation), + lithium_diffusivity_in_germanium::T = calculate_lithium_diffusivity_in_germanium(lithium_annealing_temperature,modelParameters.diffusion), ) where {T <: SSDFloat, G <: Union{<:AbstractGeometry, Nothing}} ThermalDiffusionLithiumDensity{T}(lithium_annealing_temperature, lithium_annealing_time, inactive_contact_id, distance_to_contact, lithium_density_on_contact, lithium_diffusivity_in_germanium) end diff --git a/src/ImpurityDensities/ThermalDiffusionLithiumDensityParameters.jl b/src/ImpurityDensities/ThermalDiffusionLithiumDensityParameters.jl new file mode 100644 index 000000000..32742202b --- /dev/null +++ b/src/ImpurityDensities/ThermalDiffusionLithiumDensityParameters.jl @@ -0,0 +1,96 @@ + + + +function _ThermalDiffusionLithiumParameters( + config::AbstractDict; + T::Type = Float32, + lowT_Tmin::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["low_T"]["T_min"], + lowT_Tmax::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["low_T"]["T_max"], + lowT_D0::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["low_T"]["D0"], + lowT_H::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["low_T"]["H"], + highT_Tmin::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["high_T"]["T_min"], + highT_Tmax::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["high_T"]["T_max"], + highT_D0::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["high_T"]["D0"], + highT_H::Union{RealQuantity, String} = + config["impurity_density_profile"]["annealing_temperature_ranges"]["high_T"]["H"], + a::Union{Real, String} = + config["experimental_parameters"]["a"], + b::Union{Real, String} = + config["experimental_parameters"]["b"], + input_units::Union{Missing, NamedTuple} = missing +) + + temperature_unit = !ismissing(input_units) ? input_units.temperature : u"K" + diffusivity_unit = !ismissing(input_units) ? + input_units.length^2 / internal_time_unit : u"m^2/s" + + lowT = LithiumDiffusionBranch{T}( + _parse_value(T, lowT_Tmin, temperature_unit), + _parse_value(T, lowT_Tmax, temperature_unit), + _parse_value(T, lowT_D0, diffusivity_unit), + _parse_value(T, lowT_H, u"cal") + ) + + highT = LithiumDiffusionBranch{T}( + _parse_value(T, highT_Tmin, temperature_unit), + _parse_value(T, highT_Tmax, temperature_unit), + _parse_value(T, highT_D0, diffusivity_unit), + _parse_value(T, highT_H, u"cal") + ) + + diffusion_params = LithiumDiffusionParameters{T}(lowT, highT) + + saturation_params = LithiumSaturationParameters{T}( + T(a), + T(b) + ) + + return ThermalDiffusionLithiumDensityParameters{T}( + diffusion_params, + saturation_params + ) +end + + +function ThermalDiffusionLithiumParameters(config::AbstractDict, input_units::Union{Missing, NamedTuple} = missing; kwargs...) + if !haskey(config, "impurity_density_profile") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile'.")) + elseif !haskey(config["impurity_density_profile"], "annealing_temperature_ranges") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile/annealing_temperature_ranges'.")) + elseif !haskey(config["impurity_density_profile"]["annealing_temperature_ranges"], "low_T") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile/annealing_temperature_ranges/low_T'.")) + elseif !haskey(config["impurity_density_profile"]["annealing_temperature_ranges"], "high_T") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile/annealing_temperature_ranges/high_T'.")) + end + + for axis in ("T_min", "T_max", "D0", "H") + if !haskey(config["impurity_density_profile"]["annealing_temperature_ranges"]["low_T"], axis) + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile/annealing_temperature_ranges/low_T/$(axis)'.")) + end + if !haskey(config["impurity_density_profile"]["annealing_temperature_ranges"]["high_T"], axis) + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'impurity_density_profile/annealing_temperature_ranges/high_T/$(axis)'.")) + end + end + + if !haskey(config, "experimental_parameters") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'experimental_parameters'.")) + elseif !haskey(config["experimental_parameters"], "a") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'experimental_parameters/a'.")) + elseif !haskey(config["experimental_parameters"], "b") + throw(ConfigFileError("ThermalDiffusionLithiumDensity config file needs entry 'experimental_parameters/b'.")) + end + + _ThermalDiffusionLithiumParameters(config; input_units = input_units, kwargs...) +end + +const default_ThermalDiffusionLithiumDensity_config_file = joinpath(get_path_to_example_config_files(), "ThermalDiffusionLithiumDensity/Thermal_Diffusion_Config.yaml") +function ThermalDiffusionLithiumParameters(config_filename::AbstractString = default_ThermalDiffusionLithiumDensity_config_file, input_units::Union{Missing, NamedTuple} = missing; kwargs...) + ThermalDiffusionLithiumParameters(parse_config_file(config_filename), input_units; kwargs...) +end \ No newline at end of file