changeset 10:2832aefd442c

Add 'no driver' version which can simulate in normal mode. Add Python code to optimise design.
author Daniel O'Connor <darius@dons.net.au>
date Fri, 17 Nov 2023 23:47:05 +1030
parents 66aa1acc90cd
children 8d34a9eec184
files .hgignore pa-GAN190-PP-nodriver.asc pa-GAN190-PP-nodriver.log.plt pa-GAN190-PP-nodriver.plt pa-GAN190-PP.asc pa-GAN190-PP.plt pa-GAN190.asc sim.py
diffstat 8 files changed, 385 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Fri Nov 17 23:47:05 2023 +1030
@@ -0,0 +1,3 @@
+tmp
+__pycache__
+.*~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pa-GAN190-PP-nodriver.asc	Fri Nov 17 23:47:05 2023 +1030
@@ -0,0 +1,211 @@
+Version 4
+SHEET 1 2852 992
+WIRE 1040 144 944 144
+WIRE 1072 144 1040 144
+WIRE 1120 144 1072 144
+WIRE 1312 144 1200 144
+WIRE 1424 144 1312 144
+WIRE 1584 144 1424 144
+WIRE 1664 144 1648 144
+WIRE 1840 144 1744 144
+WIRE 240 192 224 192
+WIRE 288 192 240 192
+WIRE 576 192 288 192
+WIRE 656 192 576 192
+WIRE 1312 192 1312 144
+WIRE 224 240 224 192
+WIRE 288 240 288 192
+WIRE 576 240 288 240
+WIRE 944 240 944 224
+WIRE 1936 240 1904 240
+WIRE 1968 240 1936 240
+WIRE 656 272 656 192
+WIRE 704 272 656 272
+WIRE 1216 272 784 272
+WIRE 1584 272 1584 144
+WIRE 1424 304 1424 144
+WIRE 1840 304 1840 144
+WIRE 1904 304 1904 240
+WIRE 1968 304 1968 240
+WIRE 576 384 576 240
+WIRE 704 384 576 384
+WIRE 1328 384 784 384
+WIRE 1904 432 1904 384
+WIRE 1968 432 1968 384
+WIRE 1968 432 1904 432
+WIRE 1968 448 1968 432
+WIRE 224 480 224 320
+WIRE 448 480 224 480
+WIRE 1312 480 1312 352
+WIRE 1424 480 1424 464
+WIRE 1424 480 1312 480
+WIRE 1584 480 1584 336
+WIRE 1584 480 1424 480
+WIRE 448 512 448 480
+WIRE 1424 512 1424 480
+WIRE 1072 608 1072 144
+WIRE 1120 608 1072 608
+WIRE 1312 608 1200 608
+WIRE 1424 608 1312 608
+WIRE 1584 608 1424 608
+WIRE 1664 608 1648 608
+WIRE 1824 608 1744 608
+WIRE 1840 608 1840 384
+WIRE 1840 608 1824 608
+WIRE 368 656 224 656
+WIRE 576 656 368 656
+WIRE 656 656 576 656
+WIRE 1312 656 1312 608
+WIRE 224 704 224 656
+WIRE 368 704 368 656
+WIRE 576 704 368 704
+WIRE 384 736 352 736
+WIRE 656 736 656 656
+WIRE 704 736 656 736
+WIRE 1216 736 784 736
+WIRE 1584 736 1584 608
+WIRE 1424 768 1424 608
+WIRE 576 848 576 704
+WIRE 704 848 576 848
+WIRE 1328 848 784 848
+WIRE 224 928 224 784
+WIRE 448 928 224 928
+WIRE 1312 944 1312 816
+WIRE 1424 944 1424 928
+WIRE 1424 944 1312 944
+WIRE 1584 944 1584 800
+WIRE 1584 944 1424 944
+WIRE 448 976 448 928
+WIRE 1424 976 1424 944
+FLAG 448 512 0
+FLAG 576 192 D0
+FLAG 240 192 RFDrive
+FLAG 1840 144 RFOutA
+FLAG 1040 144 HV
+FLAG 1312 144 SW0
+FLAG 816 240 0
+FLAG 944 240 0
+FLAG 1424 512 0
+FLAG 448 976 0
+FLAG 576 656 D1
+FLAG 1312 608 SW1
+FLAG 1424 976 0
+FLAG 224 656 nRFDrive
+FLAG 1824 608 RFOutB
+FLAG 1968 448 0
+FLAG 1936 240 RFOut
+FLAG 1840 688 0
+SYMBOL Voltage 224 224 R0
+WINDOW 3 -185 128 Left 2
+SYMATTR Value PULSE(0 12 0 1.5n 1.5n {Ton} {Tperiod})
+SYMATTR InstName V3
+SYMBOL Voltage 944 128 R0
+WINDOW 0 -8 -4 Left 2
+SYMATTR InstName V4
+SYMATTR Value 100
+SYMATTR SpiceLine Rser=10m Cpar=1p
+SYMBOL ind 1104 160 R270
+WINDOW 0 32 56 VTop 2
+WINDOW 3 5 56 VBottom 2
+SYMATTR InstName L1
+SYMATTR Value {L1}
+SYMATTR SpiceLine Rser=35m
+SYMBOL ind 1648 160 R270
+WINDOW 0 32 56 VTop 2
+WINDOW 3 -8 58 VBottom 2
+SYMATTR InstName L2
+SYMATTR Value {L2}
+SYMATTR SpiceLine Rser=35m
+SYMBOL cap 1648 128 R90
+WINDOW 0 0 32 VBottom 2
+WINDOW 3 40 27 VTop 2
+SYMATTR InstName C2
+SYMATTR Value {C2}
+SYMBOL cap 1600 336 R180
+WINDOW 0 24 56 Left 2
+WINDOW 3 30 8 Left 2
+SYMATTR InstName C1
+SYMATTR Value {C1}
+SYMBOL Res 1952 288 R0
+WINDOW 0 32 43 Left 2
+SYMATTR InstName R1
+SYMATTR Value {R1}
+SYMBOL Res 800 256 R90
+WINDOW 0 0 56 VBottom 2
+WINDOW 3 35 59 VTop 2
+SYMATTR InstName R4
+SYMATTR Value 0
+SYMBOL Res 800 368 R90
+WINDOW 0 0 56 VBottom 2
+WINDOW 3 36 53 VTop 2
+SYMATTR InstName R2
+SYMATTR Value 0
+SYMBOL GAN190-650FBE 1296 272 R0
+WINDOW 3 -54 59 Left 1
+SYMATTR InstName U2
+SYMBOL GAN190-650FBE 1408 384 R0
+WINDOW 3 -62 66 Left 1
+SYMATTR InstName U3
+SYMBOL ind 1104 624 R270
+WINDOW 0 32 56 VTop 2
+WINDOW 3 5 56 VBottom 2
+SYMATTR InstName L4
+SYMATTR Value {L1}
+SYMATTR SpiceLine Rser=35m
+SYMBOL ind 1648 624 R270
+WINDOW 0 32 56 VTop 2
+WINDOW 3 -8 58 VBottom 2
+SYMATTR InstName L5
+SYMATTR Value {L2}
+SYMATTR SpiceLine Rser=35m
+SYMBOL cap 1648 592 R90
+WINDOW 0 0 32 VBottom 2
+WINDOW 3 40 27 VTop 2
+SYMATTR InstName C4
+SYMATTR Value {C2}
+SYMBOL cap 1600 800 R180
+WINDOW 0 24 56 Left 2
+WINDOW 3 30 8 Left 2
+SYMATTR InstName C5
+SYMATTR Value {C1}
+SYMBOL Res 800 720 R90
+WINDOW 0 0 56 VBottom 2
+WINDOW 3 35 59 VTop 2
+SYMATTR InstName R3
+SYMATTR Value 0
+SYMBOL Res 800 832 R90
+WINDOW 0 0 56 VBottom 2
+WINDOW 3 36 53 VTop 2
+SYMATTR InstName R5
+SYMATTR Value 0
+SYMBOL GAN190-650FBE 1296 736 R0
+WINDOW 3 -54 59 Left 1
+SYMATTR InstName U5
+SYMBOL GAN190-650FBE 1408 848 R0
+WINDOW 3 -62 66 Left 1
+SYMATTR InstName U6
+SYMBOL ind2 1824 288 R0
+WINDOW 0 20 1 Left 2
+WINDOW 3 -46 112 Left 2
+SYMATTR InstName L3
+SYMATTR Value 100n
+SYMATTR Type ind
+SYMBOL ind2 1888 288 R0
+WINDOW 0 26 2 Left 2
+WINDOW 3 14 112 Left 2
+SYMATTR InstName L6
+SYMATTR Value 100n
+SYMATTR Type ind
+SYMBOL Res 1824 592 R0
+SYMATTR InstName R6
+SYMATTR Value 10Meg
+SYMBOL Voltage 224 688 R0
+WINDOW 3 -185 128 Left 2
+SYMATTR Value PULSE(0 12 {Tperiod / 2} 1.5n 1.5n {Ton} {TPeriod})
+SYMATTR InstName V5
+TEXT 112 -272 Left 2 !.param F0 = 35.24Meg\n.param Tperiod = 1 / {F0}\n.param dutypct = 20\n.param Ton = 1 / {F0} * {dutypct} / 100\n.param C1 = 10p\n.param C2 = 111p\n.param L1 = 4u\n.param L2 = 207n\n.param R1 = 12.5
+TEXT 600 -280 Left 2 !.meas PIN_HV AVG abs(V(HV)*I(V4))\n.meas POUT AVG abs(V(RFOut)*I(R1))\n.meas Efficiency Param 100*POUT/PIN_HV\n.meas IPEAK_U2 max(abs(Ix(U2:Drain)))\n.meas V_IPEAK_U2 FIND abs(V(SW0)) WHEN Ix(U2:Drain) = IPEAK_U2 * 0.999 cross=1\n.meas VPEAK_U2 max(abs(V(SW0)))\n.meas I_VPEAK_U2 FIND abs(Ix(U2:Drain)) WHEN V(SW0) = VPEAK_U2 * 0.999 cross=1\n.meas IPEAK_U5 max(abs(Ix(U5:Drain)))\n.meas VPEAK_U5 max(abs(V(SW1)))
+TEXT 600 -16 Left 2 !*.tran 0 1.8u 1.7u\n.tran 0 5u 1.7u\n*.tran 0 2.5u 1.5u\n*.tran 0 5u
+TEXT 120 56 Left 2 !.fourier {F0} 9 -1 V(rfout)
+TEXT 104 -56 Left 2 !*.step param dutypct 20 60 4\n*.step param C1 10p 130p 10p\n*.step param C2 80p 195p 5p\n*.step param L2 80n 220n 10n
+TEXT 1792 336 Left 2 !K1 L3 L6 1
Binary file pa-GAN190-PP-nodriver.log.plt has changed
Binary file pa-GAN190-PP-nodriver.plt has changed
--- a/pa-GAN190-PP.asc	Sat Oct 21 14:17:33 2023 +1030
+++ b/pa-GAN190-PP.asc	Fri Nov 17 23:47:05 2023 +1030
@@ -14,7 +14,6 @@
 WIRE 1584 144 1424 144
 WIRE 1664 144 1648 144
 WIRE 1840 144 1744 144
-WIRE 1936 144 1840 144
 WIRE 240 192 224 192
 WIRE 288 192 240 192
 WIRE 384 192 288 192
@@ -28,8 +27,8 @@
 WIRE 576 240 512 240
 WIRE 816 240 816 224
 WIRE 944 240 944 224
-WIRE 2032 240 2000 240
-WIRE 2064 240 2032 240
+WIRE 1936 240 1904 240
+WIRE 1968 240 1936 240
 WIRE 384 272 352 272
 WIRE 656 272 656 192
 WIRE 704 272 656 272
@@ -38,19 +37,19 @@
 WIRE 352 304 352 272
 WIRE 384 304 352 304
 WIRE 1424 304 1424 144
-WIRE 1936 304 1936 144
-WIRE 2000 304 2000 240
-WIRE 2064 304 2064 240
+WIRE 1840 304 1840 144
+WIRE 1904 304 1904 240
+WIRE 1968 304 1968 240
 WIRE 352 384 352 304
 WIRE 448 384 448 336
 WIRE 448 384 352 384
 WIRE 576 384 576 240
 WIRE 704 384 576 384
 WIRE 1328 384 784 384
-WIRE 2000 432 2000 384
-WIRE 2064 432 2064 384
-WIRE 2064 432 2000 432
-WIRE 2064 448 2064 432
+WIRE 1904 432 1904 384
+WIRE 1968 432 1968 384
+WIRE 1968 432 1904 432
+WIRE 1968 448 1968 432
 WIRE 128 480 128 320
 WIRE 224 480 224 320
 WIRE 224 480 128 480
@@ -74,8 +73,8 @@
 WIRE 1584 608 1424 608
 WIRE 1664 608 1648 608
 WIRE 1824 608 1744 608
-WIRE 1936 608 1936 384
-WIRE 1936 608 1824 608
+WIRE 1840 608 1840 384
+WIRE 1840 608 1824 608
 WIRE 368 656 224 656
 WIRE 384 656 368 656
 WIRE 576 656 512 656
@@ -126,9 +125,9 @@
 FLAG 1424 976 0
 FLAG 224 656 nRFDrive
 FLAG 1824 608 RFOutB
-FLAG 2064 448 0
-FLAG 2032 240 RFOut
-FLAG 1936 688 0
+FLAG 1968 448 0
+FLAG 1936 240 RFOut
+FLAG 1840 688 0
 SYMBOL Voltage 128 224 R0
 WINDOW 3 37 53 Left 2
 SYMATTR Value 5
@@ -173,7 +172,7 @@
 WINDOW 3 30 8 Left 2
 SYMATTR InstName C1
 SYMATTR Value {C1}
-SYMBOL Res 2048 288 R0
+SYMBOL Res 1952 288 R0
 WINDOW 0 32 43 Left 2
 SYMATTR InstName R1
 SYMATTR Value {R1}
@@ -235,28 +234,28 @@
 SYMBOL GAN190-650FBE 1408 848 R0
 WINDOW 3 -62 66 Left 1
 SYMATTR InstName U6
-SYMBOL ind2 1920 288 R0
+SYMBOL ind2 1824 288 R0
 WINDOW 0 20 1 Left 2
 WINDOW 3 -46 112 Left 2
 SYMATTR InstName L3
 SYMATTR Value 100n
 SYMATTR Type ind
-SYMBOL ind2 1984 288 R0
+SYMBOL ind2 1888 288 R0
 WINDOW 0 26 2 Left 2
 WINDOW 3 14 112 Left 2
 SYMATTR InstName L6
 SYMATTR Value 100n
 SYMATTR Type ind
-SYMBOL Res 1920 592 R0
+SYMBOL Res 1824 592 R0
 SYMATTR InstName R6
 SYMATTR Value 10Meg
 SYMBOL Voltage 224 688 R0
 WINDOW 3 -185 128 Left 2
 SYMATTR Value PULSE(0 5 {Tperiod / 2} 200p 200p {Ton} {TPeriod})
 SYMATTR InstName V5
-TEXT 112 -272 Left 2 !.param F0 = 35.24Meg\n.param Tperiod = 1 / {F0}\n.param dutypct = 36\n.param Ton = 1 / {F0} * {dutypct} / 100\n.param C1 = 10p\n.param C2 = 155p\n.param L1 = 5u\n.param L2 = 140n\n.param R1 = 12.5
-TEXT 608 -280 Left 2 !.meas PIN_HV AVG abs(V(HV)*I(V4))\n.meas PIN_MOD AVG abs(V(MOD_RAIL)*I(V2))\n.meas PIN_LV AVG abs(V(VCC)*I(V1))\n.meas POUT AVG abs(V(RFOut)*I(R1))\n.meas Efficiency Param 100*POUT/(PIN_HV + PIN_LV + PIN_MOD)
-TEXT 608 -152 Left 2 !*.tran 0 1.8u 1.7u\n*.tran 0 5u 1.7u\n*.tran 0 2.5u 1.5u\n.tran 0 5u
-TEXT 608 -16 Left 2 !.fourier {F0} 9 -1 V(rfout)
-TEXT 104 -8 Left 2 !*.step param dutypct 20 60 4\n*.step param C1 10p 130p 10p\n*.step param C2 80p 195p 5p\n*.step param L2 80n 220n 10n
+TEXT 112 -272 Left 2 !.param F0 = 35.24Meg\n.param Tperiod = 1 / {F0}\n.param dutypct = 20\n.param Ton = 1 / {F0} * {dutypct} / 100\n.param C1 = 10p\n.param C2 = 111p\n.param L1 = 4u\n.param L2 = 207n\n.param R1 = 12.5
+TEXT 600 -280 Left 2 !.meas PIN_HV AVG abs(V(HV)*I(V4))\n.meas PIN_MOD AVG abs(V(MOD_RAIL)*I(V2))\n.meas PIN_LV AVG abs(V(VCC)*I(V1))\n.meas POUT AVG abs(V(RFOut)*I(R1))\n.meas Efficiency Param 100*POUT/(PIN_HV + PIN_LV + PIN_MOD)\n.meas IPEAK_U2 max(abs(Ix(U2:Drain)))\n.meas V_IPEAK_U2 FIND abs(V(SW0)) WHEN Ix(U2:Drain) = IPEAK_U2 * 0.999 cross=1\n.meas VPEAK_U2 max(abs(V(SW0)))\n.meas I_VPEAK_U2 FIND abs(Ix(U2:Drain)) WHEN V(SW0) = VPEAK_U2 * 0.999 cross=1\n.meas IPEAK_U5 max(abs(Ix(U5:Drain)))\n.meas VPEAK_U5 max(abs(V(SW1)))
+TEXT 600 -16 Left 2 !*.tran 0 1.8u 1.7u\n.tran 0 5u 1.7u\n*.tran 0 2.5u 1.5u\n*.tran 0 5u
+TEXT 120 56 Left 2 !.fourier {F0} 9 -1 V(rfout)
+TEXT 104 -56 Left 2 !*.step param dutypct 20 60 4\n*.step param C1 10p 130p 10p\n*.step param C2 80p 195p 5p\n*.step param L2 80n 220n 10n
 TEXT 1792 336 Left 2 !K1 L3 L6 1
Binary file pa-GAN190-PP.plt has changed
Binary file pa-GAN190.asc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sim.py	Fri Nov 17 23:47:05 2023 +1030
@@ -0,0 +1,148 @@
+import datetime
+import pathlib
+from scipy.optimize import differential_evolution
+from spicelib.simulators.ltspice_simulator import LTspice
+from spicelib.log.ltsteps import LTSpiceLogReader
+from spicelib.editor.spice_editor import SpiceEditor
+#from spicelib.sim.sim_runner import SimRunner
+#import shlex
+import sqlite3
+import subprocess
+
+def simulate(src, simexe, simflags, rundir, runname, params):
+    src = pathlib.Path(src)
+    runname = pathlib.Path(runname)
+    assert(runname.suffix == '.net')
+    rundir = pathlib.Path(rundir)
+
+    e = SpiceEditor(src)
+    for k in params:
+        e.set_parameter(k, params[k])
+
+    #s = SimRunner(simulator = LTspice, output_folder = 'tmp', verbose = True)
+    #s.simulator.spice_exe = [simexe]
+    #raw_file, log_file = s.run_now(e, run_filename = runname)
+
+    e.write_netlist(rundir / runname)
+
+    cmd = [simexe, '-b']
+    cmd.extend(simflags)
+    cmd.append(runname.name)
+    #print(' '.join(map(shlex.quote, cmd)))
+    then = datetime.datetime.now()
+    p = subprocess.Popen(cmd, cwd = rundir)
+    p.communicate()
+    now = datetime.datetime.now()
+    taken = now - then
+
+    if p.returncode != 0:
+        raise Exception('failed')
+
+    #rawpath = rundir / runname.with_suffix('.raw')
+    #raw = spicelib.RawRead(rawpath)
+    logpath = rundir / runname.with_suffix('.log')
+    log = LTSpiceLogReader(logpath)
+
+    power = log.get_measure_value('pout')
+    eff = log.get_measure_value('efficiency')
+    thd = log.fourier['V(rfout)'][0].thd
+    ipeak_u2 = log.get_measure_value('ipeak_u2')
+    ipeak_u5 = log.get_measure_value('ipeak_u5')
+    ipeak = max(ipeak_u2, ipeak_u5)
+
+    return then, taken, power, eff, thd, ipeak
+
+
+def fn(v, cur, simexe, simflags, rundir, circ, ctr):
+    '''Called by differential_evolution, v contains the evolved parameters, the rest are passed in from the args parameter'.
+    Returns the cost value which is being minimised'''
+
+    # Get parameters for run
+    duty, c1, c2, l1, l2 = v
+
+    cur.execute('SELECT cost, run, power, efficiency, thd, ipeak FROM GAN190 WHERE duty = ? AND c1 = ? AND c2 = ? AND l1 = ? AND l2 = ?', (duty, c1, c2, l1, l2))
+    tmp = cur.fetchone()
+    if tmp is not None:
+        cost, run, power, eff, thd, ipeak = tmp
+        print(f'Found run {run:3d}: Duty {duty:3.0f}%, C1 {c1:3.0f}pF, C2 {c2:3.0f}pF, L1 {l1:3.0f}uH, L2 {l2:4.0f}nH -> Power: {power:6.1f}W Efficiency: {eff:5.1f}% THD: {thd:5.1f}% IPeak: {ipeak:4.1f}A Cost: {cost:6.2f}')
+        return cost
+
+    # Get next run number
+    run = next(ctr)
+
+    # Run the simulation
+    # Need to convert units to suit
+    runname = pathlib.Path(circ).stem + '-' + str(run) + '.net'
+    then, taken, power, eff, thd, ipeak = simulate(circ, simexe, simflags, rundir, runname,
+                                                   {'dutypct' : duty, 'C1' : c1 * 1e-12, 'C2' : c2 * 1e-12, 'L1' : l1 * 1e-6, 'L2' : l2 * 1e-9})
+
+    # Calculate the cost
+    tpwr = 2000
+    tthd = 2
+    teff = 90
+    imax = 11
+
+    cost = 0
+    if power < tpwr / 2:
+        cost += 100
+    elif power < tpwr:
+        cost += (tpwr - power) / tpwr / 100
+
+    if thd > 5 * tthd:
+        cost += 100
+    else:
+        thdinv = 100 - thd
+        tthdinv = 100 - tthd
+        if thdinv < tthdinv:
+            cost += (tthdinv - thdinv) / tthdinv
+    if eff < teff:
+        cost += (teff - eff) / teff
+
+    if ipeak > imax:
+        cost += (ipeak - imax) * 2
+
+    # Log & save the results
+    print(f'Run {run:3d}: Duty {duty:3.0f}%, C1 {c1:3.0f}pF, C2 {c2:3.0f}pF, L1 {l1:3.0f}uH, L2 {l2:4.0f}nH -> Power: {power:6.1f}W Efficiency: {eff:5.1f}% THD: {thd:5.1f}% IPeak: {ipeak:4.1f}A Cost: {cost:6.2f}')
+    taken = taken.seconds + taken.microseconds / 1e6
+    cur.execute('INSERT INTO GAN190 (name, run, start, duration, duty, c1, c2, l1, l2, power, efficiency, thd, ipeak, cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
+                 (runname, run, then, taken, duty, c1, c2, l1, l2, power, eff, thd, ipeak, cost))
+    cur.execute('COMMIT')
+
+    return cost
+
+def ev():
+    # Bounds for parameters
+    bounds = [(10, 80),
+              (1, 20),
+              (10, 300),
+              (1, 20),
+              (10, 500)]
+    # Initial solution
+    x0 = [36, 10, 155, 5, 140]
+    dbh = sqlite3.connect('results.db')
+    cur = dbh.cursor()
+    cur.execute('''
+CREATE TABLE IF NOT EXISTS GAN190 (
+    name	TEXT,		-- Circuit name
+    run		INTEGER,	-- Run number
+    start	DATETIME,	-- Datetime run started
+    duration	REAL,		-- Length of run (seconds)
+    duty	REAL,		-- Duty cyle (%)
+    c1		REAL,		-- Value of C1 (pF)
+    c2		REAL,		-- Value of C2 (pF)
+    l1		REAL,		-- Value of L1 (uH)
+    l2		REAL,		-- Value of L2 (nH)
+    power	REAL,		-- Measured power (Watts)
+    efficiency	REAL,		-- Measured efficiency (%)
+    thd		REAL,		-- Total harmonic distortion (%)
+    ipeak	REAL,		-- Peak drain current (A)
+    cost	REAL		-- Calculated cost metric
+);''')
+    def ctr():
+        i = 0
+        while True:
+            yield i
+            i += 1
+    return differential_evolution(fn, bounds, x0 = x0,
+                                  args = (cur, '/Users/oconnd1/bin/runltspice', ['-alt'], 'tmp', 'pa-GAN190-PP-nodriver.net', ctr()),
+                                  integrality = True, disp = True, seed = 12345)