def compute_fields(points_list, radia_object_id = None, field_component = 'bz'): m = len(points_list) k = m / size ## decompose the domain of the field calcaulation to the different processors and send the arrays if rank == 0: radia_object = rad.UtiDmp([radia_object_id], 'bin') for i in range(1, size): comm.send(radia_object, dest = i) else: radia_object = comm.recv(source = 0) device_id = rad.UtiDmpPrs(radia_object) ## convert the arrrays back into radia friendly format calc_points = np.asarray(points_list[rank::size]) radia_points = np.ndarray.tolist(calc_points) # Compute the fields at the points specified field_result = rad.Fld(device_id, field_component, radia_points) # construct arrays to gather points and field solution for plotting and analysis sendbuf = np.column_stack([calc_points, np.asarray(field_result)]) row,col = sendbuf.shape recvbuf = None if rank == 0: recvbuf = np.empty([size, k+1, col]) # Gather the arrays from the different processors comm.Gather(sendbuf, recvbuf, root = 0) # Return the field result if rank == 0: # clean up the data after collecting it data_out = recvbuf.reshape([size * (k + 1), col]) bad_points = np.where((data_out > 1.0e20) + (data_out < -1.0e20) ) data_out = np.delete(data_out, bad_points[0], axis = 0) # sort the data before returning, sort by x, then y, then z indices = np.lexsort((data_out[:,0], data_out[:,1], data_out[:,2])) data_out = [data_out[i,:]for i in indices] return np.asarray(data_out) else: return None
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
def dump_bin(g_id): return radia.UtiDmp(g_id, 'bin')
def dump(g_id): return radia.UtiDmp(g_id, 'asc')
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) data_cnt = rad.ObjDrwVTK(cnt02) print(data_cnt) objAfterCut = rad.ObjCutMag(mag00a,[10,0,40],[1,1,1]) #,'Frame->Lab') print('Indexes of objects after cutting:', objAfterCut) #rad.ObjDrwOpenGL(objAfterCut[0]) print(rad.UtiDmp(mag01, 'asc')) print(rad.UtiDmp(mat, 'asc')) #print(rad.UtiDmp(107, 'asc')) magDpl = rad.ObjDpl(mag, 'FreeSym->False') print('Number of objects in the container:', rad.ObjCntSize(mag)) print('Number of objects in 2nd container:', rad.ObjCntSize(cnt02)) print('Number of objects in fake container:', rad.ObjCntSize(mag04)) print('Indices of elements in the container:', rad.ObjCntStuf(mag)) print('Indices of elements in the duplicated container:', rad.ObjCntStuf(magDpl)) #rad.ObjDrwOpenGL(mag) #rad.ObjDrwOpenGL(magDpl)
def _create_dump(path, radia_obj): with open(path, 'wb') as ff: mag_dump = radia.UtiDmp(radia_obj, 'bin') ff.write(mag_dump)
def dump_bin(geom): return radia.UtiDmp(geom, 'bin')
def dump(geom): return radia.UtiDmp(geom, 'asc')