Ejemplo n.º 1
0
def APPLE_II(_per, _nper, _gap, _gapx, _phase, _phase_type, _lx, _lz, _cx, _cz, _air, _br, _mu, _ndiv, _bs1, _s1, _bs2, _s2, _bs3, _s3, _bs2dz, _qp_ind_mag, _qp_dz, _use_sym=False):

    w = [_lx,_per/4-_air,_lz]
    px = _lx/2+_gapx/2;
    pz = _gap/2+_lz/2;

    p1 = 0; p2 = _phase; p3 = 0; p4 = _phase
    if(_phase_type < 0): p2 = -_phase

    #print('w =', w)
    g1 = MagnetArray(_per, _nper, _po=[px,p1,pz], _w=w, _si=1, _type=1, _cx=_cx, _cz=_cz, _br=_br, _mu=_mu, _ndiv=_ndiv,
                     _bs1=_bs1, _s1=_s1, _bs2=_bs2, _s2=_s2, _bs3=_bs3, _s3=_s3, _bs2dz=_bs2dz, _qp_ind_mag=_qp_ind_mag, _qp_dz=_qp_dz)

    g2 = MagnetArray(_per, _nper, _po=[-px,p2,pz], _w=w, _si=1, _type=2, _cx=_cx, _cz=_cz, _br=_br, _mu=_mu, _ndiv=_ndiv,
                     _bs1=_bs1, _s1=_s1, _bs2=_bs2, _s2=_s2, _bs3=_bs3, _s3=_s3, _bs2dz=_bs2dz, _qp_ind_mag=_qp_ind_mag, _qp_dz=_qp_dz)

    if(_use_sym):
        u = rad.ObjCnt([g1,g2])
        trf = rad.TrfCmbL(rad.TrfRot([0,0,0],[0,1,0],pi), rad.TrfInv())
        rad.TrfMlt(u, trf, 2)
        return u, g1, g2, 0, 0

    g3 = MagnetArray(_per, _nper, _po=[-px,p3,-pz], _w=w, _si=-1, _type=1, _cx=_cx, _cz=_cz, _br=-_br, _mu=_mu, _ndiv=_ndiv,
                     _bs1=_bs1, _s1=_s1, _bs2=_bs2, _s2=_s2, _bs3=_bs3, _s3=_s3, _bs2dz=_bs2dz, _qp_ind_mag=_qp_ind_mag, _qp_dz=_qp_dz)

    g4 = MagnetArray(_per, _nper, _po=[px,p4,-pz], _w=w, _si=-1, _type=2, _cx=_cx, _cz=_cz, _br=-_br, _mu=_mu, _ndiv=_ndiv,
                     _bs1=_bs1, _s1=_s1, _bs2=_bs2, _s2=_s2, _bs3=_bs3, _s3=_s3, _bs2dz=_bs2dz, _qp_ind_mag=_qp_ind_mag, _qp_dz=_qp_dz)

    u = rad.ObjCnt([g1,g2,g3,g4])
    return u, g1, g2, g3, g4
Ejemplo n.º 2
0
def wiggler_example():
    # current densities in A / mm^2
    j1 = 128
    j2 = 256

    # number of arc segments
    n1 = 3
    n2 = 6

    # create 5 racetrack coils above the mid-plane:
    #   lower inside, lower outside, upper inside, upper outside, and circular
    # radia.ObjRaceTrk[ctr:[x,y,z], rad:[r1,r2], lstr:[lx,ly], ht, nseg, j]
    rt1 = radia.ObjRaceTrk([0., 0., 38.], [9.5, 24.5], [120., 0.], 36, n1, j1)
    rt2 = radia.ObjRaceTrk([0., 0., 38.], [24.5, 55.5], [120., 0.], 36, n1, j2)
    rt3 = radia.ObjRaceTrk([0., 0., 76.], [10.0, 25.0], [90., 0.], 24, n1, j1)
    rt4 = radia.ObjRaceTrk([0., 0., 76.], [25.0, 55.0], [90., 0.], 24, n1, j2)
    rt5 = radia.ObjRaceTrk([0., 0., 60.], [150.0, 166.3], [0., 0.], 39, n2, -j2)

    c1 = [0.0,1.0,1.0] # blue/green
    c2 = [1.0,0.4,0.0] # orange-red
    thcn = 0.001
    radia.ObjDrwAtr(rt1, c1, thcn)
    radia.ObjDrwAtr(rt2, c2, thcn)
    radia.ObjDrwAtr(rt3, c1, thcn)
    radia.ObjDrwAtr(rt4, c2, thcn)
    radia.ObjDrwAtr(rt5, c2, thcn)

    # assemble into a group
    geom = radia.ObjCnt([rt1, rt2, rt3, rt4, rt5])

    # and reflect in the (x,y) plane [plane through (0,0,0) with normal (0,0,1)]
    radia.TrfZerPara(geom, [0, 0, 0], [0, 0, 1])

    return geom
Ejemplo n.º 3
0
def BuildGeometry():

    #Current Densities in A/mm^2
    j1 = 128
    j2 = 256

    #Coil Presentation Parameters
    n1 = 3
    n2 = 6
    c2 = [1, 0, 0]
    c1 = [0, 1, 1]
    thcn = 0.001

    #Create 5 Coils
    Rt1 = rad.ObjRaceTrk([0., 0., 38.], [9.5, 24.5], [120., 0.], 36, n1, j1)
    rad.ObjDrwAtr(Rt1, c1, thcn)
    Rt3 = rad.ObjRaceTrk([0., 0., 76.], [10., 25.], [90., 0.], 24, n1, j1)
    rad.ObjDrwAtr(Rt3, c1, thcn)
    Rt2 = rad.ObjRaceTrk([0., 0., 38.], [24.5, 55.5], [120., 0.], 36, n1, j2)
    rad.ObjDrwAtr(Rt2, c2, thcn)
    Rt4 = rad.ObjRaceTrk([0., 0., 76.], [25., 55.], [90., 0.], 24, n1, j2)
    rad.ObjDrwAtr(Rt4, c2, thcn)
    Rt5 = rad.ObjRaceTrk([0., 0., 60.], [150., 166.3], [0., 0.], 39, n2, -j2)
    rad.ObjDrwAtr(Rt5, c2, thcn)

    Grp = rad.ObjCnt([Rt1, Rt2, Rt3, Rt4, Rt5])

    #Define Mirror Coils
    rad.TrfZerPara(Grp, [0, 0, 0], [0, 0, 1])

    return Grp
Ejemplo n.º 4
0
def sp8(pos, per, gap, gapx, phase, lxc, lzc, colc, lxs, lzs, cols, airgap, br, nper):
    """
    create "Spring8" undulator
    """
    wc = [lxc, per/4 - airgap, lzc]
    px = 0
    pz = gap/2 + lzc/2
    g1 = undparts(pos + [px, -phase/2, pz], wc, wc, nper, per, br, 1)
    rad.ObjDrwAtr(g1, colc)
    g2 = undparts(pos + [px, -phase/2, -pz], wc, wc, nper, per, -br, -1)
    rad.ObjDrwAtr(g2, colc)
    wc = [lxs, per/4 - airgap, lzs]
    px = lxc/2 + gapx + lxs/2
    pz = gap/2 + lzs/2
    
    g3 = undparts(pos + [px, phase/2, pz], wc, wc, nper, per, br, 1)
    rad.ObjDrwAtr(g3, cols)
    g4 = undparts(pos + [px, phase/2, -pz], wc, wc, nper, per, br, -1)
    rad.ObjDrwAtr(g4, cols)
    g5 = undparts(pos + [-px, phase/2, pz], wc, wc, nper, per, -br, 1)
    rad.ObjDrwAtr(g5, cols)
    g6 = undparts(pos + [-px, phase/2, -pz], wc, wc, nper, per, -br, -1)
    rad.ObjDrwAtr(g6, cols)
    
    g = rad.ObjCnt([g1, g2, g3, g4, g5, g6])
    return g
Ejemplo n.º 5
0
    def create_radia_object(self):
        """Create radia object."""
        if self._radia_object is not None:
            _rad.UtiDel(self._radia_object)

        if self._length == 0:
            return

        mat = _rad.MatLin([self._ksipar, self._ksiper],
                          _np.linalg.norm(self._magnetization))

        if self._rectangular_shape:
            center = []
            width = []
            height = []
            for shp in self._shape:
                shp = _np.array(shp)
                min0 = _np.min(shp[:, 0])
                max0 = _np.max(shp[:, 0])
                min1 = _np.min(shp[:, 1])
                max1 = _np.max(shp[:, 1])
                center.append([(max0 + min0) / 2, (max1 + min1) / 2])
                width.append(max0 - min0)
                height.append(max1 - min1)

            subblock_list = []
            for ctr, wdt, hgt, div in zip(center, width, height,
                                          self._subdivision):
                subblock = _rad.ObjRecMag(
                    [ctr[0], ctr[1], self._longitudinal_position],
                    [wdt, hgt, self._length], self._magnetization)
                subblock = _rad.MatApl(subblock, mat)
                subblock = _rad.ObjDivMag(subblock, div, 'Frame->Lab')
                subblock_list.append(subblock)
            self._radia_object = _rad.ObjCnt(subblock_list)

        else:
            subblock_list = []
            for shp, div in zip(self._shape, self._subdivision):
                subblock = _rad.ObjThckPgn(self._longitudinal_position,
                                           self._length, shp, 'z',
                                           self._magnetization)
                subblock = _rad.MatApl(subblock, mat)
                subblock = _rad.ObjDivMag(subblock, div, 'Frame->Lab')
                subblock_list.append(subblock)
            self._radia_object = _rad.ObjCnt(subblock_list)
Ejemplo n.º 6
0
    def __init__(self, objectlist=[]):
        self.objectlist = objectlist
        self.objectlistradobj = []

        for i in range(len(objectlist)):
            self.objectlistradobj.append(self.objectlist[i].radobj)

        self.radobj = rd.ObjCnt([])

        for i in range(len(objectlist)):
            rd.ObjAddToCnt(self.radobj, self.objectlist[i].radobj)
Ejemplo n.º 7
0
def apple2(pos, per, gap, gapx, phase, lx, lz, airgap, br, nper):
    wv = [lx/2, per/4 - airgap, lz]
    wh = wv
    px = lx/4 + gapx/2
    pz = gap/2 + lz/2
    
    g1 = undparts(pos + [px, phase/2, pz], wv, wh, nper, per, br, 1)
    g2 = undparts(pos + [-px, -phase/2, pz], wv, wh, nper, per, br, 1)
    g3 = undparts(pos + [px, -phase/2, -pz], wv, wh, nper, per, -br, -1)
    g4 = undparts(pos + [-px, phase/2, -pz], wv, wh, nper, per, -br, -1)
    g = rad.ObjCnt([g1, g2, g3, g4])
    return g
Ejemplo n.º 8
0
def Und(lp, mp, np, cp, lm, mm, nm, cm, gap, gapOffset, numPer):

    zer = [0, 0, 0]
    Grp = rad.ObjCnt([])

    #Principal Poles and Magnets
    #y = lp[1]/4;
    y = 0.25 * lp[1]

    #Pole = rad.ObjFullMag([lp[0]/4,y,-lp[2]/2-gap/2], [lp[0]/2,lp[1]/2,lp[2]], zer, np, Grp, mp, cp)
    Pole = rad.ObjFullMag([0.25 * lp[0], y, -0.5 * (lp[2] + gap)],
                          [0.5 * lp[0], 0.5 * lp[1], lp[2]], zer, np, Grp, mp,
                          cp)
    #y += lp[1]/4;
    y += 0.25 * lp[1]

    mDir = -1
    for i in range(0, numPer):
        initM = [0, mDir, 0]
        mDir *= -1
        #y += lm[1]/2
        y += 0.5 * lm[1]

        #Magnet = rad.ObjFullMag([lm[0]/4,y,-lm[2]/2-gap/2-gapOffset], [lm[0]/2,lm[1],lm[2]], initM, nm, Grp, mm, cm)
        Magnet = rad.ObjFullMag(
            [0.25 * lm[0], y, -0.5 * (lm[2] + gap) - gapOffset],
            [0.5 * lm[0], lm[1], lm[2]], initM, nm, Grp, mm, cm)
        #y += (lm[1] + lp[1])/2
        y += 0.5 * (lm[1] + lp[1])

        #Pole = rad.ObjFullMag([lp[0]/4,y,-lp[2]/2-gap/2], [lp[0]/2,lp[1],lp[2]], zer, np, Grp, mp, cp)
        Pole = rad.ObjFullMag([0.25 * lp[0], y, -0.5 * (lp[2] + gap)],
                              [0.5 * lp[0], lp[1], lp[2]], zer, np, Grp, mp,
                              cp)
        #y += lp[1]/2
        y += 0.5 * lp[1]

    initM = [0, mDir, 0]
    #y += lm[1]/4;
    y += 0.25 * lm[1]

    #Magnet = rad.ObjFullMag([lm[0]/4,y,-lm[2]/2-gap/2-gapOffset], [lm[0]/2,lm[1]/2,lm[2]], initM, nm, Grp, mm, cm)
    Magnet = rad.ObjFullMag(
        [0.25 * lm[0], y, -0.5 * (lm[2] + gap) - gapOffset],
        [0.5 * lm[0], 0.5 * lm[1], lm[2]], initM, nm, Grp, mm, cm)

    #Mirrors
    rad.TrfZerPerp(Grp, [0, 0, 0], [1, 0, 0])
    rad.TrfZerPara(Grp, zer, [0, 0, 1])
    rad.TrfZerPerp(Grp, zer, [0, 1, 0])

    return Grp, Pole, Magnet
Ejemplo n.º 9
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()
Ejemplo n.º 10
0
def apple2G(pos, per, gap, gapx, plr, pll, pur, pul, lx, lz, airgap, br, nper):
    """
    create "Apple II" type undulator
    """
    wv = [lx/2, per/4 - airgap, lz]
    wh = wv
    px = lx/4 + gapx/2
    pz = gap/2 + lz/2
    
    g1 = undparts(pos + [px, pur, pz], wv, wh, nper, per, br, si=1)
    g2 = undparts(pos + [-px, pul, pz], wv, wh, nper, per, br, si=1)
    g3 = undparts(pos + [px, plr, -pz], wv, wh, nper, per, -br, si=-1)
    g4 = undparts(pos + [-px, pll, -pz], wv, wh, nper, per, -br, si=-1)

    g = rad.ObjCnt([g1, g2, g3, g4])
    return g
Ejemplo n.º 11
0
def MagnetBlock(_pc, _wc, _cx, _cz, _type, _ndiv, _m):

    u = rad.ObjCnt([])
    
    wwc = _wc
    if(_type!=0):
        wwc = copy(_wc)
        wwc[0] -= 2*_cx
        
    b1 = rad.ObjRecMag(_pc, wwc, _m)
    rad.ObjAddToCnt(u, [b1])
    #ndiv2 = [1,_ndiv[1],_ndiv[2]]

    if((_cx>0.01) and (_cz>0.01)):
        if(_type==1):
            ppc = [_pc[0]-_wc[0]/2+_cx/2,_pc[1],_pc[2]-_cz/2]
            wwc = [_cx,_wc[1],_wc[2]-_cz]
            b2 = rad.ObjRecMag(ppc, wwc, _m)

            ppc = [_pc[0]+_wc[0]/2-_cx/2,_pc[1],_pc[2]+_cz/2]
            wwc = [_cx,_wc[1],_wc[2]-_cz]
            b3 = rad.ObjRecMag(ppc, wwc, _m)
            rad.ObjAddToCnt(u, [b2,b3])

        elif(_type==2):
            ppc = [_pc[0]-_wc[0]/2+_cx/2,_pc[1],_pc[2]+_cz/2]
            wwc = [_cx,_wc[1],_wc[2]-_cz]
            b2 = rad.ObjRecMag(ppc, wwc, _m)

            ppc = [_pc[0]+_wc[0]/2-_cx/2,_pc[1],_pc[2]-_cz/2]
            wwc = [_cx,_wc[1],_wc[2]-_cz]
            b3 = rad.ObjRecMag(ppc, wwc, _m)
            rad.ObjAddToCnt(u, [b2,b3])

        elif(_type==3):
            ppc = [_pc[0]-_wc[0]/2+_cx/2,_pc[1],_pc[2]]
            wwc = [_cx,_wc[1],_wc[2]-2*_cz]
            b2 = rad.ObjRecMag(ppc, wwc, _m)

            ppc = [_pc[0]+_wc[0]/2-_cx/2,_pc[1],_pc[2]]
            wwc = [_cx,_wc[1],_wc[2]-2*_cz]
            b3 = rad.ObjRecMag(ppc, wwc, _m)
            rad.ObjAddToCnt(u, [b2,b3])

    rad.ObjDivMag(u, _ndiv, 'Frame->LabTot')
    return u
Ejemplo n.º 12
0
def undparts(po, wv, wh, nnp, per, br, si, axe=0.):
    """
    create Pure Permanent Magnet
    """
    g = rad.ObjCnt([])
    p = po - [0, nnp*per/2, 0]
    for i in range(0,4*nnp + 1):
        if i == 0 or i == 4*nnp: s = 0.5
        else: s = 1.
        if i%2 == 0: w = wv
        else: w = wh
        t = -(i - 1)*np.pi/2*si
        m = np.array([np.sin(axe)*np.sin(t), np.cos(t), np.cos(axe)*np.sin(t)])*br*s
        ma = rad.ObjRecMag(p, w, m)
        rad.ObjAddToCnt(g, [ma])
        p = p + [0, per/4, 0]
    rad.ObjDrwAtr(g, [0, 0, 1])
    return g
Ejemplo n.º 13
0
    def create_radia_object(
            self,
            magnetization_dict=None,
            horizontal_pos_err_dict=None,
            vertical_pos_err_dict=None):
        _rad.UtiDelAll()
        self._cassettes = {}

        if magnetization_dict is None:
            magnetization_dict = {}

        if horizontal_pos_err_dict is None:
            horizontal_pos_err_dict = {}

        if vertical_pos_err_dict is None:
            vertical_pos_err_dict = {}

        name = 'cs'
        cs = _cassettes.PMCassette(
            upper_cassette=True, name=name,
            init_radia_object=False, **self.cassette_properties)
        cs.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        cs.shift([0, -self._gap/2, 0])
        cs.rotate([0, 0, 0], [0, 0, 1], _np.pi)
        self._cassettes[name] = cs

        name = 'ci'
        ci = _cassettes.PMCassette(
            upper_cassette=False, name=name,
            init_radia_object=False, **self.cassette_properties)
        ci.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        ci.shift([0, -self._gap/2, 0])
        self._cassettes[name] = ci

        self._radia_object = _rad.ObjCnt(
            [c.radia_object for c in [cs, ci]])
Ejemplo n.º 14
0
def Coil(ex):
    excitation = ex
    A = 127 * 31.75
    j = excitation / A
    Pi = math.pi
    coil1 = rad.ObjRecCur([17.875, 163.5, 0], [31.75, 127, 400], [0, 0, j])
    coil2 = rad.ObjArcCur([53.75, 163.5, 200], [20, 51.75], [-Pi / 2, 0], 127,
                          5, j, 'man', 'y')
    coil3 = rad.ObjArcCur([53.75, 53.75, 235.875], [46.25, 173.25],
                          [Pi / 4, Pi / 2], 31.75, 5, -j, 'man', 'z')
    rad.TrfZerPerp(coil2, [0, 0, 0], [0, 0, 1])
    rad.TrfZerPerp(coil2, [0, 0, 0], [1, -1, 0])
    rad.TrfZerPerp(coil3, [0, 0, 0], [0, 0, 1])
    rad.TrfZerPerp(coil3, [0, 0, 0], [1, -1, 0])
    rad.TrfZerPerp(coil1, [0, 0, 0], [1, -1, 0])

    coil = rad.ObjCnt([coil1, coil2, coil3])
    rad.ObjDrwAtr(coil, [1, 0, 0], 0.001)

    return coil
Ejemplo n.º 15
0
def Und(lp, mp, np, cp, lm, mm, nm, cm, gap, gapOffset, numPer):

    zer = [0, 0, 0]
    Grp = rad.ObjCnt([])

    #Principal Poles and Magnets
    y = lp[1] / 4
    Pole = rad.ObjFullMag([lp[0] / 4, y, -lp[2] / 2 - gap / 2],
                          [lp[0] / 2, lp[1] / 2, lp[2]], zer, np, Grp, mp, cp)
    y += lp[1] / 4

    mDir = -1
    for i in range(0, numPer):
        initM = [0, mDir, 0]
        mDir *= -1
        y += lm[1] / 2
        Magnet = rad.ObjFullMag(
            [lm[0] / 4, y, -lm[2] / 2 - gap / 2 - gapOffset],
            [lm[0] / 2, lm[1], lm[2]], initM, nm, Grp, mm, cm)
        y += (lm[1] + lp[1]) / 2
        Pole = rad.ObjFullMag([lp[0] / 4, y, -lp[2] / 2 - gap / 2],
                              [lp[0] / 2, lp[1], lp[2]], zer, np, Grp, mp, cp)
        y += lp[1] / 2

    initM = [0, mDir, 0]
    y += lm[1] / 4
    Magnet = rad.ObjFullMag([lm[0] / 4, y, -lm[2] / 2 - gap / 2 - gapOffset],
                            [lm[0] / 2, lm[1] / 2, lm[2]], initM, nm, Grp, mm,
                            cm)

    #Mirrors
    rad.TrfZerPerp(Grp, [0, 0, 0], [1, 0, 0])
    rad.TrfZerPara(Grp, zer, [0, 0, 1])
    rad.TrfZerPerp(Grp, zer, [0, 1, 0])

    return Grp, Pole, Magnet
Ejemplo n.º 16
0
def make_dipole(pole_dimensions,
                center,
                length,
                current=-10000,
                trimesh_mode=0,
                triangle_min_size=TRIANGLE_MIN_SIZE,
                triangle_max_size=TRIANGLE_MAX_SIZE,
                longitudinal_divisions=4):
    """
    Construct a complete H-dipole made of iron.
    :param pole_dimensions: (dict) Parameters describing geometry of pole piece. See `_create_point_table`.
    :param center: (float) Center point of dipole in x (longitudinal center for beam frame).
    :param length: (float) Length of the dipole in x
    :param current: (float) Current carried by dipole coils (default: -10000)
    :param trimesh_mode: (int) If 0 (default) then the pole piece is divisioned into polygons based on point ordering
    from coordinate list. If != 0 then a Triangular mesh is automatically generated.
    :param longitudinal_divisions: (int) Number of slices to divide up the dipole into along the x-axis (default: 4)
    :return:
    """
    # coil_factor increases coil size slightly to accommodate sharp corners of pole piece
    coil_length_factor = 1.005
    coil_height_factor = 3. / 4.
    coil_or_factor = 0.85
    # Geometry for the poles
    table_quadrant_one = _create_point_table(**pole_dimensions)
    top_coodinates = _get_all_points_top(table_quadrant_one)
    bottom_coordinates = _get_all_points_bottom(top_coodinates)

    top_pole = create_pole(top_coodinates,
                           center,
                           length,
                           mode=trimesh_mode,
                           triangle_min_size=triangle_min_size,
                           triangle_max_size=triangle_max_size)
    bottom_pole = create_pole(bottom_coordinates,
                              center,
                              length,
                              mode=trimesh_mode,
                              triangle_min_size=triangle_min_size,
                              triangle_max_size=triangle_max_size)

    # Material for the poles (uses Iron)
    ironmat = rad.MatSatIsoFrm([20000, 2], [0.1, 2], [0.1, 2])
    rad.MatApl(top_pole, ironmat)
    rad.MatApl(bottom_pole, ironmat)

    # Coils
    coil_outer_radius = pole_dimensions['pole_separation'] * coil_or_factor
    top_coil = make_racetrack_coil(
        center=[
            0, 0.0,
            pole_dimensions['gap_height'] + pole_dimensions['pole_height'] / 2.
        ],
        radii=[0.1, coil_outer_radius],
        sizes=[
            length * coil_length_factor,
            pole_dimensions['pole_width'] * 2 * coil_length_factor,
            pole_dimensions['pole_height'] * coil_height_factor
        ],
        current=current)
    bottom_coil = make_racetrack_coil(center=[
        0, 0.0, -1. *
        (pole_dimensions['gap_height'] + pole_dimensions['pole_height'] / 2.)
    ],
                                      radii=[0.1, coil_outer_radius],
                                      sizes=[
                                          length * coil_length_factor,
                                          pole_dimensions['pole_width'] * 2 *
                                          coil_length_factor,
                                          pole_dimensions['pole_height'] *
                                          coil_height_factor
                                      ],
                                      current=current)

    # Visualization
    rad.ObjDrwAtr(top_pole, [0, 0.4, 0.8])
    rad.ObjDrwAtr(bottom_pole, [0, 0.4, 0.8])
    rad.ObjDrwAtr(top_coil, [0.2, 0.9, 0.6])
    rad.ObjDrwAtr(bottom_coil, [0.2, 0.9, 0.6])

    # Element Division
    rad.ObjDivMag(top_pole, [longitudinal_divisions, 1, 1])
    rad.ObjDivMag(bottom_pole, [longitudinal_divisions, 1, 1])

    return rad.ObjCnt([top_pole, bottom_pole, top_coil, bottom_coil])
Ejemplo n.º 17
0
def MagnetArray(_per, _nper, _po, _w, _si, _type, _cx, _cz, _br, _mu, _ndiv, _bs1, _s1, _bs2, _s2, _bs3, _s3, _bs2dz=0, _qp_ind_mag=None, _qp_dz=0):

    u = rad.ObjCnt([])

    Le = _bs1+_s1+_bs2+_s2+_bs3+_s3
    Lc = (_nper+0.25)*_per
    p = [_po[0],_po[1]-(Lc/2+Le),_po[2]] #po-{0,(Lc/2+Le),0}

    nMagTot = 4*_nper+7
    iMagCen = int(nMagTot/2.) #0-based index of the central magnet
    #print('iMagCen =', iMagCen) #DEBUG

    QP_IsDef = False; QP_DispIsConst = True
    nQP_Disp = 0
    if(_qp_ind_mag is not None):
        if(isinstance(_qp_ind_mag, list) or isinstance(_qp_ind_mag, array)):
            nQP_Disp = len(_qp_ind_mag)
            if(nQP_Disp > 0): QP_IsDef = True
        if(isinstance(_qp_dz, list) or isinstance(_qp_dz, array)): QP_DispIsConst = False
        elif(_qp_dz==0): QP_IsDef = False

    for i in range(nMagTot):
        wc = copy(_w)
        
        if(i==0):
            p[1] += _bs1/2
            wc[1] = _bs1
        elif(i==1):
            p[1] += _bs1/2+_s1+_bs2/2
            wc[1] = _bs2
        elif(i==2):
            p[1] += _bs2/2+_s2+_bs3/2
            wc[1] = _bs3
        elif(i==3):
            p[1] += _bs3/2+_s3+_per/8
        elif((i>3) and (i<4*_nper+4)):
            p[1] += _per/4
        elif(i==4*_nper+4):
            p[1] += _per/8+_s3+_bs3/2
            wc[1] = _bs3
        elif(i==4*_nper+5):
            p[1] += _bs3/2+_s2+_bs2/2
            wc[1] = _bs2
        elif(i==4*_nper+6):
            p[1] += _bs2/2+_s1+_bs1/2
            wc[1] = _bs1

        pc = copy(p)

        if((i==1) or (i==4*_nper+5)):
            if(_si==1): pc[2] += _bs2dz
            else: pc[2] -= _bs2dz

        if(QP_IsDef):
            for iQP in range(nQP_Disp):
                if(i == _qp_ind_mag[iQP] + iMagCen):
                    qpdz = _qp_dz
                    if(not QP_DispIsConst): qpdz = _qp_dz[iQP]
                    pc[2] += qpdz
                    #print('Abs. Ind. of Mag. to be Displaced:', i) #DEBUG
                    break

        t = -i*pi/2*_si
        mcol = [0.0,cos(t),sin(t)]
        m = [mcol[0],mcol[1]*_br,mcol[2]*_br]

        ma = MagnetBlock(pc, wc, _cx, _cz, _type, _ndiv, m)

        mcol = [0.27, 0.9*abs(mcol[1]), 0.9*abs(mcol[2])]
        rad.ObjDrwAtr(ma, mcol, 0.0001)

        rad.ObjAddToCnt(u, [ma])

    mat = rad.MatLin(_mu, abs(_br))
    rad.MatApl(u, mat)

    return u 
Ejemplo n.º 18
0
def hybrid_undulator(lpx, lpy, lpz, pole_properties, pole_segmentation, pole_color,
                     lmx, lmz, magnet_properties, magnet_segmentation, magnet_color,
                     gap, offset, period, period_number):
    """
    create hybrid undulator magnet
    arguments:
      pole_dimensions = [lpx, lpy, lpz] = dimensions of the iron poles / mm
      pole_properties = magnetic properties of the iron poles (M-H curve)
      pole_separation = segmentation of the iron poles
      pole_color = [r,g,b] = color for the iron poles
      magnet_dimensions = [lmx, lmy, lmz] = dimensions of the magnet blocks / mm
      magnet_properties = magnetic properties of the magnet blocks (remanent magnetization)
      magnet_segmentation = segmentation of the magnet blocks
      magnet_color = [r,g,b] = color for the magnet blocks
      gap = undulator gap / mm
      offset = vertical offset / mm of the magnet blocks w/rt the poles
      period = length of one undulator period / mm
      period_number = number of full periods of the undulator magnetic field
    return: Radia representations of
      undulator group, poles, permanent magnets
    """
    pole_dimensions = [lpx, lpy, lpz]
    lmy = period / 2. - pole_dimensions[1]
    magnet_dimensions = [lmx, lmy, lmz]
    zer = [0, 0, 0]
    # full magnet will be assembled into this Radia group
    grp = rad.ObjCnt([])
    # principal poles and magnet blocks in octant(+,+,–)
    # -- half pole
    y = pole_dimensions[1] / 4
    pole = rad.ObjFullMag([pole_dimensions[0] / 4, y, -pole_dimensions[2] / 2 - gap / 2],
                          [pole_dimensions[0] / 2, pole_dimensions[1] / 2, pole_dimensions[2]],
                          zer, pole_segmentation, grp, pole_properties, pole_color)
    y += pole_dimensions[1] / 4
    # -- magnet and pole pairs
    magnetization_dir = -1
    for i in range(0, period_number):
        init_magnetization = [0, magnetization_dir, 0]
        magnetization_dir *= -1
        y += magnet_dimensions[1] / 2
        magnet = rad.ObjFullMag([magnet_dimensions[0] / 4, y, -magnet_dimensions[2] / 2 - gap / 2 - offset],
                                [magnet_dimensions[0] / 2, magnet_dimensions[1], magnet_dimensions[2]],
                                init_magnetization, magnet_segmentation, grp, magnet_properties, magnet_color)
        y += (magnet_dimensions[1] + pole_dimensions[1]) / 2
        pole = rad.ObjFullMag([pole_dimensions[0] / 4, y, -pole_dimensions[2] / 2 - gap / 2],
                              [pole_dimensions[0] / 2, pole_dimensions[1], pole_dimensions[2]],
                              zer, pole_segmentation, grp, pole_properties, pole_color)
        y += pole_dimensions[1] / 2
    # -- end magnet block
    init_magnetization = [0, magnetization_dir, 0]
    y += magnet_dimensions[1] / 4
    magnet = rad.ObjFullMag([magnet_dimensions[0] / 4, y, -magnet_dimensions[2] / 2 - gap / 2 - offset],
                            [magnet_dimensions[0] / 2, magnet_dimensions[1] / 2, magnet_dimensions[2]],
                            init_magnetization, magnet_segmentation, grp, magnet_properties, magnet_color)
    # use mirror symmetry to define the full undulator
    rad.TrfZerPerp(grp, zer, [1, 0, 0])  # reflect in the (y,z) plane
    rad.TrfZerPara(grp, zer, [0, 0, 1])  # reflect in the (x,y) plane
    rad.TrfZerPerp(grp, zer, [0, 1, 0])  # reflect in the (z,x) plane


    return grp, pole, magnet
Ejemplo n.º 19
0
def HybridUndCenPart(_gap,
                     _gap_ofst,
                     _nper,
                     _air,
                     _lp,
                     _ch_p,
                     _np,
                     _np_tip,
                     _mp,
                     _cp,
                     _lm,
                     _ch_m_xz,
                     _ch_m_yz,
                     _ch_m_yz_r,
                     _nm,
                     _mm,
                     _cm,
                     _use_ex_sym=False):
    zer = [0, 0, 0]
    grp = rad.ObjCnt([])

    y = _lp[1] / 4
    initM = [0, -1, 0]

    pole = rad.ObjFullMag([_lp[0] / 4, y, -_lp[2] / 2 - _gap / 2 - _ch_p],
                          [_lp[0] / 2, _lp[1] / 2, _lp[2]], zer,
                          [_np[0], int(_np[1] / 2 + 0.5), _np[2]], grp, _mp,
                          _cp)

    if (_ch_p > 0.):  # Pole Tip
        poleTip = rad.ObjThckPgn(
            _lp[0] / 4, _lp[0] / 2,
            [[y - _lp[1] / 4, -_gap / 2 - _ch_p], [y - _lp[1] / 4, -_gap / 2],
             [y + _lp[1] / 4 - _ch_p, -_gap / 2],
             [y + _lp[1] / 4, -_gap / 2 - _ch_p]], zer)
        rad.ObjDivMag(
            poleTip,
            [_np_tip[0], int(_np_tip[1] / 2 + 0.5), _np_tip[2]])
        rad.MatApl(poleTip, _mp)
        rad.ObjDrwAtr(poleTip, _cp)
        rad.ObjAddToCnt(grp, [poleTip])

    y += _lp[1] / 4 + _air + _lm[1] / 2

    for i in range(_nper):
        magnet = rad.ObjThckPgn(
            _lm[0] / 4, _lm[0] / 2,
            [[y + _lm[1] / 2 - _ch_m_yz_r * _ch_m_yz, -_gap / 2 - _gap_ofst],
             [y + _lm[1] / 2, -_gap / 2 - _gap_ofst - _ch_m_yz],
             [y + _lm[1] / 2, -_gap / 2 - _gap_ofst - _lm[2] + _ch_m_yz],
             [
                 y + _lm[1] / 2 - _ch_m_yz_r * _ch_m_yz,
                 -_gap / 2 - _gap_ofst - _lm[2]
             ],
             [
                 y - _lm[1] / 2 + _ch_m_yz_r * _ch_m_yz,
                 -_gap / 2 - _gap_ofst - _lm[2]
             ], [y - _lm[1] / 2, -_gap / 2 - _gap_ofst - _lm[2] + _ch_m_yz],
             [y - _lm[1] / 2, -_gap / 2 - _gap_ofst - _ch_m_yz],
             [y - _lm[1] / 2 + _ch_m_yz_r * _ch_m_yz, -_gap / 2 - _gap_ofst]],
            initM)
        # Cuting Magnet Corners
        magnet = rad.ObjCutMag(
            magnet, [_lm[0] / 2 - _ch_m_xz, 0, -_gap / 2 - _gap_ofst],
            [1, 0, 1])[0]
        magnet = rad.ObjCutMag(
            magnet, [_lm[0] / 2 - _ch_m_xz, 0, -_gap / 2 - _gap_ofst - _lm[2]],
            [1, 0, -1])[0]

        rad.ObjDivMag(magnet, _nm)
        rad.MatApl(magnet, _mm)
        rad.ObjDrwAtr(magnet, _cm)
        rad.ObjAddToCnt(grp, [magnet])

        initM[1] *= -1
        y += _lm[1] / 2 + _lp[1] / 2 + _air

        if (i < _nper - 1):
            pole = rad.ObjFullMag(
                [_lp[0] / 4, y, -_lp[2] / 2 - _gap / 2 - _ch_p],
                [_lp[0] / 2, _lp[1], _lp[2]], zer, _np, grp, _mp, _cp)

            if (_ch_p > 0.):  # Pole Tip
                poleTip = rad.ObjThckPgn(_lp[0] / 4, _lp[0] / 2,
                                         [[y - _lp[1] / 2, -_gap / 2 - _ch_p],
                                          [y - _lp[1] / 2 + _ch_p, -_gap / 2],
                                          [y + _lp[1] / 2 - _ch_p, -_gap / 2],
                                          [y + _lp[1] / 2, -_gap / 2 - _ch_p]],
                                         zer)
                rad.ObjDivMag(poleTip, _np_tip)
                rad.MatApl(poleTip, _mp)
                rad.ObjDrwAtr(poleTip, _cp)
                rad.ObjAddToCnt(grp, [poleTip])

            y += _lm[1] / 2 + _lp[1] / 2 + _air

    y -= _lp[1] / 4
    pole = rad.ObjFullMag([_lp[0] / 4, y, -_lp[2] / 2 - _gap / 2 - _ch_p],
                          [_lp[0] / 2, _lp[1] / 2, _lp[2]], zer,
                          [_np[0], int(_np[1] / 2 + 0.5), _np[2]], grp, _mp,
                          _cp)
    if (_ch_p > 0.):  # Pole Tip
        poleTip = rad.ObjThckPgn(
            _lp[0] / 4, _lp[0] / 2,
            [[y - _lp[1] / 4, -_gap / 2 - _ch_p],
             [y - _lp[1] / 4 + _ch_p, -_gap / 2], [y + _lp[1] / 4, -_gap / 2],
             [y + _lp[1] / 4, -_gap / 2 - _ch_p]], zer)
        rad.ObjDivMag(
            poleTip,
            [_np_tip[0], int(_np_tip[1] / 2 + 0.5), _np_tip[2]])
        rad.MatApl(poleTip, _mp)
        rad.ObjDrwAtr(poleTip, _cp)
        rad.ObjAddToCnt(grp, [poleTip])

    # Symmetries
    if (
            _use_ex_sym
    ):  # Some "non-physical" mirroring (applicable for calculation of central field only)
        y += _lp[1] / 4
        rad.TrfZerPerp(grp, [0, y, 0], [0, 1, 0])  # Mirror left-right
        rad.TrfZerPerp(grp, [0, 2 * y, 0], [0, 1, 0])

    #     #"Physical" symmetries (applicable also for calculation of total structure with terminations)
    #     rad.TrfZerPerp(grp, zer, [0,1,0]) #Mirror left-right
    #     #Mirror front-back
    #     rad.TrfZerPerp(grp, zer, [1,0,0])
    #     #Mirror top-bottom
    #     rad.TrfZerPara(grp, zer, [0,0,1])

    return grp
Ejemplo n.º 20
0
mag06 = rad.ObjMltExtTri(25, 8, [[0,-15],[-15,0],[0,15],[15,0]], [[5,1],[5,2],[5,3],[5,1]], 'z', [0,0,1], 'ki->Numb,TriAngMin->20,TriAreaMax->10')

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)

magBkg = rad.ObjBckg([1,2,3])

mag = rad.ObjCnt([mag00, mag01, mag02, mag03, mag04, mag05, mag06, mag07, mag08, mag09])
print('Container Content:', rad.ObjCntStuf(mag))
print('Container Size:', rad.ObjCntSize(mag))

rad.ObjAddToCnt(mag, [mag10, mag11])
cnt02 = rad.ObjCnt([mag00, mag])

mat = rad.MatLin([1.01, 1.2], [0, 0, 1.3])
#mat = rad.MatStd('NdFeB', 1.2)
rad.MatApl(mag01, mat)
print('Magn. Material index:', mat, ' appled to object:', mag01)

mag00a = rad.ObjFullMag([10,0,40],[12,18,5],[0,0,1],[2,2,2],cnt02,mat,[0.5,0,0])

rad.ObjDrwOpenGL(cnt02)
Ejemplo n.º 21
0
    def geom(circ):

        eps = 0
        ironcolor = [0, 0.5, 1]
        coilcolor = [1, 0, 0]
        ironmat = radia.MatSatIsoFrm([20000, 2], [0.1, 2], [0.1, 2])

        # Pole faces
        lx1 = thick / 2
        ly1 = width
        lz1 = 20
        l1 = [lx1, ly1, lz1]

        k1 = [[thick / 4. - chamfer / 2., 0, gap / 2.],
              [thick / 2. - chamfer, ly1 - 2. * chamfer]]
        k2 = [[thick / 4., 0., gap / 2. + chamfer], [thick / 2., ly1]]
        k3 = [[thick / 4., 0., gap / 2. + lz1], [thick / 2, ly1]]
        g1 = radia.ObjMltExtRtg([k1, k2, k3])
        radia.ObjDivMag(g1, n1)
        radia.ObjDrwAtr(g1, ironcolor)

        # Vertical segment on top of pole faces
        lx2 = thick / 2
        ly2 = ly1
        lz2 = 30
        l2 = [lx2, ly2, lz2]
        p2 = [thick / 4, 0, lz1 + gap / 2 + lz2 / 2 + 1 * eps]
        g2 = radia.ObjRecMag(p2, l2)
        radia.ObjDivMag(g2, n2)
        radia.ObjDrwAtr(g2, ironcolor)

        # Corner
        lx3 = thick / 2
        ly3 = ly2
        lz3 = ly2 * 1.25
        l3 = [lx3, ly3, lz3]
        p3 = [thick / 4, 0, lz1 + gap / 2 + lz2 + lz3 / 2 + 2 * eps]
        g3 = radia.ObjRecMag(p3, l3)

        typ = [
            [p3[0], p3[1] + ly3 / 2, p3[2] - lz3 / 2],
            [1, 0, 0],
            [p3[0], p3[1] - ly3 / 2, p3[2] - lz3 / 2],
            lz3 / ly3
        ]

        if circ == 1:
            radia.ObjDivMag(g3, [nbr, nbp, n3[1]], 'cyl', typ)
        else:
            radia.ObjDivMag(g3, n3)
        radia.ObjDrwAtr(g3, ironcolor)

        # Horizontal segment between the corners
        lx4 = thick / 2
        ly4 = 80
        lz4 = lz3
        l4 = [lx4, ly4, lz4]
        p4 = [thick / 4, ly3 / 2 + eps + ly4 / 2, p3[2]]
        g4 = radia.ObjRecMag(p4, l4)
        radia.ObjDivMag(g4, n4)
        radia.ObjDrwAtr(g4, ironcolor)

        # The other corner
        lx5 = thick / 2
        ly5 = lz4 * 1.25
        lz5 = lz4
        l5 = [lx5, ly5, lz5]
        p5 = [thick / 4, p4[1] + eps + (ly4 + ly5) / 2, p4[2]]
        g5 = radia.ObjRecMag(p5, l5)

        typ = [
            [p5[0], p5[1] - ly5 / 2, p5[2] - lz5 / 2],
            [1, 0, 0],
            [p5[0], p5[1] + ly5 / 2, p5[2] - lz5 / 2],
            lz5 / ly5
        ]

        if circ == 1:
            radia.ObjDivMag(g5, [nbr, nbp, n5[0]], 'cyl', typ)
        else:
            radia.ObjDivMag(g5, n5)
        radia.ObjDrwAtr(g5, ironcolor)

        # Vertical segment inside the coil
        lx6 = thick / 2
        ly6 = ly5
        lz6 = gap / 2 + lz1 + lz2
        l6 = [lx6, ly6, lz6]
        p6 = [thick / 4, p5[1], p5[2] - (lz6 + lz5) / 2 - eps]
        g6 = radia.ObjRecMag(p6, l6)
        radia.ObjDivMag(g6, n6)
        radia.ObjDrwAtr(g6, ironcolor)

        # Generation of the coil
        r_min = 5
        r_max = 40
        h = 2 * lz6 - 5

        cur_dens = current / h / (r_max - r_min)
        pc = [0, p6[1], 0]
        coil = radia.ObjRaceTrk(pc, [r_min, r_max], [thick, ly6], h, 3, cur_dens)
        radia.ObjDrwAtr(coil, coilcolor)

        # Make container and set the colors
        g = radia.ObjCnt([g1, g2, g3, g4, g5, g6])
        radia.ObjDrwAtr(g, ironcolor)
        radia.MatApl(g, ironmat)
        t = radia.ObjCnt([g, coil])

        # Define the symmetries
        radia.TrfZerPerp(g, [0, 0, 0], [1, 0, 0])
        radia.TrfZerPara(g, [0, 0, 0], [0, 0, 1])
        return t
Ejemplo n.º 22
0
    def undulator(
            pole_lengths, pole_props, pole_segs, block_lengths, block_props,
            block_segs, gap_height, gap_offset, num_periods
    ):
        """
        create hybrid undulator magnet
        arguments:
          pole_lengths = [lpx, lpy, lpz] = dimensions of the iron poles (mm)
          pole_props = magnetic properties of the iron poles (M-H curve)
          pole_segs = segmentation of the iron poles
          block_lengths = [lmx, lmy, lmz] = dimensions of the magnet blocks (mm)
          block_props = magnetic properties of the magnet blocks (remanent magnetization)
          block_segs = segmentation of the magnet blocks
          gap_height = undulator gap (mm)
          gap_offset = vertical offset of the magnet blocks w/rt the poles (mm)
          numPer = number of full periods of the undulator magnetic field
        return: Radia representations of
          undulator group, poles, permanent magnets
        """
        zero = [0, 0, 0]

        # colors
        c_pole = [1, 0, 1]
        c_block = [0, 1, 1]

        # full magnet will be assembled into this Radia group
        grp = radia.ObjCnt([])

        # principal poles and magnet blocks in octant(+,+,–)
        # -- half pole
        y = pole_lengths[1] / 4
        pole = radia.ObjFullMag(
            [pole_lengths[0] / 4, y, -pole_lengths[2] / 2 - gap_height / 2],
            [pole_lengths[0] / 2, pole_lengths[1] / 2, pole_lengths[2]],
            zero, pole_segs, grp, pole_props, c_pole
        )
        y += pole_lengths[1] / 4

        # -- magnet and pole pairs
        m_dir = -1
        for i in range(num_periods):
            init_m = [0, m_dir, 0]
            m_dir *= -1
            y += block_lengths[1] / 2
            magnet = radia.ObjFullMag(
                [
                    block_lengths[0] / 4,
                    y,
                    -block_lengths[2] / 2 - gap_height / 2 - gap_offset
                ],
                [
                    block_lengths[0] / 2, block_lengths[1], block_lengths[2]
                ],
                init_m, block_segs, grp, block_props, c_block
            )
            y += (block_lengths[1] + pole_lengths[1]) / 2
            pole = radia.ObjFullMag(
                [pole_lengths[0] / 4, y, -pole_lengths[2] / 2 - gap_height / 2],
                [pole_lengths[0] / 2, pole_lengths[1], pole_lengths[2]],
                zero, pole_segs, grp, pole_props, c_pole
            )
            y += pole_lengths[1] / 2

        # -- end magnet block
        init_m = [0, m_dir, 0]
        y += block_lengths[1] / 4
        magnet = radia.ObjFullMag(
            [
                block_lengths[0] / 4,
                y,
                -block_lengths[2] / 2 - gap_height / 2 - gap_offset
            ],
            [
                block_lengths[0] / 2, block_lengths[1] / 2, block_lengths[2]
            ],
            init_m, block_segs, grp, block_props, c_block)

        # use mirror symmetry to define the full undulator
        radia.TrfZerPerp(grp, zero, [1, 0, 0])  # reflect in the (y,z) plane
        radia.TrfZerPara(grp, zero, [0, 0, 1])  # reflect in the (x,y) plane
        radia.TrfZerPerp(grp, zero, [0, 1, 0])  # reflect in the (z,x) plane

        return grp, pole, magnet
Ejemplo n.º 23
0
yoke = Yoke()
#rad.ObjDrwOpenGL(yoke)
excitation = 4832.5
rad.MatApl(yoke, mat)
coil = Coil(excitation)

#rad.ObjDrwOpenGL(coil)

rad.TrfZerPara(yoke, [0, 0, 0], [1, 0, 0])
rad.TrfZerPara(yoke, [0, 0, 0], [0, 1, 0])

rad.TrfZerPerp(yoke, [0, 0, 0], [0, 0, 1])

rad.TrfZerPara(coil, [0, 0, 0], [1, 0, 0])
rad.TrfZerPara(coil, [0, 0, 0], [0, 1, 0])
full = rad.ObjCnt([yoke, coil])

#rad.ObjDrwOpenGL(full)

t0 = time.time()
res = rad.Solve(full, 0.0001, 10000)
# No workers should exit rad.Solve
assert mpi4py.MPI.COMM_WORLD.Get_rank() == 0

#print('Solved for Magnetizations in', round(time.time() - t0, 2), 's')
expect = [
    9.991124106723865e-05, 1.7586937018625115, 0.009296872940670615, 744.0
]
assert expect == res, \
    '{} expected != actual {}'.format(expect, res)
#print('Relaxation Results:', res)
Ejemplo n.º 24
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
Ejemplo n.º 25
0
    def create_radia_object(
            self,
            magnetization_dict=None,
            horizontal_pos_err_dict=None,
            vertical_pos_err_dict=None):
        _rad.UtiDelAll()
        self._cassettes = {}

        if magnetization_dict is None:
            magnetization_dict = {}

        if horizontal_pos_err_dict is None:
            horizontal_pos_err_dict = {}

        if vertical_pos_err_dict is None:
            vertical_pos_err_dict = {}

        if _utils.depth(self._block_shape) != 3:
            self._block_shape = [self._block_shape]

        mirror_block_shape = [
            [(-1)*pts[0], pts[1]] for shp in self._block_shape for pts in shp]

        name = 'cse'
        cse = _cassettes.PMCassette(
            block_shape=mirror_block_shape,
            upper_cassette=True, name=name,
            init_radia_object=False, **self.cassette_properties)
        cse.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        cse.shift([0, -self._gap/2, 0])
        cse.rotate([0, 0, 0], [0, 0, 1], _np.pi)
        self._cassettes[name] = cse

        name = 'csd'
        csd = _cassettes.PMCassette(
            block_shape=self._block_shape,
            upper_cassette=True, name=name,
            init_radia_object=False, **self.cassette_properties)
        csd.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        csd.shift([0, -self._gap/2, 0])
        csd.rotate([0, 0, 0], [0, 0, 1], _np.pi)
        self._cassettes[name] = csd

        name = 'cie'
        cie = _cassettes.PMCassette(
            block_shape=self._block_shape,
            upper_cassette=False, name=name,
            init_radia_object=False, **self.cassette_properties)
        cie.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        cie.shift([0, -self._gap/2, 0])
        self._cassettes[name] = cie

        name = 'cid'
        cid = _cassettes.PMCassette(
            block_shape=mirror_block_shape,
            upper_cassette=False, name=name,
            init_radia_object=False, **self.cassette_properties)
        cid.create_radia_object(
            magnetization_list=magnetization_dict.get(name),
            horizontal_pos_err=horizontal_pos_err_dict.get(name),
            vertical_pos_err=vertical_pos_err_dict.get(name))
        cid.shift([0, -self._gap/2, 0])
        self._cassettes[name] = cid

        self._radia_object = _rad.ObjCnt(
            [c.radia_object for c in [csd, cse, cid, cie]])
