Extract inductace sims for the paper
This commit is contained in:
parent
d310493e93
commit
f450e4fded
3 changed files with 31 additions and 13 deletions
|
|
@ -395,7 +395,8 @@ across rotations works, with twisted inductors ($k>1$) showing a further improve
|
|||
which prove to be better than simple single-layer spiral inductors. As one would expect, this gain is greatest for
|
||||
inductors with low turn count, as their turns deviate the furthest from a set of ideal, concentric circles. For the
|
||||
our test inductor with an inner diameter of \qty{15}{\milli\meter} and an outer diameter of \qty{35}{\milli\meter},
|
||||
$k=3$ trace pairs already provided an improvement over standard configurations.
|
||||
$k=3$ trace pairs already provided an improvement over standard configurations, with even better performance observed
|
||||
for $k=7$ trace pairs.
|
||||
|
||||
\todo{concrete coupling factor measurements}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import time
|
|||
import math
|
||||
import json
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
import tqdm
|
||||
import click
|
||||
|
|
@ -25,7 +26,7 @@ def mesh_args(db, coil_id, mesh_type, mesh_file, outfile, **kwargs):
|
|||
rows = dict(db.execute('SELECT key, value FROM results WHERE coil_id=?', (coil_id,)).fetchall())
|
||||
rows.update(kwargs)
|
||||
args = ['python', '-m', 'twisted_coil_gen_twolayer', mesh_type, mesh_file, '--pcb']
|
||||
for k, v in rows:
|
||||
for k, v in rows.items():
|
||||
prefix, _, k = k.partition('.')
|
||||
if v != 'False' and prefix == 'gen':
|
||||
args.append('--' + k.replace('_', '-'))
|
||||
|
|
@ -104,9 +105,10 @@ def list_runs(ctx):
|
|||
|
||||
@cli.command()
|
||||
@click.option('-r', '--run-id')
|
||||
@click.option('-l', '--log-dir', default='logs', type=click.Path(dir_okay=True, file_okay=False, path_type=pathlib.Path))
|
||||
@click.option('-m', '--mesh-dir', default='meshes')
|
||||
@click.pass_context
|
||||
def list_coils(ctx, run_id, mesh_dir):
|
||||
def list_coils(ctx, run_id, log_dir, mesh_dir):
|
||||
db = ctx.obj['db_connect']()
|
||||
if run_id is None:
|
||||
run_id, = db.execute('SELECT run_id FROM runs ORDER BY timestamp DESC LIMIT 1').fetchone()
|
||||
|
|
@ -122,9 +124,11 @@ def list_coils(ctx, run_id, mesh_dir):
|
|||
'gen.inner_diameter': 'ID[mm]',
|
||||
'gen.outer_diameter': 'OD[mm]',
|
||||
'calculated_fill_factor': 'Fill factor',
|
||||
'calculated_approximate_inductance': 'L [µH]',
|
||||
'calculated_approximate_inductance': 'L [µH] (design)',
|
||||
'calculated_trace_length': 'track len [mm]',
|
||||
'calculated_approximate_resistance': 'R [mΩ]'}
|
||||
'calculated_approximate_resistance': 'R [mΩ] (design)',
|
||||
'sim_inductance': 'L [µH] (sim)',
|
||||
'sim_resistance': 'R [mΩ] (sim)'}
|
||||
out = []
|
||||
for row in db.execute('SELECT *, MAX(meshes.timestamp) FROM coils LEFT JOIN meshes ON coils.coil_id=meshes.coil_id WHERE run_id=? GROUP BY coils.coil_id, mesh_type ORDER BY meshes.timestamp', (run_id,)).fetchall():
|
||||
if row['timestamp']:
|
||||
|
|
@ -151,6 +155,19 @@ def list_coils(ctx, run_id, mesh_dir):
|
|||
if 'calculated_fill_factor' in params:
|
||||
params['calculated_fill_factor'] = f'{float(params["calculated_fill_factor"]):.03f}'
|
||||
|
||||
log_file = log_dir / (pathlib.Path(row['filename']).stem + '_elmer_self_inductance.log')
|
||||
if log_file.is_file():
|
||||
log = log_file.read_text()
|
||||
resistance = re.search(r'Coil resistance calculated by solver: ([0-9.e+-]*) (\w?)Ω', log)
|
||||
inductance = re.search(r'Inductance calucated from field: ([0-9.e+-]*) (\w?)H', log)
|
||||
si_prefix = {'': 1, 'm': 1e-3, 'µ': 1e-6, 'n': 1e-9, 'p': 1e-12}
|
||||
if resistance:
|
||||
resistance = float(resistance.group(1)) * si_prefix[resistance.group(2)]
|
||||
params['sim_resistance'] = format(resistance*1e3, '.3f')
|
||||
if inductance:
|
||||
inductance = float(inductance.group(1)) * si_prefix[inductance.group(2)]
|
||||
params['sim_inductance'] = format(inductance*1e6, '.3f')
|
||||
|
||||
out.append([row['coil_id'], row['mesh_type'], state, row['timestamp']] + [params.get(key, '-') for key in keys])
|
||||
|
||||
print(tabulate(out, headers=['coil', 'mesh', 'state', 'time'] + list(keys.values()), disable_numparse=True, stralign='right'))
|
||||
|
|
@ -180,13 +197,13 @@ def run(ctx, run_id, log_dir, mesh_dir):
|
|||
|
||||
@run.command()
|
||||
@click.option('-j', '--num-jobs', type=int, default=1, help='Number of jobs to run in parallel')
|
||||
@click.option('-t', '--mesh-type', type=click.Choice(['split', 'normal', 'mutual']), default=['split', 'normal', 'mutual'], multiple=True)
|
||||
@click.pass_context
|
||||
def generate_meshes(ctx, num_jobs):
|
||||
def generate_meshes(ctx, num_jobs, mesh_type):
|
||||
db = ctx.obj['db_connect']()
|
||||
rows = [row['coil_id'] for row in db.execute('SELECT coil_id FROM coils WHERE run_id=?', (ctx.obj['run_id'],)).fetchall()]
|
||||
mesh_types = ['split', 'normal', 'mutual']
|
||||
|
||||
params = list(itertools.product(rows, mesh_types))
|
||||
params = list(itertools.product(rows, mesh_type))
|
||||
all_files = {get_mesh_file(db, ctx.obj['mesh_dir'], ctx.obj['run_id'], coil_id, mesh_type): (coil_id, mesh_type) for coil_id, mesh_type in params}
|
||||
todo = [(coil_id, mesh_type) for f, (coil_id, mesh_type) in all_files.items() if not f.is_file()]
|
||||
|
||||
|
|
@ -232,7 +249,7 @@ def self_inductance(ctx, num_jobs):
|
|||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
try:
|
||||
tqdm.tqdm.write(f'Processing {mesh_file}')
|
||||
res = subprocess.run(['python', '-m', 'coil_parasitics', 'inductance', '--sim-dir', tmpdir, mesh_file], check=True, capture_output=True)
|
||||
res = subprocess.run(['python', '-m', 'coil_parasitics', 'inductance', '--sim-dir', tmpdir, mesh_file], check=True, capture_output=True, text=True)
|
||||
logfile.write_text(res.stdout+res.stderr)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f'Error running simulation, rc={e.returncode}')
|
||||
|
|
@ -266,8 +283,8 @@ def self_inductance(ctx, num_jobs):
|
|||
q.join()
|
||||
|
||||
@run.command()
|
||||
@click.option('target_hosts', type=click.Path(exists=True, dir_okay=False, path_type=pathlib.Path), help='File with one SSH target host name per line')
|
||||
@click.option('job_file', type=click.Path(exists=True, dir_okay=False, path_type=pathlib.Path), help='JSON job description file')
|
||||
@click.argument('target_hosts', type=click.Path(exists=True, dir_okay=False, path_type=pathlib.Path))
|
||||
@click.argument('job_file', type=click.Path(exists=True, dir_okay=False, path_type=pathlib.Path))
|
||||
@click.pass_context
|
||||
def run_mutual_inductance(ctx, target_hosts, job_file):
|
||||
db = ctx.obj['db_connect']()
|
||||
|
|
|
|||
|
|
@ -891,7 +891,7 @@ def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_d
|
|||
svg_vias.append(Tag('circle', cx=xv, cy=yv, r=via_diameter/2, stroke='none', fill='white'))
|
||||
svg_vias.append(Tag('circle', cx=xv, cy=yv, r=via_drill/2, stroke='none', fill='black'))
|
||||
|
||||
l_total = clen*twists*2
|
||||
l_total = clen*twists*(2 if two_layer else 1)
|
||||
print(f'Approximate track length: {l_total:.2f} mm', file=sys.stderr)
|
||||
A = copper_thickness/1e3 * trace_width/1e3
|
||||
rho = 1.68e-8
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue