Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Triode / Pentode Models #29

Open
ghost opened this issue May 28, 2020 · 10 comments
Open

Triode / Pentode Models #29

ghost opened this issue May 28, 2020 · 10 comments

Comments

@ghost
Copy link

ghost commented May 28, 2020

@martinholters , I've take a look to the differents triode/pentode/... models used in the scientific litterature, I see you take part in differents study. For example the 2011 paper : "A Triode Model for Guitar Amplifier Simulation with Individual Parameter Fitting" with Kristjan Dempwolf and Udo Zölzer.

Can I ask you if you can orient me to the current state of the art for this subject? You may be advised on the subject. If not, no problem, I will take few weeks to work on the subject.

@martinholters
Copy link
Member

Although I've been somewhat involved with Kristjan Dempwolfs work, I'm not sure about my qualification concerning the current state of the art. I'm not aware of any significant publications on the subject since then, but I may easily have missed some.

If I remember correctly, we were quite happy with our results on the triode, so I would probably have started with that model. But I'm obviously biased here 😄 We also did some work on pentodes, but as far as I remember, results were a bit mixed there. It might even make sense to implement different models to facilitate further research in this area. With the obvious downside that requires, well, implementing different models.

@ghost
Copy link
Author

ghost commented May 28, 2020

So I will take probably few days before make a little feedback with the idea, and maybe a little help from you to validate my work ;)

@cristianfarias
Copy link

Hi Martin,

I added the next triode element (COHEN AND HELIE model) but it seems to not resolve successfully the initial conditions ?

  1. First I add the next code in the file elements.jl

export resistor, potentiometer, capacitor, inductor, transformer,
voltagesource, currentsource,
voltageprobe, currentprobe, diode, bjt, mosfet, opamp, triode

...
...

@doc raw"""
triode(;Gk=2.14e-3, uk=100.8, Ek=1.303, Ck=3.04, Gg=6.06e-4, Eg=1.354, Cg=13.9)

Creates a triode model

Pins: plate, grid, cathode
""" function triode(;Gk=2.14e-3, uk=100.8, Ek=1.303, Ck=3.04, Gg=6.06e-4, Eg=1.354, Cg=13.9)

nonlinear_eq =
    @inline function (q)
        VgkT1, VpkT1, IgT1, IpT1 = q
        IgT1=Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg
        IpT1=Gk*(log(1+exp(Ck*(VpkT1/uk+VgkT1)))*1/Ck)^Ek-Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg
		dIgT1_dVgkT1=(1891999529292056969*exp((139*VgkT1)/10)*((10*log(exp((139*VgkT1)/10) + 1))/139)^(177/500))/(2305843009213693952000*(exp((139*VgkT1)/10) + 1))
		dIgT1_dVpkT1=0
		dIpT1_dVgkT1=(139421*exp((76*VgkT1)/25 + (19*VpkT1)/630)*((25*log(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))/76)^(303/1000))/(50000000*(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1)) - (1891999529292056969*exp((139*VgkT1)/10)*((10*log(exp((139*VgkT1)/10) + 1))/139)^(177/500))/(2305843009213693952000*(exp((139*VgkT1)/10) + 1))
		dIpT1_dVpkT1=(139421*exp((76*VgkT1)/25 + (19*VpkT1)/630)*((25*log(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))/76)^(303/1000))/(5040000000*(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))
        res = @SVector [IgT1, IpT1]
        J = @SMatrix [dIgT1_dVgkT1 dIgT1_dVpkT1 -1.0 0.0;
                      dIpT1_dVgkT1 dIpT1_dVpkT1 0.0  -1.0]
        return (res, J)
    end
return Element(mv=[1 0; 0 1; 0 0; 0 0],
               mi = [0 0; 0 0; 1 0; 0 1],
               mq = [-1 0 0 0; 0 -1 0 0; 0 0 -1 0; 0 0 0 -1], nonlinear_eq = nonlinear_eq,
               ports = [:grid => :cathode, :plate => :cathode])

end

  1. When I tried to calculate the model I get the next error

julia> model = DiscreteModel(circ, 1/44100)
ERROR: Failed to find initial solution
Stacktrace:
[1] error(::String) at .\error.jl:33
[2] initial_solution(::Function, ::Array{Float64,1}, ::Int64) at C:\Users\cti4121.julia\packages\ACME\bLRnf\src\ACME.jl:436
[3] DiscreteModel(::Circuit, ::Float64, ::Type{HomotopySolver{CachingSolver{SimpleSolver}}}; decompose_nonlinearity::Bool) at C:\Users\cti4121.julia\packages\ACME\bLRnf\src\ACME.jl:198
[4] DiscreteModel at C:\Users\cti4121.julia\packages\ACME\bLRnf\src\ACME.jl:150 [inlined] (repeats 2 times)
[5] top-level scope at REPL[5]:1

@cristianfarias
Copy link

before that, I define this circuit to simulate

vol=0.5;

circ = @circuit begin
j3 = voltagesource(250), [-] ⟷ gnd, [+] ⟷ vcc # 250V power supply
j1 = voltagesource(), [-] ⟷ gnd # input
c1 = capacitor(47e-9), [1] ⟷ j1[+]
r1 = resistor(1e6), [1] ⟷ c1[2], [2] ⟷ gnd
r2 = resistor(70e3), [1] ⟷ c1[2]
c2 = capacitor(2.5e-9), [1] ⟷ r2[2]
t1 = triode(),
[grid] ⟷ r2[2], [plate] ⟷ c2[2]
r3 = resistor(100e3), [1] ⟷ vcc, [2] ⟷ t1[plate]
r4 = resistor(1.5e3), [1] ⟷ t1[cathode], [2] ⟷ gnd
c3 = capacitor(25e-6), [1] ⟷ t1[cathode], [2] ⟷ gnd
c4 = capacitor(1e-6), [1] ⟷ t1[plate]
p1 = potentiometer(100e3, (vol == nothing ? () : (vol,))...), [1] ⟷ gnd, [3] ⟷ c4[2]
j2 = voltageprobe(), [-] ⟷ gnd, [+] ⟷ p1[2]# output
end

Regards

@martinholters
Copy link
Member

martinholters commented Mar 9, 2021

From a brief look, I think you'd want something like

res1 = Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg - IgT1
res2 = Gk*(log(1+exp(Ck*(VpkT1/uk+VgkT1)))*1/Ck)^Ek-Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg - IpT1
# ...
res = @SVector [res1, res]

I.e., the res vector has to hold the difference between the currents computed from the voltages and the currents provided as q[3] and q[4]. For convergence, it important that the Jacobian J is correct, which I cannot judge from a brief look, but given the strange numbers occurring in there, I assume you used some special tool to compute the derivatives for specific parameter values (probably the defaults)?

EDIT: I've just tried

function triode(;Gk=2.14e-3, uk=100.8, Ek=1.303, Ck=3.04, Gg=6.06e-4, Eg=1.354, Cg=13.9)
    nonlinear_eq =
        @inline function (q)
            VgkT1, VpkT1, IgT1, IpT1 = q
            res1 = Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg - IgT1
            res2 = Gk*(log(1+exp(Ck*(VpkT1/uk+VgkT1)))*1/Ck)^Ek-Gg*(log(1+exp(Cg*VgkT1))*1/Cg)^Eg - IpT1
                    dIgT1_dVgkT1=(1891999529292056969*exp((139*VgkT1)/10)*((10*log(exp((139*VgkT1)/10) + 1))/139)^(177/500))/(2305843009213693952000*(exp((139*VgkT1)/10) + 1))
                    dIgT1_dVpkT1=0
                    dIpT1_dVgkT1=(139421*exp((76*VgkT1)/25 + (19*VpkT1)/630)*((25*log(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))/76)^(303/1000))/(50000000*(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1)) - (1891999529292056969*exp((139*VgkT1)/10)*((10*log(exp((139*VgkT1)/10) + 1))/139)^(177/500))/(2305843009213693952000*(exp((139*VgkT1)/10) + 1))
                    dIpT1_dVpkT1=(139421*exp((76*VgkT1)/25 + (19*VpkT1)/630)*((25*log(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))/76)^(303/1000))/(5040000000*(exp((76*VgkT1)/25 + (19*VpkT1)/630) + 1))
            res = @SVector [res1, res2]
            J = @SMatrix [dIgT1_dVgkT1 dIgT1_dVpkT1 -1.0 0.0;
                          dIpT1_dVgkT1 dIpT1_dVpkT1 0.0  -1.0]
            return (res, J)
        end
    return ACME.Element(mv=[1 0; 0 1; 0 0; 0 0],
                   mi = [0 0; 0 0; 1 0; 0 1],
                   mq = [-1 0 0 0; 0 -1 0 0; 0 0 -1 0; 0 0 0 -1], nonlinear_eq = nonlinear_eq,
                   ports = [:grid => :cathode, :plate => :cathode])
end

With the circuit you gave above it a) doesn't error and b) gives results that look plausible (at first glance, at least).

@cristianfarias
Copy link

cristianfarias commented Mar 10, 2021 via email

@cristianfarias
Copy link

cristianfarias commented Mar 10, 2021 via email

@martinholters
Copy link
Member

Sorry, your latest posts somehow slipped through unnoticed. Probably a bit late now, but in your example circuit, there are two r4's. Renaming the latter to, say, r11, yields plausible results. (Using the same designator twice should probably give a warning to help avoid such pitfalls).

@cristianfarias
Copy link

cristianfarias commented Jul 24, 2021 via email

@martinholters
Copy link
Member

FWIW, with the recently released v0.9.5, the buggy circuit description above now emits

┌ Warning: redefinition of `r4`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants