Esempio n. 1
0
def addLineZZ(n1, n2, group=-1):
    if group == -1:
        group = femmgroupmode
    femm.mi_addsegment(n1.real, n1.imag, n2.real, n2.imag)
    # select middle of arc for adding group
    n = (n1.real + n2.real) / 2 + ((n1.imag + n2.imag) / 2) * 1j
    femm.mi_selectsegment(n.real, n.imag)
    femm.mi_setgroup(group)
    femm.mi_clearselected()
Esempio n. 2
0
def addLine(r1, phi1, r2, phi2, group=-1):
    if group == -1:
        group = femmgroupmode
    n1 = cmath.rect(r1, rad(phi1))
    n2 = cmath.rect(r2, rad(phi2))
    femm.mi_addsegment(n1.real, n1.imag, n2.real, n2.imag)
    # select middle of arc for adding group
    # todo: better guess at point on line (unpredictable if phi1 != phi2)
    n = cmath.rect((r1 + r2) / 2., rad((phi1 + phi2) / 2.))
    femm.mi_selectsegment(n.real, n.imag)
    femm.mi_setgroup(group)
    femm.mi_clearselected()
    def conditions_limites(self):
        """Méthode permettant d'attribuer les conditions aux limites"""

        femm.mi_addboundprop('lim', 0, 0, 0, 0, 0, 0, 0, 0, 0)
        femm.mi_selectsegment(0, self.hauteur / 2)
        femm.mi_selectsegment(0, -self.hauteur / 2)
        femm.mi_selectsegment(self.largeur / 2, 0)
        femm.mi_selectsegment(-self.largeur / 2, 0)
        femm.mi_setsegmentprop('lim', 0, 1, 0, 0)
        femm.mi_clearselected()
Esempio n. 4
0
    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.")
Esempio n. 5
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.")
Esempio n. 6
0
def drawroundedcorner_box(femm, group, width, length, x_center, y_center,
                          corner_radius, one_sided):
    x1 = x_center - width / 2
    y1 = y_center - length / 2
    x2 = x1 + width
    y2 = y1 + length

    # mc = .02 * inches

    mc = corner_radius
    # first create nodes at the 4 corners
    # because they will be joined by an arc segment

    c1_x = x1
    c1_y = y1

    c2_x = x2
    c2_y = y1

    c3_x = x2
    c3_y = y2

    c4_x = x1
    c4_y = y2

    # now make blunted edge magnet based on it
    n1x = c1_x
    n1y = c1_y + mc

    n2x = c1_x + mc
    n2y = c1_y

    n3x = c2_x - mc
    n3y = c2_y

    n4x = c2_x
    n4y = c2_y + mc

    n5x = c3_x
    n5y = c3_y - mc

    n6x = c3_x - mc
    n6y = c3_y

    n7x = c4_x + mc
    n7y = c4_y

    n8x = c4_x
    n8y = c4_y - mc

    # If drawing all 4 corners
    if (one_sided == 0):
        femm.mi_addnode(n1x, n1y)
        femm.mi_addnode(n2x, n2y)
        femm.mi_addnode(n3x, n3y)
        femm.mi_addnode(n4x, n4y)
        femm.mi_addnode(n5x, n5y)
        femm.mi_addnode(n6x, n6y)
        femm.mi_addnode(n7x, n7y)
        femm.mi_addnode(n8x, n8y)

        femm.mi_addarc(n1x, n1y, n2x, n2y, 90, 3)
        femm.mi_addsegment(n2x, n2y, n3x, n3y)

        femm.mi_addarc(n3x, n3y, n4x, n4y, 90, 3)
        femm.mi_addsegment(n4x, n4y, n5x, n5y)

        femm.mi_addarc(n5x, n5y, n6x, n6y, 90, 3)
        femm.mi_addsegment(n6x, n6y, n7x, n7y)
        femm.mi_addarc(n7x, n7y, n8x, n8y, 90, 3)
        femm.mi_addsegment(n8x, n8y, n1x, n1y)

        femm.mi_clearselected()
        # femm.mi_drawrectangle(x1, mag_y1, mag_x2, mag_y2)
        # femm.mi_selectrectangle(x1, mag_y1, mag_x2, mag_y2,0)

        femm.mi_selectsegment(c1_x, c1_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c1_x + width / 4, c1_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c2_x, c2_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c3_x, c3_y + length / 2)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c3_x, c3_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c3_x - width / 4, c3_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c4_x, c4_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c4_x, c4_y - length / 2)
        femm.mi_setgroup(group)

        #femm.mi_clearselected()

    # if drawing only rounded corners on far side
    # because location is on axis.
    if (one_sided == 1):

        femm.mi_addnode(c1_x, c1_y)
        femm.mi_addnode(n3x, n3y)
        femm.mi_addnode(n4x, n4y)
        femm.mi_addnode(n5x, n5y)
        femm.mi_addnode(n6x, n6y)
        femm.mi_addnode(c4_x, c4_y)

        femm.mi_addsegment(c4_x, c4_y, c1_x, c1_y)

        femm.mi_addsegment(c1_x, c1_y, n3x, n3y)

        femm.mi_addarc(n3x, n3y, n4x, n4y, 90, 3)
        femm.mi_addsegment(n4x, n4y, n5x, n5y)

        femm.mi_addarc(n5x, n5y, n6x, n6y, 90, 3)
        femm.mi_addsegment(n6x, n6y, c4_x, c4_y)

        femm.mi_clearselected()
        femm.mi_selectsegment(c1_x, c1_y + length / 2)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c1_x + width / 2, c1_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c2_x, c2_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c2_x, c2_y + length / 2)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c3_x, c3_y)
        femm.mi_setgroup(group)
        femm.mi_selectsegment(c3_x - width / 2, c3_y)
        femm.mi_setgroup(group)
