Пример #1
0
def Materials():
    #Defines magnetic materials for the Undulators Poles and Magnets
    #Pole (~iron type Va Permendur) material data
    H = [
        0.8, 1.5, 2.2, 3.6, 5, 6.8, 9.8, 18, 28, 37.5, 42, 55, 71.5, 80, 85,
        88, 92, 100, 120, 150, 200, 300, 400, 600, 800, 1000, 2000, 4000, 6000,
        10000, 25000, 40000
    ]
    M = [
        0.000998995, 0.00199812, 0.00299724, 0.00499548, 0.00699372,
        0.00999145, 0.0149877, 0.0299774, 0.0499648, 0.0799529, 0.0999472,
        0.199931, 0.49991, 0.799899, 0.999893, 1.09989, 1.19988, 1.29987,
        1.41985, 1.49981, 1.59975, 1.72962, 1.7995, 1.89925, 1.96899, 1.99874,
        2.09749, 2.19497, 2.24246, 2.27743, 2.28958, 2.28973
    ]
    convH = 4. * 3.141592653589793e-07
    #ma = []
    #for i in range(len(H)): ma.append([H[i]*convH, M[i]])
    #mp = rad.MatSatIsoTab(ma)
    #A more compact way:
    mp = rad.MatSatIsoTab([[H[i] * convH, M[i]] for i in range(len(H))])

    #(Permanent) Magnet material: NdFeB with 1.2 Tesla Remanent Magnetization
    mm = rad.MatStd('NdFeB', 1.2)

    return mp, mm
Пример #2
0
def build_box(center, size, material, magnetization, div):
    n_mag = numpy.linalg.norm(magnetization)
    g_id = radia.ObjRecMag(center, size, magnetization)
    if div:
        radia.ObjDivMag(g_id, div)
    # do not apply a material unless a magentization of some magnitude has been set
    if n_mag > 0:
        radia.MatApl(g_id, radia.MatStd(material, n_mag))
    return g_id
Пример #3
0
    def build_model(self):
        """Build a Radia or Opera model with the current result set."""
        length = self.length_spinbox.value()
        if self.build_button.text() == 'Radia':
            rad.UtiDelAll()
            item = self.listview.selectedItems()[0]
            # build magnet geometry
            magnet = rad.ObjCnt([rad.ObjThckPgn(0, length, pg[2:].reshape((4, 2)).tolist(), "z", list(pg[:2]) + [0, ])
                                 for pg in self.state['results'][tuple(item.text().split(', '))]])
            rad.MatApl(magnet, rad.MatStd('NdFeB', next(c for c in self.controls if c.switch == 'Br').control.value()))

            # plot geometry in 3d
            ax = self.plot3d.axes
            ax.cla()
            ax.set_axis_off()
            polygons = rad.ObjDrwVTK(magnet)['polygons']
            vertices = np.array(polygons['vertices']).reshape((-1, 3))  # [x, y, z, x, y, z] -> [[x, y, z], [x, y, z]]
            [set_lim(vertices.min(), vertices.max()) for set_lim in (ax.set_xlim3d, ax.set_ylim3d, ax.set_zlim3d)]
            vertices = np.split(vertices, np.cumsum(polygons['lengths'])[:-1])  # split to find each face
            ax.add_collection3d(Poly3DCollection(vertices, linewidths=0.1, edgecolors='black',
                                                 facecolors=self.get_colour(), alpha=0.2))

            # add arrows
            magnetisation = np.array(rad.ObjM(magnet)).reshape((-1, 6)).T  # reshape to [x, y, z, mx, my, mz]
            for end in (-1, 1):  # one at each end of the block, not in the middle
                magnetisation[2] = end * length / 2
                ax.quiver(*magnetisation, color='black', lw=1, pivot='middle')

            self.tab_control.setCurrentIndex(2)  # switch to '3d' tab

            # solve the model
            try:
                rad.Solve(magnet, 0.00001, 10000)  # precision and number of iterations
            except RuntimeError:
                self.statusBar().showMessage('Radia solve error')

            # get results
            dx = 0.1
            multipoles = [mpole_names.index(c.label) for c in self.controls if c.label.endswith('pole') and c.get_arg()]
            i = multipoles[-1]
            xs = np.linspace(-dx, dx, 4)
            fit_field = np.polyfit(xs / 1000, [rad.Fld(magnet, 'by', [x, 0, 0]) for x in xs], i)
            fit_int = np.polyfit(xs / 1000,
                                 [rad.FldInt(magnet, 'inf', 'iby', [x, 0, -1], [x, 0, 1]) * 0.001 for x in xs], i)
            text = ''
            for j, (l, c, ic, u, iu) in enumerate(
                    zip(mpole_names, fit_field[::-1], fit_int[::-1], units[1:], units[:-1])):
                if j in multipoles:
                    f = factorial(j)  # 1 for dip, quad; 2 for sext; 6 for oct
                    text += f'{l} field = {c * f:.3g} {u}, integral = {ic * f:.3g} {iu}, length = {ic / c:.3g} m\n'
            ax.text2D(1, 1, text, transform=ax.transAxes, va='top', ha='right', fontdict={'size': 8})
            self.plot3d.canvas.draw()
Пример #4
0
def build_box(center, size, material, magnetization, div, h_m_curve=None):
    n_mag = numpy.linalg.norm(magnetization)
    g_id = radia.ObjRecMag(center, size, magnetization)
    if div:
        radia.ObjDivMag(g_id, div)
    # do not apply a material unless a magentization of some magnitude has been set
    if n_mag > 0:
        if material == 'custom':
            mat = radia.MatSatIsoTab(
                [[_MU_0 * h_m_curve[i][0], h_m_curve[i][1]]
                 for i in range(len(h_m_curve))])
        else:
            mat = radia.MatStd(material, n_mag)
        radia.MatApl(g_id, mat)
    return g_id
Пример #5
0
def materials(H, M, material_type_string, magnet_remanence):
    """
    define magnetic materials for the undulator poles and magnets
    arguments:
      H    = list of magnetic field values / (Amp/m)
      M    = corresponding magnetization values / T
      material_type_string = material type string
      magnet_remanence   = remanent magnetization / T
    return: Radia representations of ...
      pole-tip material, magnet material
    """
    # -- magnetic property of poles
    ma = [[sc.mu_0 * H[i], M[i]] for i in range(len(H))]
    mp = rad.MatSatIsoTab(ma)
    # -- permanent magnet material
    mm = rad.MatStd(material_type_string, magnet_remanence)
    return mp, mm
Пример #6
0
    def materials(h, m, smat, rm):
        """
        define magnetic materials for the undulator poles and magnets
        arguments:
          H    = list of magnetic field values / (Amp/m)
          M    = corresponding magnetization values / T
          smat = material type string
          rm   = remanent magnetization / T
        return: Radia representations of ...
          pole-tip material, magnet material
        """
        # -- magnetic property of poles
        ma = [[mu0 * h[i], m[i]] for i in range(len(h))]
        mp = radia.MatSatIsoTab(ma)
        # -- permanent magnet material
        mm = radia.MatStd(smat, rm)

        return mp, mm
Пример #7
0
def _radia_material(material_type, magnetization_magnitude, h_m_curve):
    if material_type == 'custom':
        return radia.MatSatIsoTab(
            [[_MU_0 * h_m_curve[i][0], h_m_curve[i][1]] for i in range(len(h_m_curve))]
        )
    return radia.MatStd(material_type, magnetization_magnitude)
Пример #8
0
#rad.ObjDrwOpenGL(mag01)

trf01 = rad.TrfPlSym([0,10,0], [0,1,0])
trf02 = rad.TrfRot([0,10,0], [0,0,1], 1.)
trf03 = rad.TrfTrsl([30,10,0])
trf04 = rad.TrfInv()
trf05 = rad.TrfCmbL(trf01, trf04)
trf06 = rad.TrfCmbR(trf01, trf04)

#rad.TrfMlt(mag01, trf03, 3)
rad.TrfOrnt(mag01, trf06)

#rad.ObjDrwOpenGL(mag01)

matNdFeB = rad.MatStd('NdFeB')
M = rad.MatMvsH(matNdFeB, 'M', [0,0,0])
print('NdFeB material index:', matNdFeB, ' Magnetization:', M)

matLin01 = rad.MatLin([0.1,0.2],1.1)
matLin02 = rad.MatLin([0.1,0.2],[0,0,1.1])
print('Linear material indexes:', matLin01, matLin02)

dmp = rad.UtiDmp([mag01, trf02], 'bin')
#print(dmp)

elemsRest = rad.UtiDmpPrs(dmp)
print('Indexes of restored elements:', elemsRest)
#rad.ObjDrwOpenGL(elemsRest[0])

print(rad.UtiDmp(elemsRest[0], 'asc'))
Пример #9
0
    def build(self):
        """Create a quadrupole with the given geometry."""
        if self.solve_state < SolveState.SHAPES:
            self.define_shapes()

        rad.UtiDelAll()
        origin = [0, 0, 0]
        nx = [1, 0, 0]
        ny = [0, 1, 0]
        nz = [0, 0, 1]

        tip_mesh = round(self.min_mesh)
        pole_mesh = round(self.min_mesh * self.pole_mult)
        yoke_mesh = round(self.min_mesh * self.yoke_mult)

        length = self.length

        # Subdivide the pole tip cylindrically. The axis is where the edge of the tapered pole meets the Y-axis.
        points = rotate45(self.tip_points)
        x2, y2 = points[-2]  # top right of pole
        x3, y3 = points[-3]  # bottom right of pole
        m = (y2 - y3) / (x2 - x3)
        c = y2 - m * x2
        pole_tip = rad.ObjThckPgn(length / 2, length, points, "z")
        # Slice off the chamfer (note the indexing at the end here - selects the pole not the cut-off piece)
        pole_tip = rad.ObjCutMag(pole_tip, [length - self.chamfer, 0, self.r], [1, 0, -1])[0]
        n_div = max(1, round(math.sqrt((x2 - x3) ** 2 + (y2 - y3) ** 2) / pole_mesh))
        # We have to specify the q values here (second element of each sublist in the subdivision argument)
        # otherwise weird things happen
        mesh = [[n_div, 4], [tip_mesh / 3, 1], [tip_mesh, 1]]
        div_opts = 'Frame->Lab;kxkykz->Size'
        # rad.ObjDivMag(pole_tip, [[tip_mesh, 1], [tip_mesh, 1], [tip_mesh, 3]], div_opts)
        rad.ObjDivMag(pole_tip, mesh, "cyl", [[[0, c, 0], nz], nx, 1], div_opts)
        rad.TrfOrnt(pole_tip, rad.TrfRot(origin, nz, -math.pi / 4))

        pole = rad.ObjThckPgn(length / 2, length, rotate45(self.pole_points), "z")
        rad.ObjDivMag(pole, [pole_mesh, ] * 3, div_opts)
        rad.TrfOrnt(pole, rad.TrfRot(origin, nz, -math.pi / 4))

        # Need to split yoke since Radia can't build concave blocks
        points = rotate45(self.yoke_points[:2] + self.yoke_points[-2:])
        # yoke1 is the part that joins the pole to the yoke
        # Subdivide this cylindrically since the flux goes around a corner here
        # The axis is the second point (x1, y1)
        x1, y1 = points[1]
        yoke1 = rad.ObjThckPgn(length / 2, length, points, "z")
        cyl_div = [[[x1, y1, 0], nz], [self.width, self.width, 0], 1]
        # The first (kr) argument, corresponding to radial subdivision,
        # in rad.ObjDivMag cuts by number not size even though kxkykz->Size is specified.
        # So we have to fudge this. It seems to require a larger number to give the right number of subdivisions.
        n_div = max(1, round(2 * self.width / yoke_mesh))
        rad.ObjDivMag(yoke1, [n_div, yoke_mesh, yoke_mesh], "cyl", cyl_div, div_opts)
        rad.TrfOrnt(yoke1, rad.TrfRot(origin, nz, -math.pi / 4))

        # For the second part of the yoke, we use cylindrical subdivision again. But the axis is not on the corner;
        # instead we calculate the point where the two lines converge (xc, yc).
        points = self.yoke_points[1:3] + self.yoke_points[-3:-1]
        x0, y0 = points[0]
        x1, y1 = points[1]
        x2, y2 = points[2]
        x3, y3 = points[3]
        m1 = (y3 - y0) / (x3 - x0)
        m2 = (y2 - y1) / (x2 - x1)
        c1 = y0 - m1 * x0
        c2 = y1 - m2 * x1
        xc = (c2 - c1) / (m1 - m2)
        yc = m1 * xc + c1
        yoke2 = rad.ObjThckPgn(length / 2, length, points, 'z')
        cyl_div = [[[xc, yc, 0], nz], [x3 - xc, y3 - yc, 0], 1]
        n_div = max(1, round(0.7 * n_div))  # this is a bit of a fudge
        rad.ObjDivMag(yoke2, [n_div, yoke_mesh, yoke_mesh], "cyl", cyl_div, div_opts)

        yoke3 = rad.ObjThckPgn(length / 2, length, self.yoke_points[2:6], "z")
        rad.ObjDivMag(yoke3, [yoke_mesh, ] * 3, div_opts)

        steel = rad.ObjCnt([pole_tip, pole, yoke1, yoke2, yoke3])
        rad.ObjDrwAtr(steel, [0, 0, 1], 0.001)  # blue steel
        rad.TrfOrnt(steel, rad.TrfRot(origin, ny, -math.pi / 2))
        rad.ObjDrwOpenGL(steel)
        rad.TrfOrnt(steel, rad.TrfRot(origin, ny, math.pi / 2))
        # rad.TrfMlt(steel, rad.TrfPlSym([0, 0, 0], [1, -1, 0]), 2)  # reflect along X=Y line to create a quadrant
        rad.TrfZerPerp(steel, origin, [1, -1, 0])
        rad.TrfZerPerp(steel, origin, nz)
        steel_material = rad.MatSatIsoFrm([2000, 2], [0.1, 2], [0.1, 2])
        steel_material = rad.MatStd('Steel42')
        steel_material = rad.MatSatIsoFrm([959.703184, 1.41019852], [33.9916543, 0.5389669], [1.39161186, 0.64144324])
        rad.MatApl(steel, steel_material)

        coil = rad.ObjRaceTrk(origin, [5, 5 + self.coil_width],
                              [self.coil_x * 2 - self.r, length * 2], self.coil_height, 4, self.current_density)
        rad.TrfOrnt(coil, rad.TrfRot(origin, nx, -math.pi / 2))
        rad.TrfOrnt(coil, rad.TrfTrsl([0, self.r + self.taper_height + self.coil_height / 2, 0]))
        rad.TrfOrnt(coil, rad.TrfRot(origin, nz, -math.pi / 4))
        rad.ObjDrwAtr(coil, [1, 0, 0], 0.001)  # red coil
        quad = rad.ObjCnt([steel, coil])

        rad.TrfZerPara(quad, origin, nx)
        rad.TrfZerPara(quad, origin, ny)

        # rad.ObjDrwOpenGL(quad)
        self.radia_object = quad
        self.solve_state = SolveState.BUILT
