def ellipsoid_sheet(a, b, c, n_zs, **kwargs): """Creates an ellipsoidal apical mesh. Parameters ---------- a, b, c : floats Size of the ellipsoid half axes in the x, y, and z directions, respectively n_zs : int The (approximate) number of faces along the z axis. kwargs are passed to `get_ellipsoid_centers` Returns ------- eptm : a :class:`Epithelium` object The mesh returned is an `Epithelium` and not a simpler `Sheet` so that a unique cell data can hold information on the whole volume of the ellipsoid. """ centers = get_ellipsoid_centers(a, b, c, n_zs, **kwargs) centers = centers.append( pd.Series({"x": 0, "y": 0, "z": 0, "theta": 0, "phi": 0}), ignore_index=True ) centers["x"] /= a centers["y"] /= b centers["z"] /= c vor3d = Voronoi(centers[list("xyz")].values) vor3d.close() dsets = from_3d_voronoi(vor3d) veptm = Epithelium("v", dsets, config.geometry.bulk_spec()) eptm_ = single_cell(veptm, centers.shape[0] - 1) eptm_.reset_index() eptm = get_outer_sheet(eptm_) eptm.reset_index() eptm.reset_topo() eptm.vert_df["rho"] = np.linalg.norm(eptm.vert_df[eptm.coords], axis=1) eptm.vert_df["theta"] = np.arcsin(eptm.vert_df.eval("z/rho")) eptm.vert_df["phi"] = np.arctan2(eptm.vert_df["y"], eptm.vert_df["x"]) eptm.vert_df["x"] = a * ( np.cos(eptm.vert_df["theta"]) * np.cos(eptm.vert_df["phi"]) ) eptm.vert_df["y"] = b * ( np.cos(eptm.vert_df["theta"]) * np.sin(eptm.vert_df["phi"]) ) eptm.vert_df["z"] = c * np.sin(eptm.vert_df["theta"]) eptm.settings["abc"] = [a, b, c] EllipsoidGeometry.update_all(eptm) return eptm
def Astar(initCord, clrn, exp=0, scale=2): actionSet = [] fact = 1 hc = 250 wc = -250 clrr = np.array(clrn, dtype='f') cart = np.array(initCord, dtype='f') print(clrr) if (clrr[0] >= 0): clr = clrr[0] else: print('Clearnace cannot be negative.....\nTerminating') return actionSet, -1 # clr = float(int(clr*100)/100.) rad = 17.7 # 35,4/2 cm tot = int(math.ceil((rad + clr)) * fact) map1 = FinalMap(500, 500, tot) map1.circ(100, 200, 225) map1.circ(50, 400, 100) map1.circ(40, 375, 375) obsChk = Obs(500, 500, tot) cv2.imwrite('grid_init.jpg', map1.grid) map2 = cv2.imread('grid_init.jpg') map2 = cv2.cvtColor(map2, cv2.COLOR_BGR2RGB) plt.grid() plt.ion() plt.imshow(map2) print('Generating voronoi diagram.....') density = 0.8 # in percentage of total pixels samples = np.random.randint(tot, 501 - tot, size=(int(500 * 500 * density), 2)) vor = Voronoi(samples, incremental=True) print('Voronoi generated....') plt.show() init = np.array([hc - cart[1], cart[0] - wc, cart[2]], dtype='f') if (not obsChk.notObs(init[:-1])): print('Start position cannot be in the obstacle.....\nTerminating') return actionSet, -1 checkInp = True while checkInp: print('Total clearance set at: ', tot) print( 'Enter the step "d" in integer (1<=d<total clearance (value as above)): ' ) step_d = int(input()) if (step_d < 1 or step_d >= tot): print('Wrong step size, try again.....') else: checkInp = False # checkInp= True # while checkInp: # print('Enter the initial starting coordinates in y as (0,500) & x as (0,500) and angle; ') # print('With origin at top left, Enter in the order of y, x, theta [separated by commas]: ') # cart= np.array(input(), dtype='f') # if(len(cart)!=3): # print 'Wrong input....Try again \nNote: Only 3 numbers needed inside the map boundaries' # else: # init= np.array([cart[0], cart[1], cart[2]], dtype='f') # if(not obsChk.notObs(init[:-1])): # print 'Start position cannot be in the obstacle.....Try again' # else: # checkInp = False checkInp = True while checkInp: print( 'Enter the goal coordinates with origin at the top left as y, x [separated by commas]: ' ) fs = np.array(input(), dtype='f') if (len(fs) != 2): print 'Wrong input....Try again \nNote: Only 2 numbers needed inside the map boundaries' else: finalState = np.array([fs[0], fs[1], 0], dtype='f') if (not obsChk.notObs(finalState[:-1])): print 'Goal position cannot be in the obstacle.....Try again' else: checkInp = False height = 500 width = 500 parentState = init parentNode = threshold_state(parentState) finalNode = threshold_state(finalState) samples2 = np.array([ parentState[:-1], finalState[:-1], [finalState[0] - 2, finalState[1] - 2], [finalState[0] + 2, finalState[1] - 2], [finalState[0] - 2, finalState[1] + 2], [finalState[0] + 2, finalState[1] + 2] ]) Voronoi.add_points(vor, samples2) Voronoi.close(vor) A = vor.vertices.copy() #(x,y) with origin at bottom left A[:, 1] = 500 - A[:, 1] isOKvert = obsChk.notObs1(A) allOKvert = A * isOKvert allOKvert = allOKvert[np.unique(np.nonzero(allOKvert)[0])] allOKvertThres = thresh(allOKvert) graph = AllNodes(height, width, 12) parentState = init parentNode = threshold_state(parentState) finalNode = threshold_state(finalState) parentCost = 0 graph.updateCost2Come(parentNode, parentCost, 0, -1, parentState, finalState, scale) parent_ownId = graph.visit(parentNode, parentState) reached = goalReached(parentNode, finalNode) found = False if (reached): found = True print('Input position is within the goal region') for i in allOKvertThres: graph.visited[i[1], i[0]] = 1 fourcc = cv2.VideoWriter_fourcc(*'XVID') if exp: vw = cv2.VideoWriter('maskVideo.avi', fourcc, 10.0, (501, 501)) vw2 = cv2.VideoWriter('visitVideo.avi', fourcc, 10.0, (501, 501)) tempImg = np.zeros([501, 501, 3], dtype='uint8') tempVisit = np.zeros([501, 501, 3], dtype='uint8') tempVisit[:, :, 1] = graph.visited * 120 tempVisit[:, :, 0] = graph.visited * 120 itr = 0 flag = 0 count = 0 step_d = 3 Rmin = tot print('Processing...Please wait') start_time = time.time() while (found != True): itr += 1 mask = FinalMap(500, 500, -1) mask.circ(Rmin, parentNode[0], parentNode[1]) finalMask = ( (mask.grid[:, :, 0] / 255) - 1 ) / 255 #dtype uint8 makes -1 value as 255 as [0,255] is only allowed explore = ((graph.visited * finalMask) == 1) * 1 if exp: tempImg[:, :, 0] = explore * 255 vw.write(tempImg) for angle in range(0, 360, 30): # Iterating for all possible angles chk = True for sd in range(1, step_d + 1): step = action(sd, angle + parentState[2]) tempState = parentState + step tempState[2] = tempState[2] - parentState[2] if (not obsChk.notObs(tempState[:-1])): chk = False break if (chk): actId = angle tempNode = threshold_state(tempState) if (explore[tempNode[0], tempNode[1]] == 1): tempCost2Come = parentCost + step_d graph.updateCost2Come(tempNode, tempCost2Come, parent_ownId, actId, tempState, finalState, scale) status, minCost, new_parentState, org_parentState = graph.minCostIdx( step_d, explore) if (status): parentState = new_parentState parentNode = threshold_state(parentState) map1.grid[parentNode[0], parentNode[1], 0] = 255 map1.grid[parentNode[0], parentNode[1], 1] = 0 map1.grid[parentNode[0], parentNode[1], 2] = 0 parentCost = graph.cost2come[parentNode[0], parentNode[1]] parent_ownId = graph.visit(parentNode, parentState) # cv2.imwrite('gridExplored.jpg',map1.grid) if exp: tempVisit[:, :, 2] = graph.visited * 120 vw2.write(tempVisit) reached = goalReached(parentState, finalState) if (reached): found = True print('Solved') break else: lenRemain = graph.removeLastState() if lenRemain: parentState = graph.getStates(-1) parentNode = threshold_state(parentState) parentCost = graph.cost2come[parentNode[0], parentNode[1]] parent_ownId = graph.getOwnId(parentNode) else: print('No solution exist, terminating....') count = 1 return actionSet, -1 if exp: vw.release() vw2.release() cv2.imwrite('gridExplored.jpg', map1.grid) plt.imshow(map1.grid) plt.show() plt.pause(0.0001) print("Time explored = %2.3f seconds " % (time.time() - start_time)) map2 = cv2.imread('gridExplored.jpg') map3 = cv2.imread('grid_init.jpg') if (not count): reached_state = graph.getStates(int(len(graph.allStates)) - 1) reached_node = threshold_state(reached_state) ans = graph.getOwnId(reached_node) print '\nYellow area shows all the obstacles and White area is the free space' print 'Blue color show all the explored Nodes (area)' print 'Red line shows optimal path (traced from start node to final node)' allNodes = [] nextState = graph.getStates(ans) nextNode = threshold_state(nextState) g_actId = graph.actDone[nextNode[0], nextNode[1]] allNodes.append(nextNode) actionSet.append(g_actId) while (ans != 0 and count == 0): startState = nextState startNode = nextNode ans = graph.getParentId(startNode) nextState = graph.getStates(ans) nextNode = threshold_state(nextState) g_actId = graph.actDone[nextNode[0], nextNode[1]] allNodes.append(nextNode) actionSet.append(g_actId) idx = len(allNodes) - 1 vw1 = cv2.VideoWriter('Vid_backTrack_on_explored.avi', fourcc, 10.0, (501, 501)) vw2 = cv2.VideoWriter('Vid_backTrack.avi', fourcc, 10.0, (501, 501)) while idx > 0: startNode = allNodes[idx] nextNode = allNodes[idx - 1] idx -= 1 cv2.line(map2, (startNode[1], startNode[0]), (nextNode[1], nextNode[0]), (0, 0, 255), 1) cv2.line(map3, (startNode[1], startNode[0]), (nextNode[1], nextNode[0]), (0, 0, 255), 1) vw1.write(map2) vw2.write(map3) vw1.release() vw2.release() plt.imshow(map2) plt.show() plt.pause(0.0001) cv2.imwrite('back_tracking_explored.jpg', map2) cv2.imwrite('back_tracking.jpg', map3) if (count == 0): actionSet.reverse() input('Path computed: ') plt.ioff() return actionSet, step_d
def natneigh(self, anisotropy=1.0, smoothie=0, plane='sn', plot=False): """ Performs Natural Neighbor (NN) interpolation with defined anisotropy to the instance's data. The algorithm assumes a brute-force way of calculating the Voronoi cells every time an unsampled point's value is computed. Kwargs: anisotropy <float> : anisotropy parameter: if >1.0, it brings points closer in the longitudinal (s) direction, if <1.0 it brings points closer in the transverse (n) direction smoothie <int> : smoothing degree (Gaussian window) plane <str> : chooses plane for interpolation; 'xy' for Cartesian, 'sn' for flow-oriented plot <boolean> : decides to plot or not the resulting NN values """ from scipy.spatial import voronoi_plot_2d import matplotlib.pyplot as plt gc.enable() print "Calculating: Natural Neighbour [NN]" nn = deepcopy(self.z) #avoid overwrite #choose plane if plane == 'sn': x = self.s * 1. / anisotropy #already flattened y = self.n #already flattened elif plane == 'xy': x = self.x.flatten() * 1. / anisotropy y = self.y.flatten() else: print "Error: Plane for interpolation not correctly specified. No interpolation performed." return #DEFINE BOUNDARY FOR INTERPOLATION #griddify points to choose boundary easier: Gx = common.to_grid(x, self.rows, self.cols) Gy = common.to_grid(y, self.rows, self.cols) bx = np.hstack((Gx[0, :], Gx[1:-1, -1], Gx[-1, :][::-1], Gx[1:-1, 0][::-1])) by = np.hstack((Gy[0, :], Gy[1:-1, -1], Gy[-1, :][::-1], Gy[1:-1, 0][::-1])) #define boundary: boundary = np.array(zip(bx, by)) #VORONOI OF SAMPLED DATA POINTS: vorpoints = np.array(zip(x[self.isdata], y[self.isdata])) #shift points around central point of the dataset (for precision purposes) center = vorpoints.mean(axis=0) vorpoints -= center #construct Voronoi diagram from (centered) sampled data points vor = Voronoi(vorpoints) vor.close() """ #TODO: delete: voronoi_plot_2d(vor) plt.ion() plt.axis('equal') plt.show() """ #calculate areas of sampled dataset Voronoi cells original_areas, vor = self.__find_areas(vor, boundary - center) """ #TODO: delete: # colorize for region in vor.regions[1:]: polygon = vor.vertices[region] plt.fill(*zip(*polygon), alpha=0.4) plt.plot(vorpoints[:,0], vorpoints[:,1], 'ko') plt.xlim(vor.min_bound[0] - 0.1, vor.max_bound[0] + 0.1) plt.ylim(vor.min_bound[1] - 0.1, vor.max_bound[1] + 0.1) plt.axis('equal') plt.ion() plt.show() """ #ITERATE THROUGH UNSAMPLED DATA POINTS: # ~ For each unsampled point, construct the new Voronoi diagram consisting of the # ~ sampled data and the current unsampled point. Then calculate the new areas and # ~ find the normalized weights based on how much of each area is "stolen away" from # ~ each sampled dataset Voronoi cell (https://en.wikipedia.org/wiki/Natural_neighbor). # ~ The areas are always bounded by the river polygon (based on the grid defined). unknown = [] for i in range(len(x[self.nodata])): if i % 1000 == 0: print i, "out of ", len(x[self.nodata]) #add new point shifted around central point varys = np.vstack((vorpoints, [ x[self.nodata][i] - center[0], y[self.nodata][i] - center[1] ])) #calculate new Voronoi pntvor = Voronoi(varys) pntvor.close() #calculate areas new_areas, pntvor = self.__find_areas(pntvor, boundary - center) new_areas = new_areas[:-1] #exclude new point's area w = new_areas / original_areas w[w > 1.0] = 1.0 #make sure that no area is larger than initial areas areaweight = 1.0 - w normalize = np.nansum(areaweight) if normalize == 0.0: #to avoid division by 0 normalize = 1e-12 areaweight /= normalize unknown.append(np.nansum(areaweight * self.z[self.isdata])) nn[self.nodata] = np.array(unknown) #grid (matrix) notation nn = common.to_grid(nn, self.rows, self.cols) #add pre-defined banks nn = self.__add_banks(nn) #smoothen for i in range(self.rows): nn[i, :] = common.smooth(nn[i, :], smoothie) print "Finished [NN]." self.z_interpol = nn del nn #plot if plot: self.plot(fignum='NN')
class Ingot: def __init__(self, hx=0, hy=0, x=[], y=[]): # размеры self.hx, self.hy = self.h = (hx, hy) # приблизительная длина стороны квадрата # в котором в среднем есть одна точка self.num=num=math.sqrt(hx*hy/len(x)) # формирую узлы с шагом num # по осям d_x=list(np.arange(-num,hx+2*num,num)) d_y=list(np.arange(-num,hy+2*num,num)) # формируем границу, с ней будет удобнее контроллировать граничные условия granica=[d_x*2+[-num]*(len(d_y)-2)+[hx+num]*(len(d_y)-2), [-num]*len(d_x)+[hy+num]*len(d_x)+d_y[1:-1]*2] # координаты всех узлов, и граничных и внутренних. Какие из них какими # будут, выяснится после построения диаграммы Вороного self.x, self.y = [list(x)+granica[0],list(y)+granica[1]] # центр слитка self.materialcentercell = self.getcellinarea((hx/2-num,hx/2+num),(hy/2-num,hy/2+num)) # количество ячеек, клеток. self.cellsnumber = cellsnumber = len(self.x) # строим диаграмму Вороного self.voron = Voronoi(np.array([self.x,self.y]).transpose()) # в этом массиве будет инофрмация о соседях для каждой клетки self.neighbours=[] # здесь будут хранится для каждой клетки расстояния до соседей self.distances_to_neighbours=[] # пока все клетки внутренние # для каждой точки 0-внутренняя, 1-граничная self.borders=[0]*cellsnumber # здесь будут храниться для каждой клетки площади поверхностей соприкосновения с соседними self.contact_surface_area=[] # для вычисления условия сходимости self.sumcontactareadevideddistance=[math.inf]*cellsnumber # полная площадь соприкосновения каждой ячейки с другим ячейками self.complete_cell_surface_area=[math.inf]*cellsnumber # площадь поверхности клетки # объем ячейки, по умолчанию -1=infinite self.volume=[-1]*cellsnumber # инициализируем массивы для списков соседей, растояний до них, и площади соприкосновения for i in range(cellsnumber): self.neighbours.append([]) self.distances_to_neighbours.append([]) self.contact_surface_area.append([]) # находим для каждой точкие его соседей for i in self.voron.ridge_points: self.neighbours[i[0]].append(i[1]) self.neighbours[i[1]].append(i[0]) # находим для каждой точки расстояния до его соседей и площади поверхностей # соприкосновения с ячейками соседей. Соседей перечисляем # согласно последовательности списка в neighbours for i in range(len(self.neighbours)): # Ищем объем ячейки, если она конечная, если бесконечная, то граница xx=[] yy=[] flag=0 # по умолчанию точка внутренняя for vert in self.voron.regions[self.voron.point_region[i]]: xx.append(self.voron.vertices[vert][0]) yy.append(self.voron.vertices[vert][1]) if vert==-1: flag=1 # значит точка граничная self.borders[i]=1 # запомним, что граничная if flag==0: self.volume[i]=PolyArea(xx,yy) self.mass[i]=self.ro()*self.volume[i] # клетка i неграничная -> считаем позже площадь поверхности # перед этим площадь math.inf переводим в 0. self.complete_cell_surface_area[i]=0 self.sumcontactareadevideddistance[i]=0 # закончили вычислять объемы (размеры) ячеек for ii in range(len(self.neighbours[i])): # ищем расстояния self.distances_to_neighbours[i].append(\ euklid_distance(\ (self.x[i],self.y[i]),\ (self.x[self.neighbours[i][ii]],self.y[self.neighbours[i][ii]])\ )) # ищем площади поверхностей (граней) касания # слабое место, поскольку свойство ridge_dict не описано в документации # но фактически есть и как раз то, что мне здесь нужно. # ridge_dict - словарь, ключь - пары соседних в диаграмме points, # значение - пары vertices вершин - концов перпендикулярного ребра temp1=(i,self.neighbours[i][ii]) temp2=(self.neighbours[i][ii],i) tmp_vertices = [] if temp1 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp1] elif temp2 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp2] if -1 in tmp_vertices: # бесконечно ли ребро self.contact_surface_area[i].append(math.inf) else: self.contact_surface_area[i].append(\ euklid_distance(\ self.voron.vertices[tmp_vertices[0]],\ self.voron.vertices[tmp_vertices[1]]\ )) self.complete_cell_surface_area[i]+=self.contact_surface_area[i][ii] self.sumcontactareadevideddistance[i]+=(self.contact_surface_area[i][ii]/self.distances_to_neighbours[i][ii]) if self.sumcontactareadevideddistance[i]==self.mass[i]==math.inf: self.sumcontactareadevideddistance[i]=math.inf else: self.sumcontactareadevideddistance[i]/=self.mass[i] self.polygons =[] # строим полигоны, которые поместим потом на рисунок self.markphase=[] # точка в центре полигона, маркер ликвидуса/солидуса # физические парметры слитка для возможного анализа self.materialmass = sum(filter(lambda x:x<math.inf,self.mass)) # фактическая масса слитка self.maxcellmass = max(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.mincellmass = min(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.materialvolume = sum(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mincellvolume = min(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.maxcellvolume = max(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mindistance=min(list(map(min,self.distances_to_neighbours))) self.maxdistance=max(list(map(max,self.distances_to_neighbours))) self.maxcellsurfacearea=max(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) self.mincellsurfacearea=min(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) suftemp=max(filter(lambda x:x<math.inf,self.sumcontactareadevideddistance)) self.sufficientstabilitycondition_dt=(self.c()/self.k(0))/suftemp # 0.97 чтобы чуточку меньше взять, чем позволено рассуждениями self.dt = 0.99 * self.sufficientstabilitycondition_dt # in seconds self.life = 0 self.CellProtocolTime=[] # здесь запоманаем возраст и температуру self.CellProtocolT =[] # какой-нибудь клетки self.voron.close() # больше точек не добавляем self.ax = [] self.pathx=[] # для рисунка полигонов self.pathy=[] # для рисунка полигонов for i in range(len(self.voron.point_region)): self.pathx.append([]) self.pathy.append([]) if self.voron.regions[self.voron.point_region[i]].count(-1)==0\ and len(self.voron.regions[self.voron.point_region[i]])>0: for ii in self.voron.regions[self.voron.point_region[i]]: self.pathx[i].append(self.voron.vertices[ii][0]) self.pathy[i].append(self.voron.vertices[ii][1]) self.flag_fig=0 # fignumber=fignumber+1 # self.fig=plt.figure(fignumber, figsize=(10,10)) self.flag_printtcircle=0 # self.flag_nexttime=0 self.flag_plotpolygon=0 self.ax_printtcircle=0 self.ax_nexttime=0 def initpolygons(self): for i in range(len(self.pathx)): self.markphase.append([]) self.polygons.append([]) if len(self.pathx[i])>0: self.polygons[i]=\ patches.Polygon(np.asarray([self.pathx[i],self.pathy[i]]).transpose(),\ color=self.colormap.to_rgba(self.T[i])) self.markphase[i]=plt.Line2D\ ([self.voron.points[i][0]],[self.voron.points[i][1]],marker=',',color='white') # self.polygons[i].set_alpha(self.alpha0) # self.flag_plotpolygon=1 # ставим флаг self.ax_nexttime=self.initfig() # инициализируем рисунок (axe) for i in range(len(self.polygons)): if self.polygons[i]!=[]: self.ax_nexttime.add_patch(self.polygons[i]) self.ax_nexttime.add_line(self.markphase[i]) # ppl.colorbar.ColorbarBase(self.ax_nexttime,cmap=self.cmap, norm=self.tcnorm) def initfig(self): # global fignumber if self.flag_fig==0: self.flag_fig=1 temp=plt.get_fignums() temp.append(0) fignumber=max(temp)+1 self.fig = plt.figure(fignumber, figsize=(10,10)) self.fig.clf() ax = self.fig.add_axes([0.05, 0.05, 0.7,0.9],axisbg='w',aspect='equal') ax.set_xlim(-self.num,hx+self.num) ax.set_ylim(-self.num,hy+self.num) axbar=self.fig.add_axes([0.8, 0.05, 0.1,0.9]) # axbar.set_xlim(0.8,0.1) # axbar.set_ylim(-self.num,hy+self.num) # mpl.colorbar.ColorbarBase(cax, cmap=cm, norm=norm, orientation='vertical') ppl.colorbar.ColorbarBase(axbar,cmap=self.cmap, norm=self.tcnorm) return(ax) def getcellinarea(self,o1,o2): for i in range(len(self.x)): if o1[0] < self.x[i] < o1[1] and o2[0] < self.y[i] < o2[1]: return(i) return(-1) def Tnext(self,cell): # Meltingpoint = MP if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() if self.borders[cell]: return(self.T[cell],self.cellphase[cell]) mass=self.mass[cell] phase=self.cellphase[cell] changephase=0 dQ=self.dt*sum( list(map( (lambda x: self.k((self.T[self.neighbours[cell][x]]+self.T[cell])/2)* self.contact_surface_area[cell][x]* (self.T[self.neighbours[cell][x]]-self.T[cell])/ self.distances_to_neighbours[cell][x]), range(len(self.neighbours[cell])) ))) TnextXX=self.T[cell]+dQ/(self.c()*mass) # если работаем без смены фаз, то выходим if self.phasechange == 0: return(TnextXX,0) # Если температура клетки ниже температуры плавления, # а её фаза сейчас ликвидус, вычислим next температуру в случае # кристаллизации if self.T[cell] < self.melting_point() and phase == 0: flag = np.random.uniform(TnextXX,TnextXX + self.mu()/self.c()) # для выбора: осуществлять ли фазовый переход if flag < self.melting_point(): changephase=1 phase = 1 # self.polygons[cell].set_alpha(self.alpha1) # self.count=self.count+1 # Если температура клетки выеше температуры плавления, # а её фаза сейчас солидус, вычислим next температуру в случае # плавления if self.T[cell] > self.melting_point() and phase == 1: flag = np.random.uniform(TnextXX - self.mu()/self.c(),TnextXX) # для выбора: осуществлять ли фазовый переход if flag > self.melting_point(): changephase=-1 phase = 0 # self.polygons[cell].set_alpha(self.alpha0) # self.count1=self.count1+1 self.cellphase[cell]=phase # возвращаем температуру и фазу return(TnextXX+changephase*self.mu()/self.c(),self.cellphase[cell]) def nexttime(self,times): self.life = self.life + self.dt for i in range(times): for cell in range(len(self.T)): self.T1[cell]=self.Tnext(cell)[0] change=self.T self.T=self.T1 self.T1=change # for cell in range(len(self.T)): # self.T[cell]=self.T1[cell] # протоколируем возраст и температуру клетки cell def writeTdown(self,cell): self.CellProtocolTime.append(self.life) self.CellProtocolT.append(self.T[cell]) # Раскрашиваем полигоны согласно температуре. Отмечаем цветом точки фазу def plotpolygon(self): if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() for cell in range(len(self.T)): if self.polygons[cell]!=[]: if self.cellphase[cell]==0: self.polygons[cell].set_color(self.colormap.to_rgba(self.T[cell])) self.markphase[cell].set_color('white') else: self.polygons[cell].set_color(self.colormap1.to_rgba(self.T[cell])) self.markphase[cell].set_color('black') # Указываем лишь только фазу def plotphase(self): if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() for cell in range(len(self.T)): if self.polygons[cell]!=[]: if self.cellphase[cell]==0: self.polygons[cell].set_color('white') else: self.polygons[cell].set_color('black') def printtcircle(self,n): if self.flag_printtcircle==0: self.flag_printtcircle=1 self.ax_printtcircle=self.initfig() temp=[] for i in range(n): for ii in range(len(self.circle)): for cell in self.neighbours[ii]: if self.circle[cell]==self.Tmax: temp.append(ii) for ii in temp: self.circle[ii]=self.Tmax # self.ax.clear() # self.ax.scatter(self.x,self.y,c=self.circle,edgecolors='None',cmap=self.cmap,marker='o',s=5) self.plotpolygon2(self.ax_printtcircle) def initT(self): for i in range(len(self.neighbours)): self.T[i]=self.Tmin for vert in self.voron.regions[self.voron.point_region[i]]: if vert==-1: self.T[i]=self.Tmax def distance_cells(self,c1,c2): return(euklid_distance((self.x[c1],self.y[c1]),(self.x[c2],self.y[c2]))) def ro(self): # [кг/м^3] плотность вещества return(7870) def c(self): # удельная теплоемкость # [Дж/(кг*К)] удельная теплоемкость return(300) def k(self,temp): # коэффициент теплопроводности # [Дж/(м*К*с)]=[Вт/(м*К)]=[кг*м^2/c^3] 50-100 if 0<=temp<=800: ktemp=((temp-0)/(800-0))*(14-60)+60 elif 800<=temp<=1520: ktemp=((temp-800)/(1520-800))*(34-14)+14 elif 1520<=temp: ktemp=35 return(ktemp) def mu(self): # теплота кристаллизации # [Дж/кг] return(220000) # сталь def melting_point(self): # [K] 1450—1520 °C для стали return(1500+273.15) def xycell(self,cell): return((self.x[cell],self.y[cell])) # находит центр масс для конечного полигона # (ячейки, клетки и т.п. синонимов) def masscenterpoints(self): xnew=[] for reg in self.voron.regions: tmp=[] if reg.count(-1)==0 and len(reg)>0: for i in reg: tmp.append(self.voron.vertices[i]) xnew.append(masscenter(tmp)) return(xnew) def plotpolygon2(self,ax): ax.clear() for i in range(len(self.pathx)): if len(self.pathx[i])>0: ax.fill(self.pathx[i], self.pathy[i], color=self.colormap.to_rgba(self.circle[i]))