Example #1
0
def setMagnet(r, phi, mat, magdir, group=-1):
    if group == -1:
        group = femmgroupmode
    n = cmath.rect(r, rad(phi))
    femm.mi_selectlabel(n.real, n.imag)
    femm.mi_setblockprop(mat, 1, 0, '<None>', magdir, group, 0)
    femm.mi_clearselected()
Example #2
0
def setCirc(r, phi, mat, circuit, turns, group=-1):
    if group == -1:
        group = femmgroupmode
    n = cmath.rect(r, rad(phi))
    femm.mi_selectlabel(n.real, n.imag)
    femm.mi_setblockprop(mat, 1, 0, circuit, 0, group, turns)
    femm.mi_clearselected()
Example #3
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.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()
Example #4
0
def draw_conductor(coords, in_conductor, label_name, label_dict):
    '''Draw a square conductor, set a block label in the middle of the
    conductor and add label properties.'''
    femm.mi_drawrectangle(*coords)

    label_coord = (average(
        (coords[0], coords[2])), average((coords[1], coords[3])))
    femm.mi_addblocklabel(*label_coord)
    femm.mi_selectlabel(*label_coord)
    if in_conductor == 1:
        femm.mi_setblockprop('copper', 1, 0, 'phase_prim', 0, 1, 1)
    elif in_conductor == 0:
        femm.mi_setblockprop('copper', 1, 0, 'phase_sec', 0, 1, 1)
    femm.mi_clearselected()
    label_dict[label_name] = label_coord
Example #5
0
 def assign_material(self,
                     material,
                     turns=None,
                     circuit=None,
                     where: Point = None):
     if where is None:
         where = self.get_midpoint()
     self.addblocklabel(where.x, where.y)
     self.selectlabel(where.x, where.y)
     if self.problemType is ProblemType.ElectroStatic:
         femm.ei_setblockprop(material, 1, 0, self.index)
     elif self.problemType is ProblemType.MagnetoStatic:
         assert turns is not None
         assert circuit is not None
         # blockname, automesh, meshsize, incircuit, magdir, group, turns
         femm.mi_setblockprop(material, 1, 0, circuit, 0, self.index, turns)
     self.clearselected()
    def setSpace(self):
        """Define space

        Define the whole space used in FEMM

        Raises:
            Exception -- Coil and projectile must be defined first to compute a safe space size.
        """
        if self.Lp is not None and self.Lb is not None:
            femm.mi_clearselected()
            self.espace = self.__space_factor * max(self.Lb, self.Rbo, self.Lp)
            femm.mi_addblocklabel(2 * self.Rbo, 0)
            femm.mi_selectlabel(2 * self.Rbo, 0)
            femm.mi_setblockprop("Air", 0, self.meshsize, "<None>", 0, 3, 0)
            femm.mi_makeABC(7, self.espace, 0, 0, 0)
            femm.mi_zoomnatural()
        else:
            raise Exception("Define coil and projectile first.")
Example #7
0
 def build_coil(self, coil_dict):
     """
     load coil_cross sections into femm environment
     :param coil_dict:
     :return:
     """
     for section, section_tuple in coil_dict.items():
         path_point = np.array(section_tuple[0])
         profile = section_tuple[1] + path_point
         # draw line segments between nodes
         for index, point in enumerate(profile):
             last_point = profile[index - 1]
             femm.mi_drawline(last_point[1], last_point[0], point[1],
                              point[0])
         femm.mi_addblocklabel(path_point[1], path_point[0])
         femm.mi_selectlabel(path_point[1], path_point[0])
         femm.mi_setblockprop(str(section))
         femm.mi_clearselected()
    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.")
Example #10
0
    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.")
