Skip to content

Instantly share code, notes, and snippets.

@kingoflolz
Created December 31, 2018 03:24
Show Gist options
  • Save kingoflolz/95225ed5efeec5e28919fc62f1b6939c to your computer and use it in GitHub Desktop.
Save kingoflolz/95225ed5efeec5e28919fc62f1b6939c to your computer and use it in GitHub Desktop.
class Simulation:
def __init__(self):
self.commands = ["newdocument(0)", "showconsole()", 'mi_probdef(0, "millimeters", "planar", 1E-8)']
self.points = {}
self.materials = {}
self.circuits = 0
def run_sim(self):
self.commands += ['mi_saveas("Untitled.fem")', "mi_analyse()", "mi_loadsolution()"]
def calculate_force(self, blocks):
self.commands += ['mo_seteditmode("area")']
for i in blocks:
self.commands += ['mo_selectblock({}, {})'.format(i[0], i[1])]
self.commands += ['print(mo_blockintegral(18))']
def add_point(self, x, y):
if (x, y) not in self.points:
self.commands += ["mi_addnode({}, {})".format(x, y)]
self.points[(x, y)] = 0
def draw_line(self, x1, y1, x2, y2):
self.add_point(x1, y1)
self.add_point(x2, y2)
self.commands += ["mi_addsegment({}, {}, {}, {})".format(x1, y1, x2, y2)]
def rect_with_mat(self, x1, y1, x2, y2, name, mag_angle=0, current=0):
self.draw_contour([
(x1, y1),
(x1, y2),
(x2, y2),
(x2, y1),
])
self.set_materials((x1 + x2) / 2, (y1 + y2) / 2, name, mag_angle, current)
def draw_contour(self, l):
for iind, i in enumerate(l):
j = l[iind - 1]
self.draw_line(i[0], i[1], j[0], j[1])
def create_boundaries(self):
x = []
y = []
for k, v in self.points.items():
x.append(k[0])
y.append(k[1])
x_center = (max(x) - min(x)) / 2 + min(x)
y_center = (max(y) - min(y)) / 2 + min(y)
r = max(max(x) - min(x), max(y) - min(y))
self.commands += ["mi_makeABC(7, {}, {}, {}, {})".format(r, x_center, y_center, 0)]
def add_materials(self, name):
if name not in self.materials:
self.materials[name] = 0
self.commands += ['mi_getmaterial("{}")'.format(name)]
def set_materials(self, x, y, name, mag_angle=0, current=0):
self.add_materials(name)
current_str = ""
if current != 0:
self.circuits += 1
self.commands += ['mi_addcircprop("circuit{}", {}, 1)'.format(self.circuits, current, 1)]
current_str = "circuit" + str(self.circuits)
self.commands += ["mi_clearselected()"]
self.commands += ["mi_addblocklabel({}, {})".format(x, y)]
self.commands += ["mi_selectlabel({}, {})".format(x, y)]
self.commands += ['mi_setblockprop("{}", 1, 0, "{}", {}, 0, 1)'.format(name, current_str, mag_angle)]
def output(self):
return "\n\r".join(self.commands)
class Motor:
def __init__(self):
self.teeth_height = 1
self.notch_height = 6
self.teeth_width = 8
self.notch_width = 2
self.air_gap = 1
self.back_iron_thickness = 3
self.magnet_width = 6
self.magnet_thickness = 2
self.magnet_space = 1
self.offset = 0
def build_magnets(self, x, sim, a):
if a:
a1 = 90
else:
a1 = 270
sim.rect_with_mat(x, (self.notch_height + self.teeth_height) / 2 + self.air_gap,
x + self.magnet_width,
(self.notch_height + self.teeth_height) / 2 + self.air_gap + self.magnet_thickness,
"NdFeB 40 MGOe", mag_angle=a1)
sim.rect_with_mat(x, -(self.notch_height + self.teeth_height) / 2 - self.air_gap,
x + self.magnet_width,
-(self.notch_height + self.teeth_height) / 2 - self.air_gap - self.magnet_thickness,
"NdFeB 40 MGOe", mag_angle=a1)
def build(self):
sim = Simulation()
sim.draw_contour([(self.notch_width / 2, self.notch_height / 2),
(self.notch_width / 2, -self.notch_height / 2),
(self.teeth_width / 2, -self.notch_height / 2),
(self.teeth_width / 2, -self.notch_height / 2 - self.teeth_height),
(-self.teeth_width / 2, -self.notch_height / 2 - self.teeth_height),
(-self.teeth_width / 2, -self.notch_height / 2),
(-self.notch_width / 2, -self.notch_height / 2),
(-self.notch_width / 2, self.notch_height / 2),
(-self.teeth_width / 2, self.notch_height / 2),
(-self.teeth_width / 2, self.notch_height / 2 + self.teeth_height),
(self.teeth_width / 2, self.notch_height / 2 + self.teeth_height),
(self.teeth_width / 2, self.notch_height / 2),
])
sim.draw_line(self.teeth_width / 2, self.notch_height / 2, self.teeth_width / 2, -self.notch_height / 2)
sim.draw_line(-self.teeth_width / 2, self.notch_height / 2, -self.teeth_width / 2, -self.notch_height / 2)
sim.set_materials(0, 0, "M-36 Steel")
sim.set_materials((self.teeth_width - self.notch_width) / 2, 0, "Copper", current=50 * 9)
sim.set_materials(-(self.teeth_width - self.notch_width) / 2, 0, "Copper", current=-50 * 9)
for i in range(4):
self.build_magnets((i - 2) * (self.magnet_width + self.magnet_space) + self.magnet_space/2, sim, i % 2)
sim.rect_with_mat(-2 * (self.magnet_width + self.magnet_space), (self.notch_height + self.teeth_height) / 2 + self.air_gap + self.magnet_thickness,
2 * (self.magnet_width + self.magnet_space), (self.notch_height + self.teeth_height) / 2 + self.air_gap + self.magnet_thickness + self.back_iron_thickness,
"M-36 Steel")
sim.rect_with_mat(-2 * (self.magnet_width + self.magnet_space), -(self.notch_height + self.teeth_height) / 2 - self.air_gap - self.magnet_thickness,
2 * (self.magnet_width + self.magnet_space), -(self.notch_height + self.teeth_height) / 2 - self.air_gap - self.magnet_thickness - self.back_iron_thickness,
"M-36 Steel")
sim.set_materials(0, (self.notch_height + self.air_gap / 2) / 2 + self.teeth_height, "Air")
sim.create_boundaries()
sim.run_sim()
sim.calculate_force([(0, 0), (self.teeth_width / 2 - 0.01, 0), ( - self.teeth_width / 2 + 0.01, 0)])
print(sim.output())
m = Motor()
m.build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment