def deleteCoil(self):
        """Delete the coil

        Provided for debugging, should not be used.
        """
        femm.mi_clearselected()
        femm.mi_selectgroup(2)
        femm.mi_deleteselected()
        femm.mi_deletematerial("Cuivre")
    def deleteProjectile(self):
        """Delete the projectile

        Deletes the projectile (drawn) but doesn't erase its properties.
        """
        femm.mi_clearselected()
        femm.mi_selectgroup(1)
        femm.mi_deleteselected()
        femm.mi_deletematerial("Projectile")
        if self.espace is not None:
            femm.mi_addsegment(0, -self.espace, 0, self.espace)
    def computedLz(self, ite=0, rType="linear"):
        """Compute dLz

        Compute the variation of inductance while the
        projectile moves on the axis. If ite is zero,
        some guess is made about the number of iterations required
        for decent approximation.
        By default the projectile is moved linearly, but it
        is possible to set the movement type to tchebychev in order
        to minimize the Runge phenomenom. However not all the code
        is compatible with it.

        Rather than computing the variation of inductance, we compute
        the force on the projectile and correct it (explanations are available
        somewhere on this git :) ).

        Keyword Arguments:
            ite {number} -- number of steps (default: {0})
            rType {str} -- type of movement, linear or tchebychev (default: {"linear"})
        """
        self.deleteProjectile()
        self.drawProjectile()
        (pas, pos, ite) = self._compute_range(ite, rType)
        force = numpy.zeros(ite)
        femm.mi_selectgroup(1)
        femm.mi_movetranslate2(0, pos[0], 4)
        for i in tqdm(range(ite // 2), disable=self.bHide):
            femm.mi_analyze()
            femm.mi_loadsolution()
            femm.mo_groupselectblock(1)
            force[i] = femm.mo_blockintegral(19)
            force[ite - i - 1] = -force[i]
            femm.mi_selectgroup(1)
            femm.mi_movetranslate2(0, pas[i], 4)
        self.dLz = 2 * force / self._i0**2
        self.dLz_z = pos * 10**-3
        self.dLz_nyquist = 1 / (2 * numpy.mean(pas) * 10**-3)
Example #4
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):
        femm.mi_movetranslate(0, dz)

    femm.mi_analyze(0)
    femm.mi_loadsolution()
    femm.mi_selectgroup(3)
    femm.mo_selectblock(0, mag_y_loc)
    fz.append(femm.mo_blockintegral(21) * 2)

    counter = counter + 1
# END OF MOTION

# POST-PROCESSING
femm.mi_saveas("final.fem")  # Save the final simulation step
max_loc = fz.index(max(fz))  # Find the location of maximum force

plt.figure(1)
plt.plot(z - z[max_loc], fz)
plt.show()
plt.xlabel('z (in)')
plt.ylabel('F [N]')
    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
            }
Example #6
0
import femm
import matplotlib.pyplot as plt

femm.openfemm()
femm.opendocument("coilgun.fem")
femm.mi_saveas("temp.fem")
femm.mi_seteditmode("group")
z = []
f = []
for n in range(0, 16):
    femm.mi_analyze()
    femm.mi_loadsolution()
    femm.mo_groupselectblock(1)
    fz = femm.mo_blockintegral(19)
    z.append(n * 0.1)
    f.append(fz)
    femm.mi_selectgroup(1)
    femm.mi_movetranslate(0, -0.1)
femm.closefemm()
plt.plot(z, f)
plt.ylabel('Force, N')
plt.xlabel('Offset, in')
plt.show()
Example #7
0
def clearGroup(group):
    if group != 0:
        clearGroup(0)
    femm.mi_selectgroup(group)
    femm.mi_deleteselected()
    femm.mi_clearselected()
Example #8
0
def rot(angle, group):
    femm.mi_selectgroup(group)
    femm.mi_moverotate(0, 0, angle)
    femm.mi_clearselected()
Example #9
0
def mirrorZZ(n1, n2, group):
    femm.mi_selectgroup(group)
    femm.mi_mirror(n1.real, n1.imag, n2.real, n2.imag)
    femm.mi_clearselected()
Example #10
0
def revolveOnce(angle, group):
    femm.mi_selectgroup(group)
    femm.mi_copyrotate(0, 0, angle, 1)
    femm.mi_clearselected()
Example #11
0
def revolve(segments, group):
    femm.mi_selectgroup(group)
    phiStep = 360 / segments
    femm.mi_copyrotate(0, 0, phiStep, segments - 1)
    femm.mi_clearselected()