def create_FEMM_bar(is_mmfr, rho, materials): """Create the property for LamSquirrel cage on the rotor Parameters ---------- is_mmfr : bool 1 to compute the rotor magnetomotive force / rotor magnetic field rho : float the Resistivity at 20°C materials : list List of materials already created in FEMM Returns ------- (str, list) material name "Rotor Bar", updated materials """ if is_mmfr: if "Rotor Bar" not in materials: femm.mi_addmaterial( "Rotor Bar", 1, 1, 0, 0, 1e-6 / rho, 0, 0, 1, 0, 0, 0, 0, 0 ) materials.append("Rotor Bar") else: if "Rotor Bar" not in materials: # replacing the rotor bars by air femm.mi_addmaterial("Rotor Bar", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0) materials.append("Rotor Bar") return "Rotor Bar", materials
def create_FEMM_magnet(label, is_mmf, is_eddies, materials, lam): """Set the material of the magnet in FEMM Parameters ---------- label : str label of the magnet is_mmfr : bool 1 to compute the lamination magnetomotive force / magnetic field is_eddies : bool 1 to calculate eddy currents materials : list list of materials already created in FEMM lam : LamSlotMag Lamination to set the magnet material Returns ------- (str, list) property, materials """ # some if's and else's to find the correct material parameter from magnet label if "HoleMagnet" in label: if "T0" in label: magnet = lam.hole[0].magnet_0 elif "T1" in label: magnet = lam.hole[0].magnet_1 elif "T2" in label: magnet = lam.hole[0].magnet_2 else: idx_str = findall(r"_T\d+_", label)[0][2:-1] magnet = lam.slot.magnet[int(idx_str)] # pole_mag = "_" + label[12] + "_" + label[-4] rho = magnet.mat_type.elec.rho # Resistivity at 20°C Hcm = magnet.mat_type.mag.Hc # Magnet coercitivity field mur = magnet.mat_type.mag.mur_lin if label not in materials: femm.mi_addmaterial( label, mur, mur, is_mmf * Hcm, 0, is_mmf * is_eddies * 1e-6 / rho, 0, 0, 1, 0, 0, 0, 0, 0, ) materials.append(label) return label, materials
def add(self): #ensure materials don't get added to the analysis more than once if self.add_count < 1: fe.mi_addmaterial(self.name, self.mu_r, self.mu_r, self.Hc, 0, self.conductivity, 0, 0, self.lam_fill, 0, 0, 0, self.num_strands) self.add_count += 1 else: pass
def affectation_materiaux(self): """Méthode permettant d'attribuer la propriété des matériaux""" # Affectation de l'air (x,y) femm.mi_addmaterial('Air', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(0, 0) femm.mi_selectlabel(0, 0) femm.mi_setblockprop('Air', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected() # Affectation du Cuivre (bobine positive) (Attention J en A/mm²) femm.mi_addmaterial('Cuivre-', 1, 1, 0, -self.k_b * self.j_max * 1.0e-6, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(self.largeur / 4, 0) femm.mi_selectlabel(self.largeur / 4, 0) femm.mi_setblockprop('Cuivre-', 0, 1, 'incricuit', 0, 0, 0) femm.mi_clearselected() # Affectation du Cuivre (bobine négative) femm.mi_addmaterial('Cuivre+', 1, 1, 0, self.k_b * self.j_max * 1.0e-6, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(-self.largeur / 4, 0) femm.mi_selectlabel(-self.largeur / 4, 0) femm.mi_setblockprop('Cuivre+', 0, 1, 'incircuit', 0, 0, 0) femm.mi_clearselected() # Matériau non linéaire # Création d'un matériau linéaire femm.mi_addmaterial('Iron', 2100, 2100, 0, 0, 0, 0, 0, 0, 0, 0, 0) # Les points de la courbe BH bdata = [ 0.1, 0.2, 0.4, 0.7, 1., 1.2, 1.3, 1.4, 1.5, 1.55, 1.6, 1.65, 1.7 ] hdata = [ 26.5, 37.8, 52.4, 71.9, 99.3, 136, 176, 279, 659, 1084, 1718, 2577, 3670 ] # Affectation des points de la courbe for n in range(0, len(bdata)): femm.mi_addbhpoint('Iron', bdata[n], hdata[n]) # Les points de la courbe Pertes fer = f(B) pdata = [ 0.0176, 0.0683, 0.240, 0.602, 1.09, 1.51, 1.79, 2.14, 2.56, 2.77, 2.96, 3.13, 3.29 ] self._interp_pertes_fer = interp1d(bdata, pdata, bounds_error=False, fill_value=(pdata[0], pdata[-1])) # Affectation du matériau femm.mi_addblocklabel(self.largeur / 2 - self.l_dent / 4, 0) femm.mi_selectlabel(self.largeur / 2 - self.l_dent / 4, 0) femm.mi_setblockprop('Iron', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected()
def add(self): #ensure materials don't get added to the analysis more than once if self.add_count < 1: H, B = np.loadtxt(self.file, unpack=True) fe.mi_addmaterial(self.name, 0, 0, 0, 0, 0, self.lam_thickness, 0, self.fill_factor, 0, 0, 0, 0, 0) for b, h in zip(B, H): fe.mi_addbhpoint(self.name, b, h) self.add_count += 1 else: pass
def set_FEMM_wind_material(materials, cname, Jcus, Cduct=None, dwire=None): """Create or update the property of a winding material Parameters ---------- materials: list list the name of all materials cname: str name of the material to create/update Jcus : float Applied source current density [A/mm^2] Cduct : float Electrical conductivity of the material [MS/m] dwire : float Diameter of each of the wire’s constituent strand [mm] Returns ------- circuits : list list the name of the circuits in FEMM """ if cname not in materials: # Create a new material femm.mi_addmaterial( cname, 1, # Relative permeability in the x- or r-direction 1, # Relative permeability in the y- or z-direction 0, # Permanent magnet coercivity [A/m] Jcus, Cduct, 0, # Lamination thickness [mm] 0, # Hysteresis lag angle [deg], (used for nonlinear BH curves) 1, # Fraction of the volume occupied per lamination that is actually filled withiron 0, # LamType (Not laminated) 0, # Hysteresis lag [deg] in the x-direction for linear problems 0, # Hysteresis lag [deg] in the y-direction for linear problems 1, # Number of strands in the wire build dwire, ) materials.append(cname) else: # Update existing one (set Jcus only) femm.mi_modifymaterial(cname, 4, Jcus) return materials
def __init__(self, bHide=False, meshsize=config.MESHSIZE, _i0=config.CURRENT, _id=None): """Initialize a FEMM solver Open FEMM and define the key elements of the magnetic problem. The problem is considered STATIC. All measurements are in MILLIMETERS here ! Keyword Arguments: bHide {bool} -- Either to show or hide the window. Hiding it provides a nice speed improvement (default: {False}) meshsize {number} -- Size of the mesh used for the finite elements. The smaller the more precise, but it comes with a computational cost (default: {1}) _i0 {number} -- Current used in computation. Any value should do, we use 100 to avoid working with very small floats (default: {100}) _id {number} -- Some id used to save the problem, if one requires to track and come back to the FEMM model (default: {None}) """ if _id is not None: self._seed = str(_id) else: self._seed = str(numpy.random.randint(10000)) self.meshsize = meshsize self.Lb = None self.Rbi = None self.Rbo = None self.phi = None self.rho = None self.n = None self.resistance = None self.Lp = None self.Rp = None self.m_vol_fer = None self.mu = None self.mass = None self.espace = None self.wire_type = None self._i0 = _i0 self.bHide = bHide femm.openfemm(bHide) femm.create(0) femm.mi_probdef(0, "millimeters", "axi", 1E-16) femm.mi_saveas("temp/temp" + self._seed + ".fem") femm.mi_addcircprop("Bobine", self._i0, 1) femm.mi_addmaterial("Air", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0)
def affectation_materiaux(self): """Méthode permettant d'attribuer la propriété des matériaux""" # Affectation de l'air (x,y) femm.mi_addmaterial('Air', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(0, 0) femm.mi_selectlabel(0, 0) femm.mi_setblockprop('Air', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected() # Affectation du Cuivre (bobine positive) (Attention J en A/mm²) femm.mi_addmaterial('Cuivre+', 1, 1, 0, self.k_b * self.j_max * 1.0e-6, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(self.largeur / 4, 0) femm.mi_selectlabel(self.largeur / 4, 0) femm.mi_setblockprop('Cuivre+', 0, 1, 'incricuit', 0, 0, 0) femm.mi_clearselected() # Affectation du Cuivre (bobine négative) femm.mi_addmaterial('Cuivre-', 1, 1, 0, -self.k_b * self.j_max * 1.0e-6, 0, 0, 0, 0, 0, 0, 0) femm.mi_addblocklabel(-self.largeur / 4, 0) femm.mi_selectlabel(-self.largeur / 4, 0) femm.mi_setblockprop('Cuivre-', 0, 1, 'incircuit', 0, 0, 0) femm.mi_clearselected() # Matériau non linéaire # Création d'un matériau linéaire femm.mi_addmaterial('Iron', 2100, 2100, 0, 0, 0, 0, 0, 0, 0, 0, 0) # Les points de la courbe BH bdata = [ 0., 0.2, 0.4, 0.7, 1, 1.2, 1.3, 1.4, 1.5, 1.55, 1.6, 1.65, 1.7, 1.8, 1.91, 2, 2.1, 3.2454 ] hdata = [ 0., 31.9, 44.9, 67.3, 106., 164., 235., 435., 1109., 1813., 2802., 4054., 5592., 9711., 16044., 31319., 88491., 1000000. ] # Affectation des points de la courbe for n in range(0, len(bdata)): femm.mi_addbhpoint('Iron', bdata[n], hdata[n]) # Affectation du matériau femm.mi_addblocklabel(self.largeur / 2 - self.l_dent / 4, 0) femm.mi_selectlabel(self.largeur / 2 - self.l_dent / 4, 0) femm.mi_setblockprop('Iron', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected()
def drawCoil(self): """Draw the coil Draws the coil in the FEMM instance Raises: Exception -- The coil is not defined, please call defineCoil before. """ if self.Lb is not None: femm.mi_clearselected() femm.mi_addmaterial("Cuivre", 1, 1, 0, 0, 1 / self.rho * 10**-6, 0, 0, 1, 3 if self.wire_type == "round" else 6, 0, 0, 1, self.phi) femm.mi_addnode(self.Rbi, -self.Lb / 2) femm.mi_addnode(self.Rbo, -self.Lb / 2) femm.mi_addnode(self.Rbi, self.Lb / 2) femm.mi_addnode(self.Rbo, self.Lb / 2) femm.mi_addsegment(self.Rbi, -self.Lb / 2, self.Rbo, -self.Lb / 2) femm.mi_addsegment(self.Rbo, -self.Lb / 2, self.Rbo, self.Lb / 2) femm.mi_addsegment(self.Rbo, self.Lb / 2, self.Rbi, self.Lb / 2) femm.mi_addsegment(self.Rbi, -self.Lb / 2, self.Rbi, self.Lb / 2) femm.mi_selectnode(self.Rbi, -self.Lb / 2) femm.mi_selectnode(self.Rbo, -self.Lb / 2) femm.mi_selectnode(self.Rbi, self.Lb / 2) femm.mi_selectnode(self.Rbo, self.Lb / 2) femm.mi_selectsegment(self.Rbi, 0) femm.mi_selectsegment((self.Rbi + self.Rbo) / 2, -self.Lb / 2) femm.mi_selectsegment(self.Rbo, 0) femm.mi_selectsegment((self.Rbi + self.Rbo) / 2, self.Lb / 2) femm.mi_setgroup(2) femm.mi_addblocklabel((self.Rbi + self.Rbo) / 2, 0) femm.mi_selectlabel((self.Rbi + self.Rbo) / 2, -self.Lb / 2) femm.mi_setblockprop("Cuivre", 0, self.meshsize, "Bobine", 0, 2, self.n) femm.mi_clearselected() else: raise Exception("No coil defined.")
def drawProjectile(self): """Draw projectile Draws the projectil in the FEMM instance Raises: Exception -- Projectile is not defined """ if self.Lp is not None: femm.mi_addmaterial("Projectile", self.mu, self.mu, 0, 0, 0, 0, 0, 1, 0, 0, 0) femm.mi_clearselected() femm.mi_addnode(0, -self.Lp / 2) femm.mi_addnode(self.Rp, -self.Lp / 2) femm.mi_addnode(0, self.Lp / 2) femm.mi_addnode(self.Rp, self.Lp / 2) femm.mi_addsegment(0, -self.Lp / 2, self.Rp, -self.Lp / 2) femm.mi_addsegment(self.Rp, -self.Lp / 2, self.Rp, self.Lp / 2) femm.mi_addsegment(self.Rp, self.Lp / 2, 0, self.Lp / 2) femm.mi_addsegment(0, self.Lp / 2, 0, -self.Lp / 2) femm.mi_selectnode(0, -self.Lp / 2) femm.mi_selectnode(self.Rp, -self.Lp / 2) femm.mi_selectnode(0, self.Lp / 2) femm.mi_selectnode(self.Rp, self.Lp / 2) femm.mi_selectsegment(0, 0) femm.mi_selectsegment(self.Rp / 2, -self.Lp / 2) femm.mi_selectsegment(self.Rp, 0) femm.mi_selectsegment(self.Rp / 2, self.Lp / 2) femm.mi_setgroup(1) femm.mi_addblocklabel(self.Rp / 2, 0) femm.mi_selectlabel(self.Rp / 2, 0) femm.mi_setblockprop("Projectile", 0, self.meshsize, "<None>", 0, 1, 0) femm.mi_clearselected() else: raise Exception("No projectile defined.")
simulation = sys.argv[1] # define problem parameters femm.mi_probdef(0, 'millimeters', 'planar', 1.e-8, 0, 30) def up_down(side): return ((-2 * side) + 1) def convert_measures(cm): return cm * 400 / 19 ## Materials femm.mi_addmaterial('Air', 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0) femm.mi_addmaterial('Coil', 1, 1, 0, 0, 58 * 0.65, 0, 0, 1, 0, 0, 0) femm.mi_addmaterial('Hiperco-50', 3520, 3520, 0, 0, 0, 0, 0, 1, 0, 0, 0) femm.mi_addmaterial('Magnet', 1.05, 1.05, 905659, 0, 0.667, 0, 0, 1, 0, 0, 0) bdata = [ 0.000000, 0.290730, 0.428710, 0.589560, 0.796270, 1.020100, 1.198100, 1.398900, 1.559600, 1.783500, 1.898500, 1.990700, 2.054400, 2.118400, 2.147700, 2.177000, 2.206500, 2.241700, 2.271200, 2.289000, 2.312600, 2.341000 ] hdata = [ 0.000000, 81.170000, 106.800000, 136.840000, 179.910000, 233.410000, 283.710000, 344.750000, 402.920000, 536.640000, 670.100000, 893.800000, 1290.400000, 2209.800000, 3233.700000, 4549.000000, 7297.800000, 11554.000000, 18294.000000, 25071.000000, 36690.000000, 62037.000000
# Draw a rectangle for the steel bar on the axis; femm.mi_drawrectangle(0, -40, 10, 40); # Draw a rectangle for the coil; femm.mi_drawrectangle(50, -50, 100, 50); # Define an "open" boundary condition using the built-in function: femm.mi_makeABC() # Add block labels, one to each the steel, coil, and air regions. femm.mi_addblocklabel(5,0); femm.mi_addblocklabel(75,0); femm.mi_addblocklabel(30,100); # Add some block labels materials properties femm.mi_addmaterial('Air', 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0); femm.mi_addmaterial('Coil', 1, 1, 0, 0, 58*0.65, 0, 0, 1, 0, 0, 0); femm.mi_addmaterial('LinearIron', 2100, 2100, 0, 0, 0, 0, 0, 1, 0, 0, 0); # A more interesting material to add is the iron with a nonlinear # BH curve. First, we create a material in the same way as if we # were creating a linear material, except the values used for # permeability are merely placeholders. femm.mi_addmaterial('Iron', 2100, 2100, 0, 0, 0, 0, 0, 1, 0, 0, 0); # A set of points defining the BH curve is then specified. bdata = [ 0.,0.3,0.8,1.12,1.32,1.46,1.54,1.62,1.74,1.87,1.99,2.046,2.08]; hdata = [ 0, 40, 80, 160, 318, 796, 1590, 3380, 7960, 15900, 31800, 55100, 79600]; for n in range(0,len(bdata)): femm.mi_addbhpoint('Iron', bdata[n],hdata[n]);
def create_FEMM_circuit(label, is_eddies, lam, I, is_mmf, j_t0, materials): """Set in FEMM circuits property Parameters ---------- label : label of the surface sym : integer for symmetry is_eddies : 1 to calculate eddy currents lam : LamSlotWind Lamination to set the winding I : ndarray Lamination currents waveforms is_mmf : 1 to compute the lamination magnetomotive force / lamination magnetic field j_t0 : time step for winding current calculation@type integer materials : list of materials already created in FEMM Returns ------- (str, list) the property of the surface having label as surf.label and materials """ is_defcirc = 1 # 1 to define circuits (necessary for eddy current loss kJ = 1 # estimation in AC mode, not necessary for magnetostatics) Zs = lam.slot.Zs rho = lam.mat_type.elec.rho # Resistivity at 20°C wind_mat = lam.winding.comp_connection_mat(Zs) # number of parallel circuits per phase (maximum 2p) Npcpp = lam.winding.Npcpp Ntcoil = lam.winding.Ntcoil # number of turns per coil Swire = lam.winding.conductor.comp_surface() Sact = lam.winding.conductor.comp_active_surface() if "Rotor" in label: # winding on the rotor Jlabel = "Jr" Clabel = "Circr" else: Jlabel = "Js" Clabel = "Circs" st = label.split("_") Nr = int(st[1][1:]) # zone radial coordinate Nt = int(st[2][1:]) # zone tangential coordinate pos = int(st[3][1:]) # Zone slot number coordinate A = wind_mat[Nr, Nt, pos, :] for zz in range(len(A)): # search for the phase of the winding if A[zz] != 0: q = zz # circuit definition if is_defcirc: if I.size == 0 or LA.norm(I) == 0: femm.mi_addcircprop(Clabel + str(q), 0, 1) # series connected else: femm.mi_addcircprop(Clabel + str(q), is_mmf * I[j_t0][q] / Npcpp, 1) # series connected # definition of armature field current sources and circuits s = sign(wind_mat[Nr, Nt, pos, q]) # same as the sign of Cwind1 if s == 1: cname = Jlabel + str(q) + "+" else: cname = Jlabel + str(q) + "-" if LA.norm(I) == 0: Jcus = 0 else: # equivalent stator current density [A/mm2] Jcus = kJ * 1e-6 * Ntcoil * (I[j_t0, q] / Npcpp) * is_mmf / Sact if cname not in materials: # adding new current source material if necessary femm.mi_addmaterial( cname, 1, 1, 0, s * Jcus, is_eddies * 1e-6 / rho, 0, 0, 1, 0, 0, 0, 1, sqrt(4 * Swire / pi), ) materials.append(cname) return cname, materials
wall_distance = 30000 wall_radius = 40000 wall_thickness = 10000 #functional variables# EXPERIMENT = 1 r = 0 r = inner_radius automesh = 1 meshsize = 30 minangle = 1 # Set up problem type. This sets up problem as an axisymmetric problem with units of micrometers femm.mi_probdef(0, 'micrometers', 'axi', 10**(-8), 0, minangle, 0) # Add materials to our workspace femm.mi_addmaterial('magnet', 1.05, 1.05, 922850, 0, 0.667, 0, 0, 1, 0, 0, 0) femm.mi_addmaterial('air', 1, 1, 0) femm.mi_addmaterial('36awgcopper', 1, 1, 0, i / ((wire_thickness / 2)**(2) * 3.14), 58, 0, 0, 1, 3, 0, 0, 1, 127) #change J applied current #define circuit with current i in series femm.mi_addcircprop('spiral', i, 1) #draw and label magnet wall femm.mi_drawrectangle(0, wall_distance, wall_radius, (wall_distance + wall_thickness)) femm.mi_addblocklabel(wall_radius / 2, (wall_distance + wall_thickness / 2)) femm.mi_selectlabel(wall_radius / 2, (wall_distance + wall_thickness / 2)) femm.mi_setblockprop('magnet', automesh, meshsize, 0, 270, 0, 0)
def create_FEMM_materials( machine, surf_list, Is, Ir, BHs, BHr, is_mmfs, is_mmfr, is_stator_linear_BH, is_rotor_linear_BH, is_eddies, j_t0, ): """Add materials in FEMM Parameters ---------- machine : Machine the machine to simulate surf_list : list List of surface of the machine Is : ndarray Stator current matrix [A] Ir : ndarray Rotor current matrix [A] BHs: ndarray B(H) curve of the stator BHr: ndarray B(H) curve of the rotor is_mmfs : bool 1 to compute the stator magnetomotive force/stator magnetic field is_mmfr : bool 1 to compute the rotor magnetomotive force / rotor magnetic field is_stator_linear_BH: bool 1 to use linear B(H) curve according to mur_lin, 0 to use the B(H) curve is_rotor_linear_BH: bool 1 to use linear B(H) curve according to mur_lin, 0 to use the B(H) curve is_eddies : bool 1 to calculate eddy currents jt_0 : int Current time step for winding calculation Returns ------- Tuple: dict, list Dictionary of properties and list containing the name of the circuits created """ prop_dict = dict() # Initialisation of the dictionnary to return rotor = machine.rotor stator = machine.stator materials = list() circuits = list() # Starting creation of properties for each surface of the machine for surf in surf_list: label = surf.label if "Lamination_Stator_bore" in label: # Stator if is_stator_linear_BH == 2: mu_is = 100000 # Infinite permeability else: mu_is = stator.mat_type.mag.mur_lin # Relative # Check if the property already exist in FEMM if "Stator Iron" not in materials: # magnetic permeability femm.mi_addmaterial( "Stator Iron", mu_is, mu_is, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ) materials.append("Stator Iron") prop_dict[label] = "Stator Iron" elif "Lamination_Rotor_bore" in label: # Rotor # Initialisation from the rotor of the machine if is_rotor_linear_BH == 2: mu_ir = 100000 # Infinite permeability else: mu_ir = rotor.mat_type.mag.mur_lin # Relative # Check if the property already exist in FEMM if "Rotor Iron" not in materials: # magnetic permeability femm.mi_addmaterial( "Rotor Iron", mu_ir, mu_ir, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ) materials.append("Rotor Iron") prop_dict[label] = "Rotor Iron" elif "Airgap" in label: # Airgap surface if "Airgap" not in materials: femm.mi_addmaterial("Airgap", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0) materials.append("Airgap") prop_dict[label] = "Airgap" elif "Ventilation" in label: # Ventilation # Check if the property already exist in FEMM if "Air" not in materials: femm.mi_addmaterial("Air", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0) materials.append("Air") prop_dict[label] = "Air" elif "Hole_" in label: # Hole but not HoleMagnet # Check if the property already exist in FEMM if "Air" not in materials: femm.mi_addmaterial("Air", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0) materials.append("Air") prop_dict[label] = "Air" elif "BarR" in label: # Squirrel cage prop, materials = create_FEMM_bar( is_mmfr, rotor.mat_type.elec.rho, materials ) prop_dict[label] = prop elif "WindR" in label: # Rotor Winding prop, materials, circuits = create_FEMM_circuit_material( circuits, label, is_eddies, rotor, Ir, is_mmfr, j_t0, materials ) prop_dict[label] = prop elif "WindS" in label: # Stator Winding prop, materials, circuits = create_FEMM_circuit_material( circuits, label, is_eddies, stator, Is, is_mmfs, j_t0, materials ) prop_dict[label] = prop elif "Magnet" in label and "Rotor" in label: # Rotor Magnet prop, materials = create_FEMM_magnet( label, is_mmfr, is_eddies, materials, rotor ) prop_dict[label] = prop elif "Magnet" in label and "Stator" in label: # Stator Magnet prop, materials = create_FEMM_magnet( label, is_mmfs, is_eddies, materials, stator ) prop_dict[label] = prop elif "No_mesh" in label: # Sliding band prop_dict[label] = "<No Mesh>" elif "yoke" in label: prop_dict[label] = "<No Mesh>" # Set Rotor and Stator BH curves (if needed) if is_stator_linear_BH == 0: for ii in range(BHs.shape[0]): femm.mi_addbhpoint("Stator Iron", BHs[ii][1], BHs[ii][0]) if is_rotor_linear_BH == 0: for ii in range(BHr.shape[0]): femm.mi_addbhpoint("Rotor Iron", BHr[ii][1], BHr[ii][0]) return prop_dict, materials, circuits
def initial_setup(boundary, currents, **kwargs): '''Start femm and setup problem definition and set boundary condition.''' if kwargs.get('hide') is True: femm.openfemm(1) femm.main_minimize() else: femm.openfemm() # newdocument(doctype) # From manual: Creates a new preprocessor document and opens up a new # preprocessor window. Specify doctype to be 0 for a magnetics problem, 1 # for an electrostatics problem, 2 for a heat flow problem, or 3 for a # current flow problem. An alternative syntax for this command is # create(doctype) femm.newdocument(0) # ei probdef(units,type,precision,(depth),(minangle)) # From manual: changes the problem definition. The units parameter # specifies the units used for measuring length in the problem domain. # Valid "units" entries are "inches", "millimeters", "centimeters", "mils", # "meters, and "micrometers". Set problemtype to "planar" for a 2-D planar # problem, or to "axi" for an axisymmetric problem. The precision parameter # dictates the precision required by the solver. For example, entering # 1.E-8 requires the RMS of the residual to be less than 10^-8. A fourth # parameter, representing the depth of the problem in the into-thepage # direction for 2-D planar problems, can also be specified for planar # problems. A sixth parameter represents the minimum angle constraint sent # to the mesh generator. if 'frequency' in kwargs: freq = kwargs['frequency'] else: freq = 6.78e6 if 'precision' in kwargs: precision = kwargs['precision'] else: precision = 5e-9 if 'min_angle' in kwargs: min_angle = kwargs['min_angle'] else: min_angle = 30 femm.mi_probdef(freq, 'millimeters', 'axi', precision, 50, min_angle) # Circuit parameters # mi addcircprop("circuitname", i, circuittype) # From manual: adds a new circuit property with name "circuitname" with a # prescribed current, i. The circuittype parameter is 0 for a # parallel-connected circuit and 1 for a series-connected circuit. # The currents in the primary and secondary circuits are set I1, I2 = currents femm.mi_addcircprop('phase_prim', I1, 1) femm.mi_addcircprop('phase_sec', I2, 1) # Add materials properties used in the simulation # mi addmaterial("materialname", mu x, mu y, H c, J, Cduct, Lam d, # Phi hmax, lam fill, LamType, Phi hx, Phi hy,NStrands,WireD) # From manual: adds a newmaterial with called "materialname" with the # material properties: # – mu x Relative permeability in the x- or r-direction. # – mu y Relative permeability in the y- or z-direction. # – H c Permanent magnet coercivity in Amps/Meter. # – J Real Applied source current density in Amps/mm2. # – Cduct Electrical conductivity of the material in MS/m. # – Lam d Lamination thickness in millimeters. # – Phi hmax Hysteresis lag angle in degrees, used for nonlinear BH curves. # – Lam fill Fraction of the volume occupied per lamination that is # actually filled with iron (Note that this parameter defaults to 1 the # femm preprocessor dialog box because, by default, iron completely fills # the volume) # – Lamtype Set to # ? 0 – Not laminated or laminated in plane # ? 1 – laminated x or r # ? 2 – laminated y or z # ? 3 – Magnet wire # ? 4 – Plain stranded wire # ? 5 – Litz wire # ? 6 – Square wire # – Phi hx Hysteresis lag in degrees in the x-direction for linear problems # – Phi hy Hysteresis lag in degrees in the y-direction for linear problems # – NStrands Number of strands in the wire build. Should be 1 for Magnet or # Square wire. # – WireD Diameter of each wire constituent strand in millimeters. femm.mi_addmaterial('air', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addmaterial('fr4', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addmaterial('copper', 1, 1, 0, 0, 58, 0, 0, 0, 0, 0, 0) femm.mi_addmaterial('polysterimide', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addmaterial('teflon', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) femm.mi_addmaterial('silgel', 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) if 'material' in kwargs: for m in kwargs['material']: femm.mi_addmaterial(*m) # Boundary condition # ei makeABC(n,R,x,y,bc) # From manual: creates a series of circular shells that emulate the # impedance of an unbounded domain (i.e. an Improvised Asymptotic Boundary # Condition). The n parameter contains the number of shells to be used # (should be between 1 and 10), R is the radius of the solution domain, and # (x,y) denotes the center of the solution domain. The bc parameter should # be specified as 0 for a Dirichlet outer edge or 1 for a Neumann outer # edge. If the function is called without all the parameters, the function # makes up reasonable values for the missing parameters. femm.mi_makeABC(7, boundary, 0, 0, 0)
# Precision of 10^(-8) for the linear solver; a placeholder of 0 for # the depth dimension, and an angle constraint of 30 degrees femm.mi_probdef(0, 'millimeters', 'axi', 1.e-8, 0, 30) # Draw a rectangle for the steel bar on the axis; femm.mi_drawrectangle(0, -40, 10, 40) # Define an "open" boundary condition using the built-in function: femm.mi_makeABC() # Add block labels, one to each the steel, coil, and air regions. femm.mi_addblocklabel(5, 0) femm.mi_addblocklabel(35, 15) # Add some block labels materials properties femm.mi_addmaterial('Air', 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0) femm.mi_addmaterial('LinearIron', 2100, 2100, 0, 0, 0, 0, 0, 1, 0, 0, 0) # Apply the materials to the appropriate block labels femm.mi_selectlabel(5, 0) femm.mi_setblockprop('LinearIron', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected() femm.mi_selectlabel(35, 15) femm.mi_setblockprop('Air', 0, 1, '<None>', 0, 0, 0) femm.mi_clearselected() # Now, the finished input geometry can be displayed. femm.mi_zoomnatural() # We have to give the geometry a name before we can analyze it.