Esempio n. 7
0
def draw_FEMM(
    self,
    nodeprop=None,
    propname=None,
    elementsize=None,
    automesh=None,
    hide=False,
    group=None,
):
    """<   Draw the segment in FEMM and assign the property

    Parameters
    ----------
    nodeprop :
        Nodal property
         (Default value = None)
    propname :
        Boundary property ’propname’
         (Default value = None)
    elementsize :
        Local element size along segment no greater than elementsize
         (Default value = None)
    automesh :
        0 = mesher defers to the element constraint defined by
        elementsize, 1 = mesher automatically chooses mesh size along
        the selected segments
        (Default value = None)
    hide :
        0 = not hidden in post-processor, 1 == hidden in post processorc
         (Default value = False)
    group :
        group the segment belongs
         (Default value = None)

    Returns
    -------

    
    """

    # Get BC (if any)
    if self.label in boundary_prop:
        propname = boundary_prop[self.label]

    # Add the nodes
    X1, Y1 = self.begin.real, self.begin.imag
    X2, Y2 = self.end.real, self.end.imag
    femm.mi_addnode(X1, Y1)
    femm.mi_selectnode(X1, Y1)
    femm.mi_setnodeprop(nodeprop, group)
    femm.mi_clearselected()
    femm.mi_addnode(X2, Y2)
    femm.mi_selectnode(X2, Y2)
    femm.mi_setnodeprop(nodeprop, group)
    femm.mi_clearselected()
    # add the segment
    femm.mi_addsegment(X1, Y1, X2, Y2)
    # Set property
    femm.mi_selectsegment((X1 + X2) / 2, (Y1 + Y2) / 2)
    femm.mi_setsegmentprop(propname, elementsize, automesh, hide, group)
    femm.mi_clearselected()
