kopia lustrzana https://gitlab.com/gerbolyze/gerbonara
Update sims & gen
rodzic
0ae13de322
commit
1ce02a9d25
|
@ -23,6 +23,7 @@ copper:
|
|||
Heat Capacity: 415.0 # 200°C
|
||||
Heat Conductivity: 401.0 # 0°C
|
||||
Relative Permeability: 1
|
||||
Relative Permittivity: 1
|
||||
steel_1.4541:
|
||||
Density: 7900.0 # 20°C
|
||||
Electric Conductivity: 1370
|
||||
|
|
|
@ -116,7 +116,7 @@ def cli():
|
|||
@cli.command()
|
||||
@click.option('-d', '--sim-dir', type=click.Path(dir_okay=True, file_okay=False, path_type=Path))
|
||||
@click.argument('mesh_file', type=click.Path(dir_okay=False, path_type=Path))
|
||||
def self_capacitance(mesh_file, sim_dir):
|
||||
def capacitance_matrix(mesh_file, sim_dir):
|
||||
physical = dict(enumerate_mesh_bodies(mesh_file))
|
||||
if sim_dir is not None:
|
||||
sim_dir = Path(sim_dir)
|
||||
|
@ -133,14 +133,14 @@ def self_capacitance(mesh_file, sim_dir):
|
|||
'Unit Charge': str(constants.elementary_charge)})
|
||||
|
||||
air = elmer.load_material('air', sim, 'coil_parasitics_materials.yml')
|
||||
ro4003c = elmer.load_material('ro4003c', sim, 'coil_parasitics_materials.yml')
|
||||
fr4 = elmer.load_material('fr4', sim, 'coil_parasitics_materials.yml')
|
||||
|
||||
solver_electrostatic = elmer.load_solver('Electrostatics_Capacitance', sim, 'coil_parasitics_solvers.yml')
|
||||
solver_electrostatic.data['Potential Difference'] = '1.0'
|
||||
eqn = elmer.Equation(sim, 'main', [solver_electrostatic])
|
||||
|
||||
bdy_sub = elmer.Body(sim, 'substrate', [physical['substrate'][1]])
|
||||
bdy_sub.material = ro4003c
|
||||
bdy_sub.material = fr4
|
||||
bdy_sub.equation = eqn
|
||||
|
||||
bdy_ab = elmer.Body(sim, 'airbox', [physical['airbox'][1]])
|
||||
|
@ -202,7 +202,7 @@ def inductance(mesh_file, sim_dir, solver_method):
|
|||
'Unit Charge': str(constants.elementary_charge)})
|
||||
|
||||
air = elmer.load_material('air', sim, 'coil_mag_materials.yml')
|
||||
ro4003c = elmer.load_material('ro4003c', sim, 'coil_mag_materials.yml')
|
||||
fr4 = elmer.load_material('fr4', sim, 'coil_mag_materials.yml')
|
||||
copper = elmer.load_material('copper', sim, 'coil_mag_materials.yml')
|
||||
|
||||
solver_current = elmer.load_solver('Static_Current_Conduction', sim, 'coil_mag_solvers.yml')
|
||||
|
@ -219,7 +219,7 @@ def inductance(mesh_file, sim_dir, solver_method):
|
|||
bdy_trace.equation = copper_eqn
|
||||
|
||||
bdy_sub = elmer.Body(sim, 'substrate', [physical['substrate'][1]])
|
||||
bdy_sub.material = ro4003c
|
||||
bdy_sub.material = fr4
|
||||
bdy_sub.equation = air_eqn
|
||||
|
||||
bdy_ab = elmer.Body(sim, 'airbox', [physical['airbox'][1]])
|
||||
|
@ -313,7 +313,7 @@ def mutual_inductance(mesh_file, sim_dir, reference_field):
|
|||
'Unit Charge': str(constants.elementary_charge)})
|
||||
|
||||
air = elmer.load_material('air', sim, 'coil_mag_materials.yml')
|
||||
ro4003c = elmer.load_material('ro4003c', sim, 'coil_mag_materials.yml')
|
||||
fr4 = elmer.load_material('fr4', sim, 'coil_mag_materials.yml')
|
||||
copper = elmer.load_material('copper', sim, 'coil_mag_materials.yml')
|
||||
|
||||
solver_current = elmer.load_solver('Static_Current_Conduction', sim, 'coil_mag_solvers.yml')
|
||||
|
@ -332,11 +332,11 @@ def mutual_inductance(mesh_file, sim_dir, reference_field):
|
|||
bdy_trace2.equation = copper_eqn
|
||||
|
||||
bdy_sub1 = elmer.Body(sim, 'substrate1', [physical['substrate1'][1]])
|
||||
bdy_sub1.material = ro4003c
|
||||
bdy_sub1.material = fr4
|
||||
bdy_sub1.equation = air_eqn
|
||||
|
||||
bdy_sub2 = elmer.Body(sim, 'substrate2', [physical['substrate2'][1]])
|
||||
bdy_sub2.material = ro4003c
|
||||
bdy_sub2.material = fr4
|
||||
bdy_sub2.equation = air_eqn
|
||||
|
||||
|
||||
|
@ -422,6 +422,114 @@ def mutual_inductance(mesh_file, sim_dir, reference_field):
|
|||
print(f'Mutual inductance calucated from field: {format_si(Lm, "H")}')
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option('-d', '--sim-dir', type=click.Path(dir_okay=True, file_okay=False, path_type=Path))
|
||||
@click.argument('mesh_file', type=click.Path(dir_okay=False, path_type=Path))
|
||||
def self_capacitance(mesh_file, sim_dir):
|
||||
physical = dict(enumerate_mesh_bodies(mesh_file))
|
||||
|
||||
if sim_dir is not None:
|
||||
sim_dir = Path(sim_dir)
|
||||
sim_dir.mkdir(exist_ok=True)
|
||||
|
||||
sim = elmer.load_simulation('3D_steady', 'self_capacitance_sim.yml')
|
||||
mesh_dir = '.'
|
||||
mesh_fn = 'mesh'
|
||||
sim.header['Mesh DB'] = f'"{mesh_dir}" "{mesh_fn}"'
|
||||
sim.constants.update({
|
||||
'Permittivity of Vacuum': str(constants.epsilon_0),
|
||||
'Gravity(4)': f'0 -1 0 {constants.g}',
|
||||
'Boltzmann Constant': str(constants.Boltzmann),
|
||||
'Unit Charge': str(constants.elementary_charge)})
|
||||
|
||||
air = elmer.load_material('air', sim, 'coil_mag_materials.yml')
|
||||
fr4 = elmer.load_material('fr4', sim, 'coil_mag_materials.yml')
|
||||
copper = elmer.load_material('copper', sim, 'coil_mag_materials.yml')
|
||||
|
||||
solver_current = elmer.load_solver('StaticCurrent', sim, 'self_capacitance_solvers.yml')
|
||||
solver_estat = elmer.load_solver('Electrostatics', sim, 'self_capacitance_solvers.yml')
|
||||
|
||||
copper_eqn = elmer.Equation(sim, 'copperEqn', [solver_current, solver_estat])
|
||||
air_eqn = elmer.Equation(sim, 'airEqn', [solver_estat])
|
||||
|
||||
bdy_trace = elmer.Body(sim, 'trace', [physical['trace'][1]])
|
||||
bdy_trace.material = copper
|
||||
bdy_trace.equation = copper_eqn
|
||||
|
||||
bdy_sub = elmer.Body(sim, 'substrate', [physical['substrate'][1]])
|
||||
bdy_sub.material = fr4
|
||||
bdy_sub.equation = air_eqn
|
||||
|
||||
bdy_ab = elmer.Body(sim, 'airbox', [physical['airbox'][1]])
|
||||
bdy_ab.material = air
|
||||
bdy_ab.equation = air_eqn
|
||||
|
||||
bdy_if_top = elmer.Body(sim, 'interface_top', [physical['interface_top'][1]])
|
||||
bdy_if_top.material = copper
|
||||
bdy_if_top.equation = copper_eqn
|
||||
|
||||
bdy_if_bottom = elmer.Body(sim, 'interface_bottom', [physical['interface_bottom'][1]])
|
||||
bdy_if_bottom.material = copper
|
||||
bdy_if_bottom.equation = copper_eqn
|
||||
|
||||
potential_force = elmer.BodyForce(sim, 'electric_potential', {'Potential': 'Equals "PotentialStat"'})
|
||||
bdy_trace.body_force = potential_force
|
||||
|
||||
# boundaries
|
||||
boundary_airbox = elmer.Boundary(sim, 'FarField', [physical['airbox_surface'][1]])
|
||||
boundary_airbox.data['Electric Infinity BC'] = 'True'
|
||||
|
||||
boundary_vplus = elmer.Boundary(sim, 'Vplus', [physical['interface_top'][1]])
|
||||
boundary_vplus.data['PotentialStat'] = 'Real 1.0'
|
||||
boundary_vplus.data['Save Scalars'] = True
|
||||
|
||||
boundary_vminus = elmer.Boundary(sim, 'Vminus', [physical['interface_bottom'][1]])
|
||||
boundary_vminus.data['PotentialStat'] = 'Real 0.0'
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
tmpdir = sim_dir if sim_dir else Path(tmpdir)
|
||||
|
||||
sim.write_startinfo(tmpdir)
|
||||
sim.write_sif(tmpdir)
|
||||
# Convert mesh from gmsh to elemer formats. Also scale it from 1 unit = 1 mm to 1 unit = 1 m (SI units)
|
||||
elmer_grid(mesh_file.absolute(), 'mesh', cwd=tmpdir, scale=[1e-3, 1e-3, 1e-3],
|
||||
stdout_log=(tmpdir / 'ElmerGrid_stdout.log'),
|
||||
stderr_log=(tmpdir / 'ElmerGrid_stderr.log'))
|
||||
solver_stdout, solver_stderr = (tmpdir / 'ElmerSolver_stdout.log'), (tmpdir / 'ElmerSolver_stderr.log')
|
||||
res = elmer_solver(tmpdir,
|
||||
stdout_log=solver_stdout,
|
||||
stderr_log=solver_stderr)
|
||||
|
||||
P, R, U_mag = None, None, None
|
||||
solver_error = False
|
||||
for l in res.stdout.splitlines():
|
||||
if (m := re.fullmatch(r'StatCurrentSolve:\s*Total Heating Power\s*:\s*([0-9.+-Ee]+)\s*', l)):
|
||||
P = float(m.group(1))
|
||||
elif (m := re.fullmatch(r'StatCurrentSolve:\s*Effective Resistance\s*:\s*([0-9.+-Ee]+)\s*', l)):
|
||||
R = float(m.group(1))
|
||||
elif (m := re.fullmatch(r'MagnetoDynamicsCalcFields:\s*ElectroMagnetic Field Energy\s*:\s*([0-9.+-Ee]+)\s*', l)):
|
||||
U_mag = float(m.group(1))
|
||||
elif re.fullmatch(r'IterSolve: Linear iteration did not converge to tolerance', l):
|
||||
solver_error = True
|
||||
|
||||
if solver_error:
|
||||
raise click.ClickException(f'Error: One of the solvers did not converge. See log files for details:\n{solver_stdout.absolute()}\n{solver_stderr.absolute()}')
|
||||
elif P is None or R is None or U_mag is None:
|
||||
raise click.ClickException(f'Error during solver execution. Electrical parameters could not be calculated. See log files for details:\n{solver_stdout.absolute()}\n{solver_stderr.absolute()}')
|
||||
|
||||
V = math.sqrt(P*R)
|
||||
I = math.sqrt(P/R)
|
||||
L = 2*U_mag / (I**2)
|
||||
|
||||
assert math.isclose(V, 1.0, abs_tol=1e-3)
|
||||
|
||||
print(f'Total magnetic field energy: {format_si(U_mag, "J")}')
|
||||
print(f'Reference coil current: {format_si(I, "Ω")}')
|
||||
print(f'Coil resistance calculated by solver: {format_si(R, "Ω")}')
|
||||
print(f'Inductance calucated from field: {format_si(L, "H")}')
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
|
||||
|
|
|
@ -1,47 +1,53 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import math
|
||||
import re
|
||||
import itertools
|
||||
import datetime
|
||||
import tempfile
|
||||
import subprocess
|
||||
import sqlite3
|
||||
import json
|
||||
|
||||
import tqdm
|
||||
|
||||
import gerbonara.cad.kicad.pcb as pcb
|
||||
import gerbonara.cad.kicad.footprints as fp
|
||||
import gerbonara.cad.primitives as cad_pr
|
||||
import gerbonara.cad.kicad.graphical_primitives as kc_gr
|
||||
|
||||
|
||||
cols = 6
|
||||
rows = 4
|
||||
|
||||
coil_specs = [
|
||||
{'n': 1, 's': True, 't': 1, 'c': 0.20, 'w': 5.00, 'v': 0.40},
|
||||
{'n': 2, 's': True, 't': 1, 'c': 0.20, 'w': 3.00, 'v': 0.40},
|
||||
{'n': 3, 's': True, 't': 1, 'c': 0.20, 'w': 1.50, 'v': 0.40},
|
||||
{'n': 5, 's': True, 't': 1, 'c': 0.20, 'w': 0.80, 'v': 0.40},
|
||||
{'n': 10, 's': True, 't': 1, 'c': 0.20, 'w': 0.50, 'v': 0.40},
|
||||
{'n': 25, 's': True, 't': 1, 'c': 0.15, 'w': 0.25, 'v': 0.40},
|
||||
{'n': 1, 's': True, 't': 1, 'c': 0.20, 'w': 5.00, 'd': 3.00, 'v': 5.00},
|
||||
{'n': 2, 's': True, 't': 1, 'c': 0.20, 'w': 3.00, 'd': 1.50, 'v': 3.00},
|
||||
{'n': 3, 's': True, 't': 1, 'c': 0.20, 'w': 1.50, 'd': 1.20, 'v': 2.00},
|
||||
{'n': 5, 's': True, 't': 1, 'c': 0.20, 'w': 0.80, 'd': 0.40, 'v': 0.80},
|
||||
{'n': 10, 's': True, 't': 1, 'c': 0.20, 'w': 0.50, 'd': 0.30, 'v': 0.60},
|
||||
{'n': 25, 's': True, 't': 1, 'c': 0.15, 'w': 0.25, 'd': 0.30, 'v': 0.60},
|
||||
|
||||
{'n': 1, 's': False, 't': 1, 'c': 0.20, 'w': 5.00, 'v': 0.40},
|
||||
{'n': 2, 's': False, 't': 1, 'c': 0.20, 'w': 3.00, 'v': 0.40},
|
||||
{'n': 3, 's': False, 't': 1, 'c': 0.20, 'w': 1.50, 'v': 0.40},
|
||||
{'n': 5, 's': False, 't': 1, 'c': 0.20, 'w': 0.80, 'v': 0.40},
|
||||
{'n': 10, 's': False, 't': 1, 'c': 0.20, 'w': 0.50, 'v': 0.40},
|
||||
{'n': 25, 's': False, 't': 1, 'c': 0.15, 'w': 0.25, 'v': 0.40},
|
||||
{'n': 1, 's': False, 't': 3, 'c': 0.20, 'w': 5.00, 'd': 3.00, 'v': 5.00},
|
||||
{'n': 2, 's': False, 't': 1, 'c': 0.20, 'w': 3.00, 'd': 1.50, 'v': 3.00},
|
||||
{'n': 3, 's': False, 't': 1, 'c': 0.20, 'w': 2.50, 'd': 1.20, 'v': 2.00},
|
||||
{'n': 5, 's': False, 't': 1, 'c': 0.20, 'w': 2.50, 'd': 0.40, 'v': 0.80},
|
||||
{'n': 10, 's': False, 't': 1, 'c': 0.20, 'w': 1.50, 'd': 0.30, 'v': 0.60},
|
||||
{'n': 25, 's': False, 't': 1, 'c': 0.15, 'w': 0.50, 'd': 0.30, 'v': 0.60},
|
||||
|
||||
{'n': 1, 's': False, 't': 3, 'c': 0.20, 'w': 5.00, 'v': 0.40},
|
||||
{'n': 2, 's': False, 't': 3, 'c': 0.20, 'w': 3.00, 'v': 0.40},
|
||||
{'n': 3, 's': False, 't': 2, 'c': 0.20, 'w': 1.50, 'v': 0.40},
|
||||
{'n': 5, 's': False, 't': 2, 'c': 0.20, 'w': 0.80, 'v': 0.40},
|
||||
{'n': 10, 's': False, 't': 3, 'c': 0.20, 'w': 0.50, 'v': 0.40},
|
||||
{'n': 25, 's': False, 't': 2, 'c': 0.15, 'w': 0.25, 'v': 0.40},
|
||||
{'n': 1, 's': False, 't': 4, 'c': 0.20, 'w': 5.00, 'd': 3.00, 'v': 5.00},
|
||||
{'n': 2, 's': False, 't': 3, 'c': 0.20, 'w': 3.00, 'd': 1.50, 'v': 3.00},
|
||||
{'n': 3, 's': False, 't': 4, 'c': 0.20, 'w': 2.50, 'd': 1.20, 'v': 2.00},
|
||||
{'n': 5, 's': False, 't': 3, 'c': 0.20, 'w': 2.50, 'd': 0.40, 'v': 0.80},
|
||||
{'n': 10, 's': False, 't': 3, 'c': 0.20, 'w': 1.50, 'd': 0.30, 'v': 0.60},
|
||||
{'n': 25, 's': False, 't': 3, 'c': 0.15, 'w': 0.50, 'd': 0.30, 'v': 0.60},
|
||||
|
||||
{'n': 1, 's': False, 't': 5, 'c': 0.20, 'w': 5.00, 'v': 0.40},
|
||||
{'n': 2, 's': False, 't': 5, 'c': 0.20, 'w': 3.00, 'v': 0.40},
|
||||
{'n': 3, 's': False, 't': 4, 'c': 0.20, 'w': 1.50, 'v': 0.40},
|
||||
{'n': 5, 's': False, 't': 3, 'c': 0.20, 'w': 0.80, 'v': 0.40},
|
||||
{'n': 10, 's': False, 't': 7, 'c': 0.20, 'w': 0.50, 'v': 0.40},
|
||||
{'n': 25, 's': False, 't': 7, 'c': 0.15, 'w': 0.25, 'v': 0.40},
|
||||
{'n': 1, 's': False, 't': 5, 'c': 0.20, 'w': 5.00, 'd': 3.00, 'v': 5.00},
|
||||
{'n': 2, 's': False, 't': 5, 'c': 0.20, 'w': 3.00, 'd': 1.50, 'v': 3.00},
|
||||
{'n': 3, 's': False, 't': 4, 'c': 0.20, 'w': 2.50, 'd': 1.20, 'v': 2.00},
|
||||
{'n': 5, 's': False, 't': 7, 'c': 0.20, 'w': 2.50, 'd': 0.40, 'v': 0.80},
|
||||
{'n': 10, 's': False, 't': 7, 'c': 0.20, 'w': 1.50, 'd': 0.30, 'v': 0.60},
|
||||
{'n': 25, 's': False, 't': 13, 'c': 0.15, 'w': 0.50, 'd': 0.30, 'v': 0.60},
|
||||
]
|
||||
|
||||
version_string = 'v1.0'
|
||||
|
@ -55,6 +61,8 @@ mouse_bite_hole_spacing = 0.3
|
|||
hole_offset = 5
|
||||
hole_dia = 3.2
|
||||
coil_dia = 35 # mm
|
||||
coil_inner_dia = 15 # mm
|
||||
board_thickness = 0.80 # mm
|
||||
pad_offset = 2 # mm
|
||||
pad_dia = 2.0 # mm
|
||||
pad_length = 3.5 # mm
|
||||
|
@ -62,6 +70,16 @@ pad_drill = 1.1 # mm
|
|||
pad_pitch = 2.54 # mm
|
||||
v_cuts = False # FIXME DEBUG
|
||||
mouse_bites = False # FIXME DEBUG
|
||||
|
||||
db = sqlite3.connect('coil_parameters.sqlite3')
|
||||
db.execute('CREATE TABLE IF NOT EXISTS runs (run_id INTEGER PRIMARY KEY, timestamp TEXT, version TEXT)')
|
||||
db.execute('CREATE TABLE IF NOT EXISTS coils (coil_id INTEGER PRIMARY KEY, run_id INTEGER, FOREIGN KEY (run_id) REFERENCES runs(run_id))')
|
||||
db.execute('CREATE TABLE IF NOT EXISTS results (result_id INTEGER PRIMARY KEY, coil_id INTEGER, key TEXT, value TEXT, FOREIGN KEY (coil_id) REFERENCES coils(coil_id))')
|
||||
cur = db.cursor()
|
||||
cur.execute('INSERT INTO runs(timestamp, version) VALUES (datetime("now"), ?)', (version_string,))
|
||||
run_id = cur.lastrowid
|
||||
db.commit()
|
||||
|
||||
coil_pitch = coil_dia + coil_border*2 + cut_gap
|
||||
|
||||
total_width = coil_pitch*cols + 2*tooling_border + cut_gap
|
||||
|
@ -286,52 +304,78 @@ b.add(kc_gr.Text(text=f'Planar inductor test panel {version_string} {timestamp}
|
|||
thickness=a/5),
|
||||
justify=pcb.Justify(h=pcb.Atom.left, v=pcb.Atom.top))))
|
||||
|
||||
for index, ((y, x), spec) in enumerate(zip(itertools.product(range(rows), range(cols)), coil_specs), start=1):
|
||||
for index, ((y, x), spec) in tqdm.tqdm(enumerate(zip(itertools.product(range(rows), range(cols)), coil_specs), start=1)):
|
||||
pass
|
||||
with tempfile.NamedTemporaryFile(suffix='.kicad_mod') as f:
|
||||
tile_x0 = x0 + tooling_border + cut_gap + x*coil_pitch + tile_width/2
|
||||
tile_y0 = y0 + tooling_border + cut_gap + y*coil_pitch + tile_height/2
|
||||
|
||||
for key, alias in {
|
||||
'inner_diameter': 'id',
|
||||
'outer_diameter': 'od',
|
||||
'trace_width': 'w',
|
||||
'turns': 'n',
|
||||
'twists': 't',
|
||||
'clearance': 'c',
|
||||
'single_layer': 's',
|
||||
'via_drill': 'v'}.items():
|
||||
'gen.inner_diameter': 'id',
|
||||
'gen.outer_diameter': 'od',
|
||||
'gen.trace_width': 'w',
|
||||
'gen.turns': 'n',
|
||||
'gen.twists': 't',
|
||||
'gen.clearance': 'c',
|
||||
'gen.single_layer': 's',
|
||||
'gen.via_drill': 'd',
|
||||
'gen.via_diameter': 'v'}.items():
|
||||
if alias in spec:
|
||||
spec[key] = spec.pop(alias)
|
||||
|
||||
if 'via_diameter' not in spec:
|
||||
spec['via_diameter'] = spec['trace_width']
|
||||
if 'gen.via_diameter' not in spec:
|
||||
spec['gen.via_diameter'] = spec['gen.trace_width']
|
||||
|
||||
if 'inner_diameter' not in spec:
|
||||
spec['inner_diameter'] = 15
|
||||
if 'gen.inner_diameter' not in spec:
|
||||
spec['gen.inner_diameter'] = coil_inner_dia
|
||||
|
||||
if 'outer_diameter' not in spec:
|
||||
spec['outer_diameter'] = 35
|
||||
if 'gen.outer_diameter' not in spec:
|
||||
spec['gen.outer_diameter'] = coil_dia
|
||||
|
||||
args = ['python', '-m', 'twisted_coil_gen_twolayer', '--no-keepout-zone']
|
||||
for k, v in spec.items():
|
||||
if not isinstance(v, bool) or v:
|
||||
prefix, _, k = k.partition('.')
|
||||
if (not isinstance(v, bool) or v) and prefix == 'gen':
|
||||
args.append('--' + k.replace('_', '-'))
|
||||
if v is not True:
|
||||
args.append(str(v))
|
||||
args.append(f.name)
|
||||
subprocess.run(args, check=True)
|
||||
res = subprocess.run(args, check=True, capture_output=True, text=True)
|
||||
|
||||
coil = fp.Footprint.open_mod(f.name)
|
||||
coil.at = fp.AtPos(tile_x0, tile_y0, 0)
|
||||
b.add(coil)
|
||||
|
||||
t = [f'n={spec["turns"]}',
|
||||
f'{spec["twists"]} twists',
|
||||
f'w={spec["trace_width"]:.2f}mm']
|
||||
if spec.get('single_layer'):
|
||||
t = [f'n={spec["gen.turns"]}',
|
||||
f'{spec["gen.twists"]} twists',
|
||||
f'w={spec["gen.trace_width"]:.2f}mm']
|
||||
if spec.get('gen.single_layer'):
|
||||
t.append('single layer')
|
||||
|
||||
spec['gen.board_thickness'] = board_thickness
|
||||
cur.execute('INSERT INTO coils(run_id) VALUES (?)', (run_id,))
|
||||
coil_id = cur.lastrowid
|
||||
|
||||
for key, value in spec.items():
|
||||
if isinstance(value, bool):
|
||||
value = str(value)
|
||||
db.execute('INSERT INTO results(coil_id, key, value) VALUES (?, ?, ?)', (coil_id, key, value))
|
||||
|
||||
for l in res.stderr.splitlines():
|
||||
if (m := re.fullmatch(r'Approximate inductance:\s*([-+.0-9eE]+)\s*µH', l.strip())):
|
||||
val = float(m.group(1)) * 1e-6
|
||||
db.execute('INSERT INTO results(coil_id, key, value) VALUES (?, "calculated_approximate_inductance", ?)', (coil_id, val))
|
||||
if (m := re.fullmatch(r'Approximate track length:\s*([-+.0-9eE]+)\s*mm', l.strip())):
|
||||
val = float(m.group(1)) * 1e-3
|
||||
db.execute('INSERT INTO results(coil_id, key, value) VALUES (?, "calculated_trace_length", ?)', (coil_id, val))
|
||||
if (m := re.fullmatch(r'Approximate resistance:\s*([-+.0-9eE]+)\s*Ω', l.strip())):
|
||||
val = float(m.group(1))
|
||||
db.execute('INSERT INTO results(coil_id, key, value) VALUES (?, "calculated_approximate_resistance", ?)', (coil_id, val))
|
||||
if (m := re.fullmatch(r'Fill factor:\s*([-+.0-9eE]+)', l.strip())):
|
||||
val = float(m.group(1))
|
||||
db.execute('INSERT INTO results(coil_id, key, value) VALUES (?, "calculated_fill_factor", ?)', (coil_id, val))
|
||||
db.commit()
|
||||
|
||||
sz = 1.5
|
||||
b.add(kc_gr.Text(text='\\n'.join(t),
|
||||
at=pcb.AtPos(tile_x0, tile_y0),
|
||||
|
@ -361,7 +405,7 @@ for index, ((y, x), spec) in enumerate(zip(itertools.product(range(rows), range(
|
|||
pads = make_pads(pads_x0, tile_y0, 270, 2, pad_dia, pad_length, pad_drill, pad_pitch)
|
||||
b.add(pads)
|
||||
|
||||
w = min(spec.get('trace_width', pad_dia), pad_dia)
|
||||
w = min(spec.get('gen.trace_width', pad_dia), pad_dia)
|
||||
x, y, _r, _f = pads.pad(2).abs_pos
|
||||
w2 = (x - pad_length/2, y)
|
||||
x, y, _r, _f = pads.pad(1).abs_pos
|
||||
|
|
|
@ -537,9 +537,9 @@ def print_valid_twists(ctx, param, value):
|
|||
@click.option('--show-twists', callback=print_valid_twists, expose_value=False, type=int, is_eager=True, help='Calculate and show valid --twists counts for the given number of turns. Takes the number of turns as a value.')
|
||||
@click.option('--clearance', type=float, default=None)
|
||||
@click.option('--arc-tolerance', type=float, default=0.02)
|
||||
@click.option('--mesh-split-out', type=click.Path(writable=True, dir_okay=False, path_type=Path))
|
||||
@click.option('--mesh-out', type=click.Path(writable=True, dir_okay=False, path_type=Path))
|
||||
@click.option('--mag-mesh-out', type=click.Path(writable=True, dir_okay=False, path_type=Path))
|
||||
@click.option('--mag-mesh-mutual-out', type=click.Path(writable=True, dir_okay=False, path_type=Path))
|
||||
@click.option('--mesh-mutual-out', type=click.Path(writable=True, dir_okay=False, path_type=Path))
|
||||
@click.option('--mutual-offset-x', type=float, default=0)
|
||||
@click.option('--mutual-offset-y', type=float, default=0)
|
||||
@click.option('--mutual-offset-z', type=float, default=5)
|
||||
|
@ -550,8 +550,8 @@ def print_valid_twists(ctx, param, value):
|
|||
@click.version_option()
|
||||
def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_drill, via_offset, trace_width, clearance,
|
||||
footprint_name, layer_pair, twists, clipboard, counter_clockwise, keepout_zone, keepout_margin,
|
||||
arc_tolerance, pcb, mesh_out, magneticalc_out, circle_segments, mag_mesh_out, copper_thickness,
|
||||
board_thickness, mag_mesh_mutual_out, mutual_offset_x, mutual_offset_y, mutual_offset_z, mutual_rotation_z,
|
||||
arc_tolerance, pcb, mesh_out, magneticalc_out, circle_segments, mesh_split_out, copper_thickness,
|
||||
board_thickness, mesh_mutual_out, mutual_offset_x, mutual_offset_y, mutual_offset_z, mutual_rotation_z,
|
||||
two_layer):
|
||||
|
||||
if 'WAYLAND_DISPLAY' in os.environ:
|
||||
|
@ -562,8 +562,8 @@ def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_d
|
|||
if gcd(twists, turns) != 1:
|
||||
raise click.ClickException('For the geometry to work out, the --twists parameter must be co-prime to --turns, i.e. the two must have 1 as their greatest common divisor. You can print valid values for --twists by running this command with --show-twists [turns number].')
|
||||
|
||||
if mesh_out and not pcb:
|
||||
raise click.ClickException('--pcb is required when --mesh-out is used.')
|
||||
if (mesh_out or mesh_split_out or mesh_mutual_out) and not pcb:
|
||||
raise click.ClickException('--pcb is required when --mesh-out, --mesh-mutual-out or --mesh-split-out are used.')
|
||||
|
||||
if magneticalc_out and not pcb:
|
||||
raise click.ClickException('--pcb is required when --magneticalc-out is used.')
|
||||
|
@ -903,16 +903,16 @@ def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_d
|
|||
traces[0] = traces[0][1:]
|
||||
|
||||
r = outer_diameter/2 + 20
|
||||
if mesh_split_out:
|
||||
traces_to_gmsh(traces, mesh_split_out, ((-r, -r), (r, r)), copper_thickness=copper_thickness, board_thickness=board_thickness)
|
||||
|
||||
if mesh_out:
|
||||
traces_to_gmsh(traces, mesh_out, ((-r, -r), (r, r)), copper_thickness=copper_thickness, board_thickness=board_thickness)
|
||||
traces_to_gmsh_mag(traces, mesh_out, ((-r, -r), (r, r)), copper_thickness=copper_thickness, board_thickness=board_thickness)
|
||||
|
||||
if mag_mesh_out:
|
||||
traces_to_gmsh_mag(traces, mag_mesh_out, ((-r, -r), (r, r)), copper_thickness=copper_thickness, board_thickness=board_thickness)
|
||||
|
||||
if mag_mesh_mutual_out:
|
||||
if mesh_mutual_out:
|
||||
m_dx, m_dy, m_dz = mutual_offset_x, mutual_offset_y, mutual_offset_z
|
||||
mutual_rotation_z = math.radians(mutual_rotation_z)
|
||||
traces_to_gmsh_mag_mutual(traces, mag_mesh_mutual_out, ((-r, -r), (r, r)),
|
||||
traces_to_gmsh_mag_mutual(traces, mesh_mutual_out, ((-r, -r), (r, r)),
|
||||
copper_thickness=copper_thickness, board_thickness=board_thickness,
|
||||
mutual_offset=(m_dx, m_dy, m_dz), mutual_rotation=(0, 0, mutual_rotation_z))
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue