Mercurial > ~darius > hgwebdir.cgi > pa
comparison sim.py @ 12:49939e179c86
Run 4 simulations at once.
Since this requires the function arguments to be pickleable we pass the DB filename around.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 18 Nov 2023 12:03:13 +1030 |
parents | 8d34a9eec184 |
children | ac2ff6be22f7 |
comparison
equal
deleted
inserted
replaced
11:8d34a9eec184 | 12:49939e179c86 |
---|---|
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))) | 31 #print(' '.join(map(shlex.quote, cmd))) |
32 then = datetime.datetime.now() | 32 then = datetime.datetime.now() |
33 print(f'Starting run {runname} at {then}') | |
33 p = subprocess.Popen(cmd, cwd = rundir) | 34 p = subprocess.Popen(cmd, cwd = rundir) |
34 p.communicate() | 35 p.communicate() |
35 now = datetime.datetime.now() | 36 now = datetime.datetime.now() |
36 taken = now - then | 37 taken = now - then |
37 | 38 |
78 if ipeak > imax: | 79 if ipeak > imax: |
79 cost += (ipeak - imax) * 5 | 80 cost += (ipeak - imax) * 5 |
80 | 81 |
81 return cost | 82 return cost |
82 | 83 |
83 def fn(v, cur, simexe, simflags, rundir, circ, ctr): | 84 def fn(v, dsn, simexe, simflags, rundir, circ): |
84 '''Called by differential_evolution, v contains the evolved parameters, the rest are passed in from the args parameter'. | 85 '''Called by differential_evolution, v contains the evolved parameters, the rest are passed in from the args parameter'. |
85 Returns the cost value which is being minimised''' | 86 Returns the cost value which is being minimised''' |
86 | 87 |
87 # Get parameters for run | 88 # Get parameters for run |
88 duty, c1, c2, l1, l2 = v | 89 duty, c1, c2, l1, l2 = v |
89 | 90 |
90 # Check if this combination has already been tried | 91 # Check if this combination has already been tried |
92 dbh = sqlite3.connect(dsn) | |
93 cur = dbh.cursor() | |
91 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 duty = ? AND c1 = ? AND c2 = ? AND l1 = ? AND l2 = ?', (duty, c1, c2, l1, l2)) |
92 tmp = cur.fetchone() | 95 tmp = cur.fetchone() |
93 if tmp is not None: | 96 if tmp is not None: |
94 run, power, eff, thd, ipeak = tmp | 97 run, power, eff, thd, ipeak = tmp |
95 # Recalculate the cost since it is cheap and might have been tweaked since the original run | 98 # Recalculate the cost since it is cheap and might have been tweaked since the original run |
96 cost = calccost(power, eff, thd, ipeak) | 99 cost = calccost(power, eff, thd, ipeak) |
97 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}') | 100 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}') |
98 return cost | 101 return cost |
99 | 102 |
100 # Get next run number | 103 # Get next run number |
101 run = next(ctr) | 104 cur.execute('BEGIN DEFERRED') |
105 cur.execute('INSERT INTO GAN190 DEFAULT VALUES RETURNING rowid') | |
106 run = cur.fetchone()[0] | |
107 cur.execute('COMMIT') | |
102 | 108 |
103 # Run the simulation | 109 # Run the simulation |
104 # Need to convert units to suit | 110 # Need to convert units to suit |
105 runname = pathlib.Path(circ).stem + '-' + str(run) + '.net' | 111 runname = pathlib.Path(circ).stem + '-' + str(run) + '.net' |
106 then, taken, power, eff, thd, ipeak = simulate(circ, simexe, simflags, rundir, runname, | 112 then, taken, power, eff, thd, ipeak = simulate(circ, simexe, simflags, rundir, runname, |
109 cost = calccost(power, eff, thd, ipeak) | 115 cost = calccost(power, eff, thd, ipeak) |
110 | 116 |
111 # Log & save the results | 117 # Log & save the results |
112 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}') | 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}') |
113 taken = taken.seconds + taken.microseconds / 1e6 | 119 taken = taken.seconds + taken.microseconds / 1e6 |
114 cur.execute('INSERT INTO GAN190 (name, run, start, duration, duty, c1, c2, l1, l2, power, efficiency, thd, ipeak, cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', | 120 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', | |
115 (runname, run, then, taken, duty, c1, c2, l1, l2, power, eff, thd, ipeak, cost)) | 122 (runname, run, then, taken, duty, c1, c2, l1, l2, power, eff, thd, ipeak, cost)) |
116 cur.execute('COMMIT') | 123 cur.execute('COMMIT') |
117 | 124 |
118 return cost | 125 return cost |
119 | 126 |
120 def ev(): | 127 def ev(): |
121 # Bounds for parameters | 128 # Bounds for parameters |
129 # Note that the parameters are also constrained to be integral | |
122 bounds = [(10, 80), | 130 bounds = [(10, 80), |
123 (1, 20), | 131 (1, 20), |
124 (10, 300), | 132 (10, 300), |
125 (1, 20), | 133 (1, 20), |
126 (10, 500)] | 134 (10, 500)] |
135 | |
127 # Initial solution | 136 # Initial solution |
128 x0 = [36, 10, 155, 5, 140] | 137 x0 = [36, 10, 155, 5, 140] |
129 dbh = sqlite3.connect('results.db') | 138 |
139 # Where to save results | |
140 dsn = 'results.db' | |
141 dbh = sqlite3.connect(dsn) | |
130 cur = dbh.cursor() | 142 cur = dbh.cursor() |
131 cur.execute(''' | 143 cur.execute(''' |
132 CREATE TABLE IF NOT EXISTS GAN190 ( | 144 CREATE TABLE IF NOT EXISTS GAN190 ( |
133 name TEXT, -- Circuit name | 145 name TEXT, -- Circuit name |
134 run INTEGER, -- Run number | 146 run INTEGER, -- Run number |
143 efficiency REAL, -- Measured efficiency (%) | 155 efficiency REAL, -- Measured efficiency (%) |
144 thd REAL, -- Total harmonic distortion (%) | 156 thd REAL, -- Total harmonic distortion (%) |
145 ipeak REAL, -- Peak drain current (A) | 157 ipeak REAL, -- Peak drain current (A) |
146 cost REAL -- Calculated cost metric | 158 cost REAL -- Calculated cost metric |
147 );''') | 159 );''') |
148 def ctr(): | 160 |
149 i = 0 | |
150 while True: | |
151 yield i | |
152 i += 1 | |
153 return differential_evolution(fn, bounds, x0 = x0, | 161 return differential_evolution(fn, bounds, x0 = x0, |
154 args = (cur, '/Users/oconnd1/bin/runltspice', ['-alt'], 'tmp', 'pa-GAN190-PP-nodriver.net', ctr()), | 162 args = (dsn, '/Users/oconnd1/bin/runltspice', [], 'tmp', 'pa-GAN190-PP-nodriver.net'), |
155 integrality = True, disp = True, seed = 12345) | 163 integrality = True, disp = True, seed = 12345, updating = 'deferred', workers = 4) |