Пример #10
0
mag07 = rad.ObjCylMag([0,20,0], 5, 10, 21, 'z', [0,0,1])

mag08 = rad.ObjRecCur([-15,0,0], [5,7,15], [0.5,0.5,1.])

mag09 = rad.ObjArcCur([0,0,-5], [10,13], [0,2.5], 10, 15, 1.7, 'man', 'z')

mag10 = rad.ObjRaceTrk([0,0,0], [27,28], [1,2.5], 5, 15, 1.7, 'man', 'z')

mag11 = rad.ObjFlmCur([[-10,-30,-10],[30,-30,-10],[30,25,25],[-30,25,25],[-30,-30,-10]], 10.2)

mag = rad.ObjCnt([mag00, mag01, mag02, mag03, mag04, mag05, mag06, mag07, mag08, mag09])
rad.ObjAddToCnt(mag, [mag10, mag11])
cnt02 = rad.ObjCnt([mag00, mag])

mat = rad.MatStd('NdFeB', 1.2)
rad.MatApl(mag01, mat)
print('Magn. Material index:', mat, ' appled to object:', mag01)

magDpl = rad.ObjDpl(mag, 'FreeSym->False')

print('Number of objects in the container:', rad.ObjCntSize(mag))
print('Number of objects in 2nd container:', rad.ObjCntSize(cnt02))
print('Number of objects in fake container:', rad.ObjCntSize(mag04))

print('Indices of elements in the container:', rad.ObjCntStuf(mag))
print('Indices of elements in the duplicated container:', rad.ObjCntStuf(magDpl))

#rad.ObjDrwOpenGL(mag)
#rad.ObjDrwOpenGL(magDpl)