Beispiel #1
0
def main():
    n_pontos = 40
    polos = 7
    deg_mec = np.linspace(0, 360, n_pontos)
    deg_ele = deg_mec / polos

    a_flux = np.zeros(n_pontos)
    b_flux = np.zeros(n_pontos)
    c_flux = np.zeros(n_pontos)
    print(a_flux)

    for i in range(n_pontos):
        femm.mi_modifyboundprop("Sliding", 11, deg_ele[i])
        femm.mi_analyse()
        femm.mi_loadsolution()

        a_flux[i] = femm.mo_getcircuitproperties("A")[2]
        b_flux[i] = femm.mo_getcircuitproperties("A")[2]
        c_flux[i] = femm.mo_getcircuitproperties("A")[2]

    flux_1n = np.zeros(n_pontos)
    for i in range(n_pontos):
        femm.mi_modifyboundprop("Sliding", 11, deg_ele[i])
        femm.mi_analyse()
        femm.mi_loadsolution()

        femm.mo_selectblock(1.5, 8.6)
        flux_1n[i] = femm.mo_blockintegral(1) / femm.mo_blockintegral(5)
        femm.mo_clearblock()

    ap = 10e-3 * (10.86 + 10.96) * 1e-3 * np.pi / 14
    bt = flux_1n / ap / 4
    def computeL0(self):
        """Compute L0

        Compute the bare inductance of the coil without projectile.
        """
        self.deleteProjectile()
        femm.mi_refreshview()
        femm.mi_analyze()
        femm.mi_loadsolution()
        # print(femm.mo_getcircuitproperties("Bobine"))
        self.L0 = femm.mo_getcircuitproperties("Bobine")[2] / self._i0
        self.resistance = femm.mo_getcircuitproperties("Bobine")[1] / self._i0
        femm.mo_close()
        self.drawProjectile()
Beispiel #3
0
def comp_FEMM_Phi_wind(qs,
                       Npcpp,
                       is_stator,
                       Lfemm,
                       L1,
                       sym,
                       is_rescale_flux=True):
    """Compute the total fluxlinkage of the winding phases

    Parameters
    ----------
    qs : int 
        number of phases
    Npcpp : int
        number of parallel circuits per phase (maximum 2p)
    is_stator : bool
        true if windings are stator windings
    Lfemm : float
        lenght of FEMM model
    L1 : float
        actual lenght for rescaling fluxlinkage 
    sym : int
        symmetry factor (ie. 1 = full machine, 2 = half machine ...)
    is_rescale_flux : bool
        True if rescaling should be applied

    Returns
    -------
    Phi_wind : float
        fluxlinkage of the winding phases [Vs]

    """
    Phi_wind = zeros((1, qs))

    if is_stator:
        label = "Circs"
    else:
        label = "Circr"

    # For each phase/circuit
    for q in range(qs):
        PropCirc = mo_getcircuitproperties(label + str(q))
        # rescaling to account for end winding flux
        if is_rescale_flux:
            Kphi = L1 / Lfemm
        else:
            Kphi = 1
        # flux linkage of phase q in Wb=Vs=HA
        Phi_wind[0, q] = sym * PropCirc[2] * Kphi / Npcpp
    return Phi_wind
