def wradTranslate(self, translation_vector): '''trying to write a translation function''' #translate vertices for i in range(len(self.vertices)): self.vertices[i] = self.vertices[i] + translation_vector #translate radia object tran = rd.TrfTrsl(translation_vector) rd.TrfOrnt(self.radobj, tran)
def _apply_rotation(g_id, xform): xform = PKDict(xform) radia.TrfOrnt( g_id, radia.TrfRot( sirepo.util.split_comma_delimited_string(xform.center, float), sirepo.util.split_comma_delimited_string(xform.axis, float), numpy.pi * float(xform.angle) / 180. ) )
def wradFieldInvert(self): '''trying to write a field inversion function''' for i in range(len(self.magnetisation)): u = -self.magnetisation[i] self.magnetisation[i] = u self.material.M = self.magnetisation fieldinvert = rd.TrfInv(self.radobj) rd.TrfOrnt(self.radobj, fieldinvert) #invert the colour tmp = np.zeros(3) #reflect colour tmpcol = [(4 * x - 2) for x in self.colour] tmpcol[0] = -tmpcol[0] tmpcol[1] = -tmpcol[1] tmpcol[2] = -tmpcol[2] self.colour = [(2 + x) / 4.0 for x in tmpcol] rd.ObjDrwAtr(self.radobj, self.colour, self.linethickness)
def wradRotate(self, pivot_origin, pivot_vector, rot_magnitude): '''trying to write a rotation function # u' = quq* #u is point #q is quaternion representation of rotation angle ( sin (th/2)i, sin(th/2)j, sin (th/2)k, cos (th/2))''' q = R.from_quat([ pivot_vector[0] * np.sin(rot_magnitude / 2.0), pivot_vector[1] * np.sin(rot_magnitude / 2.0), pivot_vector[2] * np.sin(rot_magnitude / 2.0), np.cos(rot_magnitude / 2.0) ]) #rotate vertices for i in range(len(self.vertices)): u = self.vertices[i] - pivot_origin self.vertices[i] = q.apply(u) #rotate magnetisation vector self.magnetisation = (q.apply(self.magnetisation)).tolist() self.material.M = self.magnetisation # rotate colour q = R.from_quat([ pivot_vector[0] * np.sin(rot_magnitude / 2.0), pivot_vector[1] * np.sin(rot_magnitude / 2.0), pivot_vector[2] * np.sin(rot_magnitude / 2.0), np.cos(rot_magnitude / 2.0), ]) tmpcol = [(4 * x - 2) for x in self.colour] tmpcol = q.apply(tmpcol) self.colour = [(2 + x) / 4.0 for x in tmpcol] rd.ObjDrwAtr(self.radobj, self.colour, self.linethickness) #rotate radia object rota = rd.TrfRot(pivot_origin, pivot_vector, rot_magnitude) rd.TrfOrnt(self.radobj, rota)
def _apply_translation(g_id, xform): radia.TrfOrnt(g_id, radia.TrfTrsl(_split_comma_field(xform.distance, 'float')))
def _apply_rotation(g_id, xform): radia.TrfOrnt( g_id, radia.TrfRot(_split_comma_field(xform.center, 'float'), _split_comma_field(xform.axis, 'float'), numpy.pi * float(xform.angle) / 180.))
def rotate(self, point, vector, angle): """Rotate radia object.""" if self._radia_object is not None: self._radia_object = _rad.TrfOrnt( self._radia_object, _rad.TrfRot(point, vector, angle))
def shift(self, value): """Shift radia object.""" if self._radia_object is not None: self._radia_object = _rad.TrfOrnt(self._radia_object, _rad.TrfTrsl(value))
def _apply_translation(g_id, xform): xform = PKDict(xform) radia.TrfOrnt( g_id, radia.TrfTrsl(sirepo.util.split_comma_delimited_string(xform.distance, float)) )
#mag00sbd = rad.ObjDivMagCyl(mag00, [[2,0.5],[3,0.2],[4,0.1]], [2.5,4,0], [0,0,1], [8,0,0], 3, 'Frame->Lab') print('Volume of 3D object:', rad.ObjGeoVol(mag01sbd)) print('Geom. Limits of 3D object:', rad.ObjGeoLim(mag01sbd)) #rad.ObjDrwOpenGL(mag01) trf01 = rad.TrfPlSym([0,10,0], [0,1,0]) trf02 = rad.TrfRot([0,10,0], [0,0,1], 1.) trf03 = rad.TrfTrsl([30,10,0]) trf04 = rad.TrfInv() trf05 = rad.TrfCmbL(trf01, trf04) trf06 = rad.TrfCmbR(trf01, trf04) #rad.TrfMlt(mag01, trf03, 3) rad.TrfOrnt(mag01, trf06) #rad.ObjDrwOpenGL(mag01) matNdFeB = rad.MatStd('NdFeB') M = rad.MatMvsH(matNdFeB, 'M', [0,0,0]) print('NdFeB material index:', matNdFeB, ' Magnetization:', M) matLin01 = rad.MatLin([0.1,0.2],1.1) matLin02 = rad.MatLin([0.1,0.2],[0,0,1.1]) print('Linear material indexes:', matLin01, matLin02) dmp = rad.UtiDmp([mag01, trf02], 'bin') #print(dmp) elemsRest = rad.UtiDmpPrs(dmp)
def wradReflect(self, reflection_origin, reflection_vector): '''trying to write a reflection function # u' = quq #u is point #q is quaternion representation of rotation angle ( sin (th/2)i, sin(th/2)j, sin (th/2)k, cos (th/2))''' r = reflection_vector / np.linalg.norm( reflection_vector) #ai + bj + ck tmp = np.zeros(3) #reflect vertices for i in range(len(self.vertices)): u = self.vertices[i] - reflection_origin # xi + yj + zk #i x(-a^2 + b^2 + c^2) -2aby -2acz #j y(-b^2 + a^2 + c^2) -2abx -2bcz #k z(-c^2 + a^2 + b^2) -2acx -2bcy tmp[0] = u[0] * (-r[0]**2 + r[1]**2 + r[2]**2) - 2 * r[0] * (r[1] * u[1] + r[2] * u[2]) tmp[1] = u[1] * (-r[1]**2 + r[0]**2 + r[2]**2) - 2 * r[1] * (r[0] * u[0] + r[2] * u[2]) tmp[2] = u[2] * (-r[2]**2 + r[0]**2 + r[1]**2) - 2 * r[2] * (r[0] * u[0] + r[1] * u[1]) self.vertices[i] = tmp #reflect magnetisation vector u = self.magnetisation tmp[0] = u[0] * (-r[0]**2 + r[1]**2 + r[2]**2) - 2 * r[0] * (r[1] * u[1] + r[2] * u[2]) tmp[1] = u[1] * (-r[1]**2 + r[0]**2 + r[2]**2) - 2 * r[1] * (r[0] * u[0] + r[2] * u[2]) tmp[2] = u[2] * (-r[2]**2 + r[0]**2 + r[1]**2) - 2 * r[2] * (r[0] * u[0] + r[1] * u[1]) self.magnetisation = tmp self.material.M = self.magnetisation #is colour applied at this level? #reflect the colour r = reflection_vector / np.linalg.norm( reflection_vector) #ai + bj + ck tmp = np.zeros(3) #reflect colour tmpcol = [(4 * x - 2) for x in self.colour] u = tmpcol # xi + yj + zk #i x(-a^2 + b^2 + c^2) -2aby -2acz #j y(-b^2 + a^2 + c^2) -2abx -2bcz #k z(-c^2 + a^2 + b^2) -2acx -2bcy tmp[0] = u[0] * (-r[0]**2 + r[1]**2 + r[2]**2) - 2 * r[0] * (r[1] * u[1] + r[2] * u[2]) tmp[1] = u[1] * (-r[1]**2 + r[0]**2 + r[2]**2) - 2 * r[1] * (r[0] * u[0] + r[2] * u[2]) tmp[2] = u[2] * (-r[2]**2 + r[0]**2 + r[1]**2) - 2 * r[2] * (r[0] * u[0] + r[1] * u[1]) tmpcol = tmp self.colour = [(2 + x) / 4.0 for x in tmpcol] rd.ObjDrwAtr(self.radobj, self.colour, self.linethickness) #reflect radia object refl = rd.TrfPlSym(reflection_origin, reflection_vector) rd.TrfOrnt(self.radobj, refl)
def rotate(self, point, vector, angle): self._radia_object = _rad.TrfOrnt( self._radia_object, _rad.TrfRot(point, vector, angle))
def shift(self, value): self._radia_object = _rad.TrfOrnt( self._radia_object, _rad.TrfTrsl(value))
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 shift(self, value): """Shift the radia object.""" if self._radia_object is not None: self._radia_object = _rad.TrfOrnt(self._radia_object, _rad.TrfTrsl(value)) self._longitudinal_position += value[2]
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