Ejemplo n.º 1
0
def add_pcbs(tg):
    '''Add primary and secondary side pcbs.'''
    # coordinates of the PCB on the primary side
    if tg.layers_primary == 1 or tg.layers_primary == 2:
        coords_pcb_prim = coords_of_rectangle(
            0, tg.height_dielectric + tg.height_copper + tg.height_gap,
            tg.radius_pcb, tg.height_pcb_core)
    elif tg.layers_primary == 4:
        coords_pcb_prim = coords_of_rectangle(
            0, tg.height_dielectric + tg.height_copper + tg.height_gap,
            tg.radius_pcb, tg.height_pcb_core + 2 * tg.height_pcb_prepreg +
            2 * tg.height_copper)
    else:
        print('Unknown number of layers on primary side')
        femm.closefemm()
        return (0, 0)

    # coordinates of the PCB on the secondary side
    if tg.layers_secondary == 1 or tg.layers_secondary == 2:
        coords_pcb_sec = coords_of_rectangle(0,
                                             -tg.height_copper - tg.height_gap,
                                             tg.radius_pcb,
                                             -tg.height_pcb_core)
    elif tg.layers_secondary == 4:
        coords_pcb_sec = coords_of_rectangle(
            0, -tg.height_copper - tg.height_gap, tg.radius_pcb,
            -tg.height_pcb_core - 2 * tg.height_pcb_prepreg -
            2 * tg.height_copper)
    else:
        print('Unknown number of layers on secondary side')
        femm.closefemm()
        return (0, 0)
    femm.mi_drawrectangle(*coords_pcb_prim)
    femm.mi_drawrectangle(*coords_pcb_sec)
Ejemplo n.º 2
0
def add_pcbs(tg, label_dict):
    '''Add primary and secondary side pcbs.

    Args:
        tg (TransformerGeometry): contains all geometry information needed
        to build conductors in the problem.
        label_dict (dict): stores coordinates
    '''

    # coordinates of the PCB on the primary side
    if tg.layers_primary == 1 or tg.layers_primary == 2:
        coords_pcb_prim = coords_rectangle(
            0, tg.height_dielectric + tg.height_copper + tg.height_gap,
            tg.radius_pcb, tg.height_pcb_core)
    elif tg.layers_primary == 4:
        coords_pcb_prim = coords_rectangle(
            0, tg.height_dielectric + tg.height_copper + tg.height_gap,
            tg.radius_pcb, tg.height_pcb_core + 2 * tg.height_pcb_prepreg +
            2 * tg.height_copper)
    else:
        print('Unknown number of layers on primary side')
        femm.closefemm()
        return (0, 0)

    # coordinates of the PCB on the secondary side
    if tg.layers_secondary == 1 or tg.layers_secondary == 2:
        coords_pcb_sec = coords_rectangle(0, -tg.height_copper - tg.height_gap,
                                          tg.radius_pcb, -tg.height_pcb_core)
    elif tg.layers_secondary == 4:
        coords_pcb_sec = coords_rectangle(
            0, -tg.height_copper - tg.height_gap, tg.radius_pcb,
            -tg.height_pcb_core - 2 * tg.height_pcb_prepreg -
            2 * tg.height_copper)
    else:
        print('Unknown number of layers on secondary side')
        femm.closefemm()
        return (0)
    femm.ei_drawrectangle(*coords_pcb_prim)
    femm.ei_drawrectangle(*coords_pcb_sec)
    label_dict['PCB_prim'] = coords_pcb_prim
    label_dict['PCB_sec'] = coords_pcb_sec
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
femm.ei_zoomnatural()

# Save the geometry to disk so we can analyze it
femm.ei_saveas('strips.fee')

# Create a placeholder matrix which we will fill with capacitance values
c = []

for k in range(0, 4):
    femm.ei_modifyconductorprop('v0', 1, 1 if (k == 0) else 0)
    femm.ei_modifyconductorprop('v1', 1, 1 if (k == 1) else 0)
    femm.ei_modifyconductorprop('v2', 1, 1 if (k == 2) else 0)
    femm.ei_modifyconductorprop('v3', 1, 1 if (k == 3) else 0)
    femm.ei_analyze()
    femm.ei_loadsolution()
    c.append([
        femm.eo_getconductorproperties('v0')[1],
        femm.eo_getconductorproperties('v1')[1],
        femm.eo_getconductorproperties('v2')[1],
        femm.eo_getconductorproperties('v3')[1]
    ])

femm.closefemm()

print('The capacitance matrix (pF/m):')
for j in range(0, 4):
    for k in range(0, 4):
        c[j][k] *= 10**12
    print(c[j])
Ejemplo n.º 5
0
def calc_field_distribution(tg, voltage_high=1, view=None, **kwargs):
    ''' Setup of electro-static problem in femm to calculate capacitance
    between primary and secondary side of planar transformer. Additionally,
    electric field can be investigated

    Args:
        tg (:obj:'TransformerGeometry'): tg contains all geometry information
        needed to solve the problem.
        voltage_high (float): Voltage potential of the primary side.
        view (:obj:'View'): Save images of edges and guards.

    Returns:
        capacitance (float): calculated capacitance between primary and
        secondary side of planar transformer.
    '''

    etiquettes_dict = {}  # Dictionary to store coordinates of nodes

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

    # draw conductors on primary and secondary sides
    add_conductors(tg, etiquettes_dict)
    add_pcbs(tg, etiquettes_dict)
    add_isolation(tg)
    add_block_labels(tg, etiquettes_dict)

    round_conductor_edges(tg, etiquettes_dict, kwargs.get('segment_angle'))

    #    if tg.edge_type == 'Round':
    #        round_conductor_edges(tg, etiquettes_dict)
    #    elif tg.edge_type == 'Trapezoidal':
    #        trapezoidal_conductor_edges(tg, etiquettes_dict)
    if tg.tracks:
        modify_tracks(tg, etiquettes_dict, kwargs.get('segment_angle'))

    if tg.guard:
        add_guard(tg, tg.guard, etiquettes_dict)

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

    # Save geometry file
    femm.ei_saveas('field_calculations.fee')

    # 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.ei_analyze(1)

    # Post-processor
    femm.ei_loadsolution()

    # eo_showdensityplot(legend,gscale,type,upper D,lower D)
    # From manual: Shows the flux density plot with options:
    # legend Set to 0 to hide the plot legend or 1 to show the plot legend.
    # gscale Set to 0 for a colour density plot or 1 for a grey scale density
    # plot.
    # type Sets the type of density plot. A value of 0 plots voltage, 1 plots
    # the magnitude of D, and 2 plots the magnitude of E
    # upper D Sets the upper display limit for the density plot.
    # lower D Sets the lower display limit for the density plot.
    if 'plot_field_max' in kwargs:
        femm.eo_showdensityplot(1, 0, 2, kwargs['plot_field_max'] * 20 / 19, 0)

    # Save field lines along outer point of the PCB conductors. If the
    # conductors have trapezoidal shape, it is difficult to estimate where the
    # peak field will be. Hence, the contour lines are not saved.
#    if not edge_trapezoid:
#        save_field_contour(ep_cuivre, etiquettes_dict, guard=guard)
    if view:
        set_view(view, tg.guard, etiquettes_dict)

    # eo_getconductorproperties("conductor")
    # From manual: Properties are returned for the conductor property named
    # ”conductor”. Two values are returned: The voltage of the specified
    # conductor, and the charge carried on the specified conductor.

    # Calculate the capacitance
    circuit_properties = femm.eo_getconductorproperties('zero')
    charge = -circuit_properties[1]  # get charge on secondary side conductors
    capacitance = charge / voltage_high

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

    return capacitance
Ejemplo n.º 6
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()

# result data export
femm.mi_loadsolution()

# plot the flux density along z axis
zee = []
bee = []
for n in range(-0, 30):
    b = femm.mo_getb(0, n)
    zee.append(n)
    bee.append(b[1])

plt.plot(zee, bee)
plt.ylabel('Flux Density, Tesla')
plt.xlabel('Distance along the z-axis, mm')
plt.title('Plot of flux density along the axis')
plt.grid()
plt.show()

femm.closefemm()  # close the instance of femm
Ejemplo n.º 7
0
 def closeSimulation(self):
     femm.closefemm()
Ejemplo n.º 8
0
def closeFemm(filename='test.fem'):
    femm.mi_saveas(filename)
    femm.closefemm()
    def fermeture_simulation(self):
        """Fermeture de FEMM"""

        femm.closefemm()