Beispiel #4
0
def calc_inductance(tg, currents, inductances=(None, None), **kwargs):
    ''' Setup of magneto-static problem in femm to calculate inductance and
    resistance of planar transformer.

    Args:
        tg (:obj:'TransformerGeometry'): tg contains all geometry information
        of the transformer.
        currents (list of float): currents in the primary and secondary side
        circuits on the form [I_prim, I_sec].
        inductances (list of float): self-inductances of the primary and
        secondary side circuits on the form [L_prim, L_sec]. Used to calculate
        mutual inductance.

    Returns:
        (inductance, resistance): calculated self or mutual inductance and
        equivalent series resistance of either primary or secondary circuit.
    '''

    etiquettes_dict = {}  # Dictionary to store coordinates of nodes

    # initialitiation of the magneto-static problem
    boundary_radius = 2 * tg.radius_dielectric
    initial_setup(boundary_radius, currents, **kwargs)

    # draw geometry and add block labels
    add_conductors(tg, etiquettes_dict)
    add_pcbs(tg)
    add_isolation(tg)
    add_block_labels(tg, etiquettes_dict)

    # mi zoomnatural()
    # From manual: zooms to a “natural” view with sensible extents.
    femm.mi_zoomnatural()

    # Saving geometry file
    femm.mi_saveas('inductance_transformer.fem')

    # Meshing and analysis
    # From manual: Note that it is not necessary to run mesh before performing
    # an analysis, as mi_analyze() will make sure the mesh is up to date before
    # running an analysis.

    # mi analyze(flag)
    # From manual: runs fkern to solve the problem. The flag parameter controls
    # whether the fkern window is visible or minimized. For a visible window,
    # either specify no value for flag or specify 0. For a minimized window,
    # flag should be set to 1.
    femm.mi_analyze(1)

    # Post-processing
    femm.mi_loadsolution()

    # mo_seteditmode(mode)
    # From manual: Sets themode of the postprocessor to point, contour, or area
    # mode. Valid entries for mode are "point", "contour", and "area".
    femm.mo_seteditmode('area')

    # mo_blockintegral(type)
    # From manual: Calculate a block integral for the selected blocks
    # Type Definition
    # 0 A · J
    # 1 A
    # 2 Magnetic field energy
    # 3 Hysteresis and/or lamination losses
    # 4 Resistive losses
    # 5 Block cross-section area
    # 6 Total losses
    # 7 Total current
    # 8 Integral of Bx (or Br) over block
    # 9 Integral of By (or rBz) over block
    # 10 Block volume
    # ...

    # mo_getcircuitproperties("circuit")
    # From manual: Used primarily to obtain impedance information associated
    # with circuit properties. Properties are returned for the circuit property
    # named "circuit". Three values are returned by the function. In order,
    # these results are:
    # – current Current carried by the circuit
    # – volts Voltage drop across the circuit
    # – flux_re Circuit’s flux linkage

    # mo_groupselectblock(n)
    # From manual: Selects all the blocks that are labeled by block labels
    # that are members of group n. If no number is specified (i.e.
    # mo_groupselectblock() ), all blocks are selected.

    # Calculate the inductance of the circuit with non-zero current. If both
    # currents are given, we calculate the mutual inductance.
    L1, L2 = inductances
    if (currents[0] > 0) and (currents[1] == 0):
        circ = femm.mo_getcircuitproperties('phase_prim')
        resistance = circ[1].real
        inductance = abs(circ[2] / circ[0])
    elif (currents[0] == 0) and (currents[1] > 0):
        circ = femm.mo_getcircuitproperties('phase_sec')
        resistance = circ[1].real
        inductance = abs(circ[2] / circ[0])
    else:
        femm.mo_groupselectblock()
        # axisymmetric problem, integral is multiplied by 2
        Wm = femm.mo_blockintegral(2) * 2
        inductance = ((Wm - 0.5 *
                       (L1 * currents[1]**2 + L2 * currents[0]**2)) /
                      (currents[0] * currents[1]))
        resistance = 0
        femm.mo_clearblock()

    if kwargs.get('close') is True:
        femm.closefemm()

    return (inductance, resistance)
Beispiel #5
0

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

# If we were interested in the flux density at specific positions, 
# we could inquire at specific points directly:
b0=femm.mo_getb(0,0);
print('Flux density at the center of the bar is %g T' % b0[1]);
b1=femm.mo_getb(0,50);
print('Flux density at r=0,z=50 is %g T' % b1[1]);

# The program will report the terminal properties of the circuit:
# current, voltage, and flux linkage 
vals = femm.mo_getcircuitproperties('icoil');

# [i, v, \[Phi]] = MOGetCircuitProperties["icoil"]

# If we were interested in inductance, it could be obtained by
# dividing flux linkage by current
L = 1000*vals[2]/vals[0];
print('The self-inductance of the coil is %g mH' % L);

