예제 #1
0
    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.")
예제 #2
0
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)
예제 #3
0
            (halfMiddleBarHeight) * up_down(side),
        )

        x_magnets_label = -halfMovilWidth + leftMagnetSpace + gapSimulation + (
            iman * (magnetWidth + innerMagnetSpace)) + (magnetWidth / 2)
        y_magnets_label = (halfMiddleBarHeight +
                           (magnetHeight / 2)) * up_down(side)

        femm.mi_addblocklabel(x_magnets_label, y_magnets_label)

        femm.mi_selectlabel(x_magnets_label, y_magnets_label)
        femm.mi_setblockprop('Magnet', 0, 1, '<None>', 90 * up_down(iman % 2),
                             0, 0)
        femm.mi_clearselected()

femm.mi_makeABC()

### Añadiendo Materiales
#### Fijos

# Arms
x_label_arms = 0
y_label_arms = halfHeight - 10
femm.mi_addblocklabel(x_label_arms, y_label_arms)

femm.mi_selectlabel(x_label_arms, y_label_arms)
femm.mi_setblockprop('Hiperco-50', 0, 1, '<None>', 0, 0, 0)
femm.mi_clearselected()

femm.mi_addblocklabel(x_label_arms, -y_label_arms)
예제 #4
0
                      magnet_corner_radius, one_sided_magnet_flag)

femm.mi_addblocklabel(mag_label_x, mag_label_y)
femm.mi_selectlabel(mag_label_x, mag_label_y)
femm.mi_setblockprop('NdFeB 52 MGOe', 0, 1, '<none>', 90, 0, 0)
femm.mi_setgroup(3)  # seems i needed this as well.. # MAJOR ADDITION
femm.mi_selectlabel(mag_label_x, mag_label_y)
femm.mi_setgroup(3)
femm.mi_clearselected()

# DEFINE ABSORBING BOUNDARY CONDITIONS
# THIS IS LIKELY A SOURCE OF ERROR IF YOU CHANGE THE COIL AND MAGNET SIZES
sim_diameter = mag_y_loc_o + Lm / 2 + Lc / 2 + Lc
y_center_of_ABC = sim_diameter / 4 - Lm / 2
x_center_of_ABC = 0
femm.mi_makeABC(7, sim_diameter / 2 * 1.2, x_center_of_ABC, y_center_of_ABC, 0)

##  RUNN 1
z_start = mag_y_loc_o
z_end = 0
num_points = 25  # resolution of points inbetween z_start and z_end
dz = (z_end - z_start) / (num_points - 1)
z = np.linspace(z_start, z_end, num_points)
fz = []

# START OF MOTION
counter = 0  # Initialize a counter because I was too lazy to get the index in the for loop
for z_loc in z:
    mag_y_loc = z_loc
    # Only start after the initial position has been used.
    if (counter > 0):
예제 #5
0
import matplotlib.pyplot as plt

femm.openfemm()  # create an instance of femm without GUI

# problem definition
femm.newdocument(0)  # create new magnetic problem preprocessor document

femm.mi_probdef(
    0, 'millimeters', 'axi', 1.e-8, 0, 30
)  # Define the problem type. Magnetostatic; Units of mm; Axisymmetric; Precision of 10^(-8) for the linear solver; a placeholder of 0 for the depth dimension, and an angle constraint of 30 degrees

# geometry definition
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()
예제 #6
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()
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
    femm.mi_addblocklabel(((inner_edge + outer_edge) / 2), 0)
    femm.mi_selectlabel(((inner_edge + outer_edge) / 2), 0)
    femm.mi_setblockprop('36awgcopper', automesh, meshsize, 'spiral', 0, 0, 1)
    femm.mi_clearselected()
    r = outer_edge

#define the air
femm.mi_addblocklabel((wall_radius / 2), (wall_distance / 2))
femm.mi_selectlabel((wall_radius / 2), (wall_distance / 2))
femm.mi_setblockprop('air', automesh, meshsize, 0)
femm.mi_clearselected()

femm.mi_makeABC(1, ((wall_distance + outer_radius + wall_radius) * 2), 0, 0, 0)

femm.mi_zoomnatural()

# Save the geometry to disk so we can analyze it
femm.mi_saveas('spiral.fem')
예제 #8
0
def abc():
    femm.mi_makeABC()