Example #11
0
    def set_materials(self, magnet, iron):

        #ensure that the materials are actually added to the analysis
        magnet.add()
        iron.add()

        R1 = self.OR - (self.dm + self.dri)  #inner radius of rotor
        R2 = self.OR - self.dm  #radius to inside of PM

        #assign magnet material
        mag_center = [(R2 + self.OR) / 2, 0]
        mag_orientation = 1  #1 = North facing out, -1 = North facing in

        num_magnets = 2 * self.p
        theta = 360 / num_magnets

        for i in range(num_magnets):
            xy = rotate(*mag_center, theta * i)

            #add 180 degrees if magnet faces in
            mag_dir = theta * i + 180 * (mag_orientation < 0
                                         )  #magnet orientation in deg
            fe.mi_addblocklabel(*xy)
            fe.mi_selectlabel(*xy)
            fe.mi_setblockprop(magnet.name, 1, 0, 0, mag_dir, 0, 0)
            fe.mi_clearselected()

            mag_dir *= -1  #alternate between N and S poles

        #assign steel material
        xy = [(R1 + R2) / 2, 0]

        fe.mi_addblocklabel(*xy)
        fe.mi_selectlabel(*xy)
        fe.mi_setblockprop(iron.name, 1, 0, 0, 0, 1, 0)
        fe.mi_clearselected()

        #add air to center if rotor is hollow
        if self.hollow:
            fe.mi_addblocklabel(0, 0)
            fe.mi_selectlabel(0, 0)
            fe.mi_setblockprop('Air', 1, 0, 0, 0, 0, 0)
            fe.mi_clearselected()
            -halfWidth + leftCurrentGap + currentWidth +
            (iman * (bodyWidth + innerStatorGap)),
            (halfHeight - barHeight - currentHeight) * up_down(side),
        )

        current_x_label = -halfWidth + leftCurrentGap + (currentWidth / 2) + (
            iman * (bodyWidth + innerStatorGap))
        current_y_label = (halfHeight - barHeight -
                           (currentHeight / 2)) * up_down(side)

        femm.mi_addblocklabel(current_x_label, current_y_label)

        femm.mi_addcircprop(f"circuit_{side}_{iman}", 30, 1)

        femm.mi_selectlabel(current_x_label, current_y_label)
        femm.mi_setblockprop('Coil', 0, 1, f"circuit_{side}_{iman}", 0, 0,
                             500 * up_down(side) * up_down(iman % 2))
        femm.mi_clearselected()

        femm.mi_drawline(
            -halfWidth + leftCurrentGap + bodyWidth + (2 * currentWidth) +
            (iman * (bodyWidth + innerStatorGap)),
            (halfHeight - barHeight) * up_down(side),
            -halfWidth + leftCurrentGap + bodyWidth + (2 * currentWidth) +
            (iman * (bodyWidth + innerStatorGap)),
            (halfHeight - barHeight - currentHeight) * up_down(side),
        )

        femm.mi_drawline(
            -halfWidth + leftCurrentGap + bodyWidth + (2 * currentWidth) +
            (iman * (bodyWidth + innerStatorGap)),
            (halfHeight - barHeight - currentHeight) * up_down(side),
Example #13
0
    femm.mi_drawrectangle(
        0.05, -0.1, 0.1,
        0.1)  # Primary Coil 0.2" Height, 0.05" inner radius, 0.1" outer radius
    femm.mi_drawrectangle(
        0.05, 0.11, 0.1, 0.31
    )  # Top Secondary Coil 0.2" Height, 0.05" inner radius, 0.1" outer radius
    femm.mi_drawrectangle(
        0.05, -0.31, 0.1, -0.11
    )  # Bottom Secondary Coil 0.2" Height, 0.05" inner radius, 0.1" outer radius

    # Add Block Labels, materials, and circuits

    # Air Label
    femm.mi_addblocklabel(0.3, 0)
    femm.mi_selectlabel(0.3, 0)
    femm.mi_setblockprop('Air', 1, 0, '<None>', 0, 0, 0)

    # Pure Iron Label
    femm.mi_clearselected()
    femm.mi_addblocklabel(0.02, d)
    femm.mi_selectlabel(0.02, d)
    femm.mi_setblockprop('Pure Iron', 1, 0, '<None>', 0, 0, 0)

    # Secondary Coil Copper Labels
    femm.mi_clearselected()
    femm.mi_addblocklabel(0.075, 0.21)
    femm.mi_addblocklabel(0.075, -0.21)
    femm.mi_selectlabel(0.075, 0.21)
    femm.mi_selectlabel(0.075, -0.21)
    femm.mi_setblockprop('30 AWG', 1, 0, '<None>', 0, 0, 0)
Example #14
0
def setCircZ(n, mat, circuit, turns, group=-1):
    if group == -1:
        group = femmgroupmode
    femm.mi_selectlabel(n.real, n.imag)
    femm.mi_setblockprop(mat, 1, 0, circuit, 0, group, turns)
    femm.mi_clearselected()
Example #15
0
femm.mi_addcircprop('icoil', current, 1)  # Add it to the FEMM model

od_coil = id_coil + 2 * N_layers * od_wire  # outer coil diameter

coil_group_number = 5  # Define coil number different as magnet
# Call this function to draw a box with rounded corners
# I find this introduces less errors
coil_center_x = id_coil / 2 + (od_coil - id_coil) / 4
coil_center_y = 0
drawroundedcorner_box(femm, coil_group_number, (od_coil - id_coil) / 2, Lc,
                      coil_center_x, coil_center_y, od_wire, 0)
# With segments now drawn, label it
femm.mi_addblocklabel(coil_center_x,
                      coil_center_y)  # Create a label within the coil segments
femm.mi_selectlabel(coil_center_x, coil_center_y)  # Select that label
femm.mi_setblockprop('22 AWG', 0, 1, 'icoil', 0, 0,
                     N_layers * N_turns)  # Apply properties to the label
femm.mi_clearselected()

### DEFINE AIR REGION

air_x = od_coil / 2 + id_coil / 4
air_y = 0
femm.mi_addblocklabel(air_x, air_y)
femm.mi_selectlabel(air_x, air_y)
femm.mi_setblockprop('Air', 0, 1, '<none>', 0, 0, 0)
femm.mi_clearselected()

# DEFINE THE PERMANENT MAGNET
Lm = 0.6 * inches  # Magnet length
od_m = 0.5 * inches  # Magnet Diameter(assumes cylindrical magnet)
mag_y_loc_o = Lc / 2 + 2 * Lc  # Initial position of the magnet
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)
femm.mi_clearselected()

#draw and label spiral cross section
while (r < outer_radius):
    if (r == inner_radius):
        pass
    else:
        r = r + wire_spacing

    inner_edge = r
    outer_edge = r + wire_thickness
    femm.mi_drawarc(inner_edge, 0, outer_edge, 0, 180, EXPERIMENT)
    #mi_drawarc(x1,y1,x2,y2,angle,maxseg)
    femm.mi_addarc(outer_edge, 0, inner_edge, 0, 180, EXPERIMENT)
    #other half of circle
Example #17
0
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]);

# Add a "circuit property" so that we can calculate the properties of the
# coil as seen from the terminals.
femm.mi_addcircprop('icoil', 20, 1);

# Apply the materials to the appropriate block labels
femm.mi_selectlabel(5,0);
femm.mi_setblockprop('Iron', 0, 1, '<None>', 0, 0, 0);
femm.mi_clearselected()

femm.mi_selectlabel(75,0);
femm.mi_setblockprop('Coil', 0, 1, 'icoil', 0, 0, 200);
femm.mi_clearselected()

femm.mi_selectlabel(30,100);
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.
femm.mi_saveas('coil.fem');
Example #18
0
    def simulate(self):
        self.__updateDimensions()
        # open FEMM
        femm.openfemm()
        femm.main_maximize()

        # True Steady State
        # new Magnetostatics document

        femm.newdocument(0)

        # Define the problem type.  Magnetostatic; Units of mm; 2D planar;
        # 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', 'planar', 1.e-8, 0, 30)

        # Import Materials
        femm.mi_getmaterial('Air')
        femm.mi_getmaterial(self.magnetType)
        femm.mi_getmaterial(self.windingType)

        # Draw geometry
        # Coil
        for coil in range(0, self.numStators):
            corner = Vector(coil * (self.coilLength + self.coilBufferLength), 0)
            femm.mi_drawrectangle(corner.x, corner.y, corner.x + self.coilLength, corner.y + self.pcbThickness)
            femm.mi_addblocklabel(corner.x + self.coilLength / 2, corner.y + self.pcbThickness / 2)
            femm.mi_selectlabel(corner.x + self.coilLength / 2, corner.y + self.pcbThickness / 2)
            femm.mi_setblockprop(self.windingType, 1, 0, '<None>', 0, 0, self.numWindings)


        # # Upper Rotor
        for magnet in range(0, self.numPoles):
            corner = Vector(magnet * (self.magnetLength + self.magnetBufferLength), self.pcbThickness + self.airGap)
            femm.mi_drawrectangle(corner.x, corner.y, corner.x + self.magnetLength, corner.y + self.rotorThickness)
            femm.mi_addblocklabel(corner.x + self.magnetLength / 2, corner.y + self.rotorThickness / 2)
            femm.mi_selectlabel(corner.x + self.magnetLength / 2, corner.y + self.rotorThickness / 2)
            if magnet % 2 == 0:
                femm.mi_setblockprop(self.magnetType, 1, 0, '<None>', 90, 0, 0)
            else:
                femm.mi_setblockprop(self.magnetType, 1, 0, '<None>', -90, 0, 0)
            if magnet == int(self.numPoles / 2):
                self.testPoint = Vector(corner.x, 0 + self.pcbThickness / 2)

        # Lower Rotor
        for magnet in range(0, self.numPoles):
            corner = Vector(magnet * (self.magnetLength + self.magnetBufferLength), -self.airGap)
            femm.mi_drawrectangle(corner.x, corner.y, corner.x + self.magnetLength, corner.y - self.rotorThickness)
            femm.mi_addblocklabel(corner.x + self.magnetLength / 2, corner.y - self.rotorThickness / 2)
            femm.mi_selectlabel(corner.x + self.magnetLength / 2, corner.y - self.rotorThickness / 2)
            if magnet % 2 == 0:
                femm.mi_setblockprop(self.magnetType, 1, 0, '<None>', 90, 0, 0)
            else:
                femm.mi_setblockprop(self.magnetType, 1, 0, '<None>', -90, 0, 0)

        # Define an "open" boundary condition using the built-in function:
        # Add air block label outside machine
        femm.mi_makeABC()
        airLabel = Vector((self.numStators / 2) * (self.coilLength + self.coilBufferLength), 5 * (self.rotorThickness + self.airGap))
        femm.mi_addblocklabel(airLabel.x, airLabel.y)
        femm.mi_selectlabel(airLabel.x, airLabel.y)
        femm.mi_setblockprop('Air', 1, 0, '<None>', 0, 0, 0)

        # We have to give the geometry a name before we can analyze it.
        femm.mi_saveas('alternatorSim.fem')

        # Now,analyze the problem and load the solution when the analysis is finished
        femm.mi_analyze()
        femm.mi_loadsolution()

        # Now, the finished input geometry can be displayed.
        # femm.mo_zoom(self.testPoint.x - 2 * self.coilLength, self.testPoint.y - self.coilLength,
        #              self.testPoint.x + 2 * self.coilLength,
        #              self.testPoint.y + self.coilLength)
        # femm.mo_showdensityplot(1, 0, 1, 0, 'mag')

        self.fluxDensity = self.getFlux()