# Or we could, for example, plot the results along a line using 
zee=[]
bee=[]
for n in range(-100,101):
	b=femm.mo_getb(0,n);
	zee.append(n)
	bee.append(b[1]);
    def computeMuImpact(self,
                        mus=[5, 10, 50, 100, 500, 1000, 5000],
                        error=0.1):
        """Compute the impact of Mu

        The model is NOT LINEAR in mu. It is hard to guess what would be the effect
        of an increased suceptibility and it may highly modify the response of the coil.
        However, for some configuration the error is low (typically a long coil and a small projectile).

        This function provides some help to know if we can consider the model linear in Mu.
        Simply provide a range of possible susceptibilities for your projectile, and an
        acceptable relative error.

        We do not check the whole linearity, but simply in two points selected empirically.
        Therefore some care should be taken regarding the output of this helper method.

        Keyword Arguments:
            mus {list} -- [description] (default: {[5, 10, 50, 100, 500, 1000, 5000]})
            error {number} -- [description] (default: {0.1})
        """
        _mu = self.mu
        res = []
        test_res = []
        print("Coil " + self._seed + " mus")
        for mu in mus:
            self.mu = mu
            self.deleteProjectile()
            self.drawProjectile()
            femm.mi_clearselected()
            femm.mi_selectgroup(1)

            femm.mi_analyze()
            femm.mi_loadsolution()
            femm.mo_groupselectblock(1)
            res.append(femm.mo_getcircuitproperties("Bobine")[2] / self._i0)

            femm.mi_movetranslate2(0, self.Lb / 4, 4)
            femm.mi_analyze()
            femm.mi_loadsolution()
            femm.mo_groupselectblock(1)
            test_res.append(
                femm.mo_getcircuitproperties("Bobine")[2] / self._i0)
        self.mu = _mu
        success = True
        errors = []
        for i in range(0, len(test_res)):
            errors.append(
                numpy.abs((res[i] / res[0]) / (test_res[i] / test_res[0]) - 1))
            if errors[-1] > error:
                success = False
                # break
        if success:
            return {
                'valid': True,
                'mus': mus,
                'mu_Lz_0': res,
                'mu_Lz_1': test_res,
                'errors': errors
            }
        else:
            return {
                'valid': False,
                'mus': mus,
                'mu_Lz_0': res,
                'mu_Lz_1': test_res,
                'errors': errors
            }
Beispiel #7
0
for coil_origin in coil_origins:
    coil = Rectangle(coil_origin.x, coil_origin.y, Params.D4, Params.D3)
    coil.assign_material(Params.CoilMaterial, Params.Turns, 'Circuit')

# 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('feladat2.fem')

move_vectors = [Point(0, 0)]  # do it once without moving
for previous, current in zip(Params.core_gap, Params.core_gap[1:]):
    move_vectors.append(Point(0, previous - current))

forces = {}
for core_gap, move_vector in zip(Params.core_gap, move_vectors):
    bottom_part.move(move_vector.x, move_vector.y)
    femm.mi_analyze()
    femm.mi_loadsolution()
    bottom_part.select_block_for_anal()
    forces[core_gap] = femm.mo_blockintegral(19)  # 19 means force

    (current, voltage, flux_linkage) = femm.mo_getcircuitproperties('Circuit')
    inductance = flux_linkage / current

    print(
        f'In case of {core_gap:.1f} cm gap, force is {forces[core_gap]:.2f} N; inductance is {inductance*1000:.2f} mH'
    )

femm.closefemm()
Beispiel #8
0
            # Store vector potential at the element centroid for elements that are in PMs
            A[index, m] = femm.mo_geta(float(np.real(z[m])),
                                       float(np.imag(z[m])))
        elif g[m] == GroupSummary['stator_iron_core'] \
            or g[m] == GroupSummary['rotor_iron_core'] \
            or g[m] == GroupSummary['coils']: # Element is on the stator or rotor iron or coils
            # Store flux density at the element centroid for these elements
            b_temp = femm.mo_getb(float(np.real(z[m])), float(np.imag(z[m])))
            b[index, m] = b_temp[0] + 1j * b_temp[1]

    # Torque, force, fluxes
    torque = femm.mo_gapintegral('WholeModelSlidingBand', 0)
    forces = femm.mo_gapintegral('WholeModelSlidingBand', 1)
    energy = femm.mo_gapintegral('WholeModelSlidingBand', 2)

    cP_Uac = femm.mo_getcircuitproperties('U-GrpAC')
    cP_Vac = femm.mo_getcircuitproperties('V-GrpAC')
    cP_Wac = femm.mo_getcircuitproperties('W-GrpAC')
    cP_Ubd = femm.mo_getcircuitproperties('U-GrpBD')
    cP_Vbd = femm.mo_getcircuitproperties('V-GrpBD')
    cP_Wbd = femm.mo_getcircuitproperties('W-GrpBD')
    M[index, 0] = torque
    M[index, 1] = forces[0]
    M[index, 2] = forces[1]
    M[index, 3] = energy
    M[index, 4] = cP_Uac[0]
    M[index, 5] = cP_Vac[0]
    M[index, 6] = cP_Wac[0]
    M[index, 7] = cP_Ubd[0]
    M[index, 8] = cP_Vbd[0]
    M[index, 9] = cP_Wbd[0]