comparison sim.py @ 14:ac2ff6be22f7

Take circuit name in top level function. Print command which failed if it does.
author Daniel O'Connor <darius@dons.net.au>
date Sun, 19 Nov 2023 00:05:58 +1030
parents 49939e179c86
children f0665f53b854
comparison
equal deleted inserted replaced
13:7cdfaa0b5ad2 14:ac2ff6be22f7
3 from scipy.optimize import differential_evolution 3 from scipy.optimize import differential_evolution
4 from spicelib.simulators.ltspice_simulator import LTspice 4 from spicelib.simulators.ltspice_simulator import LTspice
5 from spicelib.log.ltsteps import LTSpiceLogReader 5 from spicelib.log.ltsteps import LTSpiceLogReader
6 from spicelib.editor.spice_editor import SpiceEditor 6 from spicelib.editor.spice_editor import SpiceEditor
7 #from spicelib.sim.sim_runner import SimRunner 7 #from spicelib.sim.sim_runner import SimRunner
8 #import shlex 8 import shlex
9 import sqlite3 9 import sqlite3
10 import subprocess 10 import subprocess
11 11
12 def simulate(src, simexe, simflags, rundir, runname, params): 12 def simulate(src, simexe, simflags, rundir, runname, params):
13 src = pathlib.Path(src) 13 src = pathlib.Path(src)
26 e.write_netlist(rundir / runname) 26 e.write_netlist(rundir / runname)
27 27
28 cmd = [simexe, '-b'] 28 cmd = [simexe, '-b']
29 cmd.extend(simflags) 29 cmd.extend(simflags)
30 cmd.append(runname.name) 30 cmd.append(runname.name)
31 #print(' '.join(map(shlex.quote, cmd)))
32 then = datetime.datetime.now() 31 then = datetime.datetime.now()
33 print(f'Starting run {runname} at {then}') 32 print(f'Starting run {runname} at {then}')
34 p = subprocess.Popen(cmd, cwd = rundir) 33 p = subprocess.Popen(cmd, cwd = rundir)
35 p.communicate() 34 p.communicate()
36 now = datetime.datetime.now() 35 now = datetime.datetime.now()
37 taken = now - then 36 taken = now - then
38 37
39 if p.returncode != 0: 38 if p.returncode != 0:
40 raise Exception('failed') 39 print('Run failed: ' + ' '.join(map(shlex.quote, cmd)))
40 return 100000
41 41
42 #rawpath = rundir / runname.with_suffix('.raw') 42 #rawpath = rundir / runname.with_suffix('.raw')
43 #raw = spicelib.RawRead(rawpath) 43 #raw = spicelib.RawRead(rawpath)
44 logpath = rundir / runname.with_suffix('.log') 44 logpath = rundir / runname.with_suffix('.log')
45 log = LTSpiceLogReader(logpath) 45 log = LTSpiceLogReader(logpath)
89 duty, c1, c2, l1, l2 = v 89 duty, c1, c2, l1, l2 = v
90 90
91 # Check if this combination has already been tried 91 # Check if this combination has already been tried
92 dbh = sqlite3.connect(dsn) 92 dbh = sqlite3.connect(dsn)
93 cur = dbh.cursor() 93 cur = dbh.cursor()
94 cur.execute('SELECT run, power, efficiency, thd, ipeak FROM GAN190 WHERE duty = ? AND c1 = ? AND c2 = ? AND l1 = ? AND l2 = ?', (duty, c1, c2, l1, l2)) 94 cur.execute('SELECT run, power, efficiency, thd, ipeak FROM GAN190 WHERE name = ? AND duty = ? AND c1 = ? AND c2 = ? AND l1 = ? AND l2 = ?',
95 (circ, duty, c1, c2, l1, l2))
95 tmp = cur.fetchone() 96 tmp = cur.fetchone()
96 if tmp is not None: 97 if tmp is not None:
97 run, power, eff, thd, ipeak = tmp 98 run, power, eff, thd, ipeak = tmp
98 # Recalculate the cost since it is cheap and might have been tweaked since the original run 99 # Recalculate the cost since it is cheap and might have been tweaked since the original run
99 cost = calccost(power, eff, thd, ipeak) 100 cost = calccost(power, eff, thd, ipeak)
117 # Log & save the results 118 # Log & save the results
118 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}') 119 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}')
119 taken = taken.seconds + taken.microseconds / 1e6 120 taken = taken.seconds + taken.microseconds / 1e6
120 cur.execute('BEGIN DEFERRED') 121 cur.execute('BEGIN DEFERRED')
121 cur.execute('REPLACE INTO GAN190 (name, run, start, duration, duty, c1, c2, l1, l2, power, efficiency, thd, ipeak, cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', 122 cur.execute('REPLACE INTO GAN190 (name, run, start, duration, duty, c1, c2, l1, l2, power, efficiency, thd, ipeak, cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
122 (runname, run, then, taken, duty, c1, c2, l1, l2, power, eff, thd, ipeak, cost)) 123 (circ, run, then, taken, duty, c1, c2, l1, l2, power, eff, thd, ipeak, cost))
123 cur.execute('COMMIT') 124 cur.execute('COMMIT')
124 125
125 return cost 126 return cost
126 127
127 def ev(): 128 def ev(circ):
128 # Bounds for parameters 129 # Bounds for parameters
129 # Note that the parameters are also constrained to be integral 130 # Note that the parameters are also constrained to be integral
130 bounds = [(10, 80), 131 bounds = [(10, 80),
131 (1, 20), 132 (1, 20),
132 (10, 300), 133 (10, 300),
157 ipeak REAL, -- Peak drain current (A) 158 ipeak REAL, -- Peak drain current (A)
158 cost REAL -- Calculated cost metric 159 cost REAL -- Calculated cost metric
159 );''') 160 );''')
160 161
161 return differential_evolution(fn, bounds, x0 = x0, 162 return differential_evolution(fn, bounds, x0 = x0,
162 args = (dsn, '/Users/oconnd1/bin/runltspice', [], 'tmp', 'pa-GAN190-PP-nodriver.net'), 163 args = (dsn, '/Users/oconnd1/bin/runltspice', [], 'tmp', circ),
163 integrality = True, disp = True, seed = 12345, updating = 'deferred', workers = 4) 164 integrality = True, disp = True, seed = 12345, updating = 'deferred', workers = 4)