def assign_FEMM_surface(surf, prop, FEMM_dict, rotor, stator):
    """Assign the property given in parameter to surface having the label given
    Parameters
    ----------
    surf : Surface
        the surface to assign
    prop : str
        The property to assign in FEMM
    FEMM_dict : dict
        Dictionnary containing the main parameters of FEMM
    rotor : Lamination
        The rotor of the machine
    stator : Lamination
        The stator of the machine
    Returns
    -------
    None

    """

    mesh_dict = get_mesh_param(surf.label, FEMM_dict)
    label = surf.label
    Clabel = 0  # By default no circuit
    Ntcoil = 0  # By default no circuit
    mag = 0  # By default no magnetization

    # Select the lamination according to the label
    if "Rotor" in label:
        lam = rotor
    else:
        lam = stator

    # point_ref is None => don't assign the surface
    if surf.point_ref is not None:
        # Select the surface
        point_ref = surf.point_ref
        femm.mi_addblocklabel(point_ref.real, point_ref.imag)
        femm.mi_selectlabel(point_ref.real, point_ref.imag)

        # Get circuit or magnetization properties if needed
        if "Wind" in label:  # If the surface is a winding
            if "Rotor" in label:  # Winding on the rotor
                Clabel = "Circr" + prop[2]
            else:  # winding on the stator
                Clabel = "Circs" + prop[2]
            Ntcoil = lam.winding.Ntcoil
            if prop[-1] == "-":  # Adapt Ntcoil sign if needed
                Ntcoil *= -1
        elif "HoleMagnet" in label:  # LamHole
            if "Parallel" in label:
                # calculate pole angle and angle of pole middle
                alpha_p = 360 / lam.hole[0].Zh
                mag_0 = (floor_divide(angle(point_ref, deg=True), alpha_p) +
                         0.5) * alpha_p

                # HoleM50 or HoleM53
                if (type(lam.hole[0]) == HoleM50) or (type(lam.hole[0])
                                                      == HoleM53):
                    if "_T0_" in label:
                        mag = mag_0 + lam.hole[0].comp_alpha() * 180 / pi
                    else:
                        mag = mag_0 - lam.hole[0].comp_alpha() * 180 / pi

                # HoleM51
                if type(lam.hole[0]) == HoleM51:
                    if "_T0_" in label:
                        mag = mag_0 + lam.hole[0].comp_alpha() * 180 / pi
                    elif "_T1_" in label:
                        mag = mag_0
                    else:
                        mag = mag_0 - lam.hole[0].comp_alpha() * 180 / pi

                # HoleM52
                if type(lam.hole[0]) == HoleM52:
                    mag = mag_0

                # modifiy magnetisation of south poles
                if "_S_" in label:
                    mag = mag + 180
            else:
                raise NotImplementedYetError(
                    "Only parallele magnetization are available for HoleMagnet"
                )
        elif "Magnet" in label:  # LamSlotMag
            if "Radial" in label and "_N_" in label:  # Radial magnetization
                mag = "theta"  # North pole magnet
            elif "Radial" in label:
                mag = "theta + 180"  # South pole magnet
            elif "Parallel" in label and "_N_" in label:
                mag = angle(point_ref) * 180 / pi  # North pole magnet
            elif "Parallel" in label:
                mag = angle(point_ref) * 180 / pi + 180  # South pole magnet
            elif "Hallbach" in label:
                Zs = lam.slot.Zs
                mag = str(-(Zs / 2 - 1)) + " * theta + 90 "
        elif "Ventilation" in label:
            prop = "Air"
        elif "Hole" in label:
            prop = "Air"
        # Set the surface property
        femm.mi_setblockprop(
            prop,
            mesh_dict["automesh"],
            mesh_dict["meshsize"],
            Clabel,
            mag,
            mesh_dict["group"],
            Ntcoil,
        )
        femm.mi_clearselected()
