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
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
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
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
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)
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)
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
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
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()
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
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
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
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]])
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
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
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])
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
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
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
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)
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
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
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)
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
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]])
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])
def build_container(g_ids): return radia.ObjCnt(g_ids)
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