Exemple #1
0
    def set_cassete_positions(self, dp=None, dcp=None, dgv=None, dgh=None):
        """
        Change longitudinal cassette positions to adjust
        polarization and energy.
        """
        if dp is None:
            dp = self._dp

        if dcp is None:
            dcp = self._dcp

        if dgv is None:
            dgv = self._dgv

        if dgh is None:
            dgh = self._dgh

        csd = self._cassettes['csd']
        cse = self._cassettes['cse']
        cid = self._cassettes['cid']
        cie = self._cassettes['cie']

        csd_z = _np.array(_rad.ObjM(csd.radia_object))[:, 0, 2]
        csd_shift = - (_np.max(csd_z) + _np.min(csd_z))/2 + dgv

        cse_z = _np.array(_rad.ObjM(cse.radia_object))[:, 0, 2]
        cse_shift = - (
            _np.max(cse_z) + _np.min(cse_z))/2 + dgv + dgh + dp + dcp

        cid_z = _np.array(_rad.ObjM(cid.radia_object))[:, 0, 2]
        cid_shift = - (_np.max(cid_z) + _np.min(cid_z))/2 + dp - dcp

        cie_z = _np.array(_rad.ObjM(cie.radia_object))[:, 0, 2]
        cie_shift = - (_np.max(cie_z) + _np.min(cie_z))/2 + dgh

        csd.shift([0, 0, csd_shift])
        cse.shift([0, 0, cse_shift])
        cid.shift([0, 0, cid_shift])
        cie.shift([0, 0, cie_shift])

        self._dp = dp
        self._dcp = dcp
        self._dgv = dgv
        self._dgh = dgh
        return True
    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()
Exemple #3
0
 def check_segments(self, container):
     """Loop through all the objects in a container and evaluate the segmentation.
     Good shapes will have a magnetisation perpendicular to one of the faces.
     So find the normal of each face and evaluate the dot product with  the magnetisation, both normalised to 1.
     The best have a max dot product of 1. Theoretical min is 1/sqrt(3) though most will be above 1/sqrt(2)."""
     shapes = rad.ObjCntStuf(container)
     xmin, xmax, ymin, ymax, zmin, zmax = rad.ObjGeoLim(container)
     print(f'Checking {len(shapes)} shapes in {container}, extent: x {xmin:.1f} to {xmax:.1f}, y {ymin:.1f} to {ymax:.1f}, z {zmin:.1f} to {zmax:.1f}')
     dot_products = {}
     for shape in shapes:
         sub_shapes = rad.ObjCntStuf(shape)
         if len(sub_shapes) > 0:  # this shape is a container
             dot_products.update(self.check_segments(shape))  # recurse and update dict
         else:  # it's an atomic shape
             mag = rad.ObjM(shape)[0]  # returns [[mx, my, mz]], select the first element i.e. [mx, my, mz]
             norm = np.linalg.norm(mag)  # normalise so total is 1
             if norm == 0:
                 continue
             mag = mag / norm
             # Have to parse the information from rad.UtiDmp, no other way of getting polyhedron faces!
             info = rad.UtiDmp(shape).replace('{', '[').replace('}', ']')  # convert from Mathematica list format
             in_face_list = False
             # print(info)
             lines = info.split('\n')
             description = lines[0].split(': ')
             # print(description)
             object_type = description[-1]
             # print('Type is', object_type)
             if object_type == 'RecMag':  # cuboid with axes parallel to x, y, z
                 # simply find the largest component of normalised magnetisation - the closer to 1, the better
                 dot_products[shape] = max(abs(mag))
             elif object_type == 'Polyhedron':  # need to loop over the faces
                 product_list = []
                 for line in lines[1:]:
                     if in_face_list:
                         if '[' not in line:  # reached the end of the face list
                             break
                         points = np.array(eval(line.rstrip(',')))
                         normal = np.cross(points[1] - points[0], points[2] - points[0])
                         product_list.append(np.dot(normal / np.linalg.norm(normal), mag))  # normalise->unit vector
                     elif 'Face Vertices' in line:
                         in_face_list = True
                 dot_products[shape] = max(product_list)  # max seems to be a reasonable figure of merit
     return dot_products
Exemple #4
0
def get_magnetization(g_id):
    return radia.ObjM(g_id)
 def get_magnetization(self, name):
     return radia.ObjM(self.get_geom(name))
Exemple #6
0
def get_magnetization(geom):
    return radia.ObjM(geom)