Example #20
0
femm.mi_drawrectangle(6, 0, 15, 5)  # draw a rectangle for the ring magnet;

# boundaries conditions
femm.mi_makeABC()  # simulate an open boundary condition

# materials properties
femm.mi_addblocklabel(1, 1)  # air block (airbox)
femm.mi_addblocklabel(10, 3)  # ring block (neodymium)

femm.mi_getmaterial(
    'Air')  # fetches the material called air from the materials library
femm.mi_getmaterial('N48')

femm.mi_selectlabel(10, 3)  # assign the material to the block
femm.mi_setblockprop(
    'N48', 0, 1, '<None>', 90, 0, 0
)  # setblockprop(’blockname’, automesh, meshsize, ’incircuit’, magdir, group, turns)
femm.mi_clearselected()

femm.mi_selectlabel(1, 1)
femm.mi_setblockprop('Air', 0, 1, '<None>', 0, 0, 0)
femm.mi_clearselected()

femm.mi_zoomnatural()  # to check geometry while debuging
femm.mi_saveas('ring.fem')

# meshing
# automaticaly done by the analysis function

# analysis
femm.mi_analyze()
Example #21
0
def add_block_labels(tg, etiquettes_dict):
    '''Add block labels to pcbs, air, isolation disc, isolation gel/liquid.'''
    # Add block labels
    # ei seteditmode(editmode)
    # From manual: Sets the current editmode to:
    # – "nodes" - nodes
    # – "segments" - line segments
    # – "arcsegments" - arc segments
    # – "blocks" - block labels
    # – "group" - selected group
    femm.mi_seteditmode('blocks')

    # ei addblocklabel(x,y)
    # From manual: Add a new block label at (x,y)

    # labels for the PCBs
    coords = [2, tg.height_dielectric + tg.height_pcb_core / 2.]
    femm.mi_addblocklabel(*coords)
    etiquettes_dict['pcb_prim'] = coords

    coords = [2, -tg.height_pcb_core / 2.]
    femm.mi_addblocklabel(*coords)
    etiquettes_dict['pcb_sec'] = coords

    # label for the surrounding air
    coords = [2, tg.height_dielectric * 2 + tg.height_gel]
    femm.mi_addblocklabel(*coords)
    etiquettes_dict['air'] = coords

    # label for the dilectric gel or liquid surrounding the transformer
    coords = [tg.radius_pcb + 2, tg.height_dielectric + tg.height_gel / 2.]
    femm.mi_addblocklabel(*coords)
    etiquettes_dict['gel'] = coords

    # label for the isolation disc
    coords = [2, tg.height_dielectric / 2.]
    femm.mi_addblocklabel(*coords)
    etiquettes_dict['isolant'] = coords

    # Set material type for all blocks
    # mi_setblockprop("blockname", automesh, meshsize, "incircuit",
    # magdirection, group, turns)
    # From manual: Set the selected block labels to have the properties:
    # – Block property "blockname".
    # – automesh: 0 = mesher defers to mesh size constraint defined in
    # meshsize, 1 = mesher automatically chooses the mesh density.
    # – meshsize: size constraint on the mesh in the block marked by this label
    # – Block is a member of the circuit named "incircuit"
    # – The magnetization is directed along an angle in measured in degrees
    # denoted by the parameter magdirection. Alternatively, magdirection can be
    # a string containing a formula that prescribes the magnetization direction
    # as a function of element position. In this formula theta and R denotes
    # the angle in degrees of a line connecting the center each element with
    # the origin and the length of this line, respectively; x and y denote the
    # x- and y-position of the center of the each element. For axisymmetric
    # problems, r and z should be used in place of x and y.
    # – A member of group number group
    # – The number of turns associated with this label is denoted by turns.

    femm.mi_selectlabel(*etiquettes_dict['pcb_prim'])
    femm.mi_selectlabel(*etiquettes_dict['pcb_sec'])
    femm.mi_setblockprop('fr4', 1, 0, '<None>', 0, 1, 0)
    femm.mi_clearselected()

    femm.mi_selectlabel(*etiquettes_dict['air'])
    femm.mi_setblockprop('air', 1, 0, '<None>', 0, 1, 0)
    femm.mi_clearselected()

    femm.mi_selectlabel(*etiquettes_dict['gel'])
    femm.mi_setblockprop('silgel', 1, 0, 'None')
    femm.mi_clearselected()

    femm.mi_selectlabel(*etiquettes_dict['isolant'])
    femm.mi_setblockprop(tg.material_dielectric, 1, 0, 'None')
    femm.mi_clearselected()
Example #22
0
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.
femm.mi_saveas('coil.fem')

# Now,analyze the problem and load the solution when the analysis is finished
femm.mi_analyze()
femm.mi_loadsolution()