Esempio n. 8
0
def draw_FEMM(
    output,
    is_mmfr,
    is_mmfs,
    sym,
    is_antiper,
    type_calc_leakage,
    is_remove_vent=False,
    is_remove_slotS=False,
    is_remove_slotR=False,
    type_BH_stator=0,
    type_BH_rotor=0,
    kgeo_fineness=1,
    kmesh_fineness=1,
    user_FEMM_dict={},
    path_save="FEMM_model.fem",
    is_sliding_band=True,
    transform_list=[],
    rotor_dxf=None,
    stator_dxf=None,
):
    """Draws and assigns the property of the machine in FEMM
    
    Parameters
    ----------
    output : Output
        Output object
    is_mmfr : bool
        1 to compute the rotor magnetomotive force / rotor
        magnetic field
    is_mmfs : bool
        1 to compute the stator magnetomotive force/stator
        magnetic field
    type_calc_leakage : int
        0 no leakage calculation
        1 calculation using single slot
    is_remove_vent : bool
        True to remove the ventilation ducts in FEMM (Default value = False)
    is_remove_slotS : bool
        True to solve without slot effect on the Stator (Default value = False)
    is_remove_slotR : bool
        True to solve without slot effect on the Rotor (Default value = False)
    type_BH_stator: int
        2 Infinite permeability, 1 to use linear B(H) curve according to mur_lin, 0 to use the B(H) curve
    type_BH_rotor: bool
        2 Infinite permeability, 1 to use linear B(H) curve according to mur_lin, 0 to use the B(H) curve
    kgeo_fineness : float
        global coefficient to adjust geometry fineness
        in FEMM (1: default ; > 1: finner ; < 1: less fine)
    kmesh_fineness : float
        global coefficient to adjust mesh fineness
        in FEMM (1: default ; > 1: finner ; < 1: less fine)
    sym : int
        the symmetry applied on the stator and the rotor (take into account antiperiodicity)
    is_antiper: bool
        To apply antiperiodicity boundary conditions
    rotor_dxf : DXFImport
        To use a dxf version of the rotor instead of build_geometry
    stator_dxf : DXFImport
        To use a dxf version of the stator instead of build_geometry

    Returns
    -------

    FEMM_dict : dict
        Dictionnary containing the main parameters of FEMM (including circuits and materials)
    """

    # Initialization from output for readibility
    BHs = output.geo.stator.BH_curve  # Stator B(H) curve
    BHr = output.geo.rotor.BH_curve  # Rotor B(H) curve
    Is = output.elec.Is  # Stator currents waveforms
    Ir = output.elec.Ir  # Rotor currents waveforms
    machine = output.simu.machine

    # Computing parameter (element size, arcspan...) needed to define the simulation
    FEMM_dict = comp_FEMM_dict(machine, kgeo_fineness, kmesh_fineness,
                               type_calc_leakage)
    FEMM_dict.update(user_FEMM_dict)  # Overwrite some values if needed

    # The package must be initialized with the openfemm command.
    try:
        femm.openfemm()
    except Exception as e:
        raise FEMMError(
            "ERROR: Unable to open FEMM, please check that FEMM is correctly installed\n"
            + str(e))

    # We need to create a new Magnetostatics document to work on.
    femm.newdocument(0)

    # Minimize the main window for faster geometry creation.
    femm.main_minimize()

    # defining the problem
    femm.mi_probdef(0, "meters", FEMM_dict["pbtype"], FEMM_dict["precision"])

    # Modifiy the machine to match the conditions
    machine = type(machine)(init_dict=machine.as_dict())
    if is_remove_slotR:  # Remove all slots on the rotor
        lam_dict = machine.rotor.as_dict()
        machine.rotor = Lamination(init_dict=lam_dict)
    if is_remove_slotS:  # Remove all slots on the stator
        lam_dict = machine.stator.as_dict()
        machine.stator = Lamination(init_dict=lam_dict)
    if is_remove_vent:  # Remove all ventilations
        machine.rotor.axial_vent = list()
        machine.stator.axial_vent = list()

    # Building geometry of the (modified) stator and the rotor
    surf_list = list()
    lam_list = machine.get_lam_list()
    lam_int = lam_list[0]
    lam_ext = lam_list[1]

    # Adding no_mesh for shaft if needed
    if lam_int.Rint > 0 and sym == 1:
        surf_list.append(
            Circle(point_ref=0, radius=lam_int.Rint, label="No_mesh"))

    # adding the Airgap surface
    if is_sliding_band:
        surf_list.extend(
            get_sliding_band(sym=sym, lam_int=lam_int, lam_ext=lam_ext))
    else:
        surf_list.extend(get_airgap_surface(lam_int=lam_int, lam_ext=lam_ext))

    # adding Both laminations surfaces (or import from DXF)
    if rotor_dxf is not None:
        femm.mi_readdxf(rotor_dxf.file_path)
        surf_list.extend(rotor_dxf.get_surfaces())
    else:
        surf_list.extend(machine.rotor.build_geometry(sym=sym))
    if stator_dxf is not None:
        femm.mi_readdxf(stator_dxf.file_path)
        surf_list.extend(stator_dxf.get_surfaces())
    else:
        surf_list.extend(machine.stator.build_geometry(sym=sym))

    # Applying user defined modifications
    for transfrom in transform_list:
        for surf in surf_list:
            if transfrom["label"] in surf.label and transfrom[
                    "type"] == "rotate":
                surf.rotate(transfrom["value"])
            elif transfrom["label"] in surf.label and transfrom[
                    "type"] == "translate":
                surf.translate(transfrom["value"])

    # Creation of all the materials and circuit in FEMM
    prop_dict, materials, circuits = create_FEMM_materials(
        machine,
        surf_list,
        Is,
        Ir,
        BHs,
        BHr,
        is_mmfs,
        is_mmfr,
        type_BH_stator,
        type_BH_rotor,
        is_eddies,
        j_t0=0,
    )
    create_FEMM_boundary_conditions(sym=sym, is_antiper=is_antiper)

    # Draw and assign all the surfaces of the machine
    for surf in surf_list:
        label = surf.label
        # Get the correct element size and group according to the label
        surf.draw_FEMM(
            nodeprop="None",
            maxseg=FEMM_dict["arcspan"],  # max span of arc element in degrees
            propname="None",
            FEMM_dict=FEMM_dict,
            hide=False,
        )
        assign_FEMM_surface(surf, prop_dict[label], FEMM_dict, machine.rotor,
                            machine.stator)

    # Apply BC for DXF import
    if rotor_dxf is not None:
        for BC in rotor_dxf.BC_list:
            if BC[1] is True:  # Select Arc
                femm.mi_selectarcsegment(BC[0].real, BC[0].imag)
                femm.mi_setarcsegmentprop(FEMM_dict["arcspan"], BC[2], False,
                                          None)
            else:  # Select Line
                femm.mi_selectsegment(BC[0].real, BC[0].imag)
                femm.mi_setsegmentprop(BC[2], None, None, False, None)
            femm.mi_clearselected()

    femm.mi_zoomnatural()  # Zoom out
    femm.mi_probdef(
        FEMM_dict["freqpb"],
        "meters",
        FEMM_dict["pbtype"],
        FEMM_dict["precision"],
        FEMM_dict["Lfemm"],
        FEMM_dict["minangle"],
        FEMM_dict["acsolver"],
    )
    femm.smartmesh(FEMM_dict["smart_mesh"])
    femm.mi_saveas(path_save)  # Save
    # femm.mi_close()

    FEMM_dict["materials"] = materials
    FEMM_dict["circuits"] = circuits

    return FEMM_dict