Ejemplo n.º 26
0
    def create_radia_object(self,
                            magnetization_list=None,
                            horizontal_pos_err=None,
                            vertical_pos_err=None):
        """Create radia object."""
        if self._radia_object is not None:
            _rad.UtiDel(self._radia_object)

        if horizontal_pos_err is None:
            horizontal_pos_err = [0] * self.nr_blocks
        if len(horizontal_pos_err) != self.nr_blocks:
            raise ValueError('Invalid length for horizontal errors list.')
        self._horizontal_pos_err = horizontal_pos_err

        if vertical_pos_err is None:
            vertical_pos_err = [0] * self.nr_blocks
        if len(vertical_pos_err) != self.nr_blocks:
            raise ValueError('Invalid length for vertical errors list.')
        self._vertical_pos_err = vertical_pos_err

        block_length = self._period_length / 4 - self._block_distance

        length_list = _utils.flatten([
            self._start_blocks_length, [block_length] * self.nr_core_blocks,
            self._end_blocks_length
        ])

        distance_list = _utils.flatten([
            self._start_blocks_distance,
            [self._block_distance] * (self.nr_core_blocks - 1),
            self._end_blocks_distance
        ])

        position_list = [0]
        for i in range(1, self.nr_blocks):
            position_list.append((length_list[i] + length_list[i - 1]) / 2 +
                                 distance_list[i - 1])
        position_list = list(_np.cumsum(position_list))

        if magnetization_list is None:
            magnetization_list = self.get_ideal_magnetization_list()

        self._blocks = []
        for length, position, magnetization in zip(length_list, position_list,
                                                   magnetization_list):
            block = _blocks.PMBlock(self._block_shape,
                                    length,
                                    position,
                                    magnetization,
                                    subdivision=self._block_subdivision,
                                    rectangular_shape=self._rectangular_shape,
                                    ksipar=self._ksipar,
                                    ksiper=self._ksiper)
            self._blocks.append(block)

        for idx, block in enumerate(self._blocks):
            block.shift([horizontal_pos_err[idx], vertical_pos_err[idx], 0])

        rad_obj_list = []
        for block in self._blocks:
            if block.radia_object is not None:
                rad_obj_list.append(block.radia_object)
        self._radia_object = _rad.ObjCnt(rad_obj_list)

        self.shift([0, 0, -(position_list[0] + position_list[-1]) / 2])
Ejemplo n.º 27
0
def build_container(g_ids):
    return radia.ObjCnt(g_ids)
Ejemplo n.º 28
0
def Geom():

    #Pole faces
    rap = 0.5
    ct = [0, 0, 0]
    z0 = gap / 2
    y0 = width / 2
    amax = hyp * asinh(y0 / z0)
    dz = z0 * (cosh(amax) - 1)
    aStep = amax / np
    na = int(amax * (1 + 2 / np) / aStep) + 1
    qq = [[(z0 * sinh(ia * aStep / hyp)), (z0 * cosh(ia * aStep))]
          for ia in range(na)]
    hh = qq[np][1] + height * rap - dz
    qq[np + 1] = [qq[np][0], hh]
    qq[np + 2] = [0, hh]
    g1 = rad.ObjThckPgn(thick / 4, thick / 2, qq)
    rad.ObjDivMag(g1, n1)

    #Vertical segment on top of pole faces
    g2 = rad.ObjRecMag(
        [thick / 4, width / 4, gap / 2 + height * (1 / 2 + rap / 2)],
        [thick / 2, width / 2, height * (1 - rap)])
    rad.ObjDivMag(g2, n2)

    #Corner
    gg = rad.ObjCnt([g1, g2])
    gp = rad.ObjCutMag(gg, [thick / 2 - chamfer - gap / 2, 0, 0],
                       [1, 0, -1])[0]
    g3 = rad.ObjRecMag([thick / 4, width / 4, gap / 2 + height + depth / 2],
                       [thick / 2, width / 2, depth])
    cy = [[[0, width / 2, gap / 2 + height], [1, 0, 0]],
          [0, 0, gap / 2 + height], 2 * depth / width]
    rad.ObjDivMag(g3, [nr3, np3, nx], 'cyl', cy)

    #Horizontal segment between the corners
    tan_n = tan(2 * pi / 2 / Nn)
    length = tan_n * (height + gap / 2) - width / 2
    g4 = rad.ObjRecMag(
        [thick / 4, width / 2 + length / 2, gap / 2 + height + depth / 2],
        [thick / 2, length, depth])
    rad.ObjDivMag(g4, n4)

    #The other corner
    posy = width / 2 + length
    posz = posy / tan_n
    g5 = rad.ObjThckPgn(thick / 4, thick / 2,
                        [[posy, posz], [posy, posz + depth],
                         [posy + depth * tan_n, posz + depth]])
    cy = [[[0, posy, posz], [1, 0, 0]], [0, posy, posz + depth], 1]
    rad.ObjDivMag(g5, [nr5, np5, nx], 'cyl', cy)

    #Generation of the coil
    Rmax = Rmin - width / 2 + gap / 2 + offset - 2
    coil1 = rad.ObjRaceTrk([0, 0, gap / 2 + height / 2 + offset / 2],
                           [Rmin, Rmax], [thick, width - 2 * Rmin],
                           height - offset, 3, CurDens)
    rad.ObjDrwAtr(coil1, coilcolor)
    hh = (height - offset) / 2
    coil2 = rad.ObjRaceTrk([0, 0, gap / 2 + height - hh / 2],
                           [Rmax, Rmax + hh * 0.8], [thick, width - 2 * Rmin],
                           hh, 3, CurDens)
    rad.ObjDrwAtr(coil2, coilcolor)

    #Make container, set the colors and define symmetries
    g = rad.ObjCnt([gp, g3, g4, g5])
    rad.ObjDrwAtr(g, ironcolor)
    gd = rad.ObjCnt([g])

    rad.TrfZerPerp(gd, ct, [1, 0, 0])
    rad.TrfZerPerp(gd, ct, [0, 1, 0])

    t = rad.ObjCnt([gd, coil1, coil2])
    rad.TrfZerPara(t, ct, [0, cos(pi / Nn), sin(pi / Nn)])

    rad.TrfMlt(t, rad.TrfRot(ct, [1, 0, 0], 4 * pi / Nn), int(round(Nn / 2)))
    rad.MatApl(g, ironmat)
    rad.TrfOrnt(t, rad.TrfRot([0, 0, 0], [1, 0, 0], pi / Nn))

    return t