def run_point(self, points, ticks=None, force_no_debug=False, envelop=False): """This function calculate concenrations at ONE given point. Note that point is real position, NOT grid index.""" bOutput = lambda : ((not envelop) and (not ticks is None) and (tick in ticks)) or ((ticks is None or envelop) and (tick % OUTSTEP == 0)) tick = 0 output_tick = [] dest = dict(zip(points, tuple([dict() for i in range(len(points))]))) while tick * TIMESTEP < DURATION: #判断烟团释放过程是否结束 if tick < len(self.release): #表示此刻有无烟团释放 if self.release[tick] > 0: #加入烟团list self.smoke_list.append(smoke_def(self.release[tick], self.met, tick, pos=(0.0, 0.0, self.src_height))) if bOutput(): if __debug__ and (not force_no_debug): print "current time-tick is %d" % tick map(smoke_def.walk, self.smoke_list) if bOutput(): diffc = []; mass = []; stab = []; pos = []; #In point mode, we just record all smokes down here and calculated for smoke in filter(lambda x:not x.invalid, self.smoke_list): pos += list(smoke.pos) #计算扩散系数 diffc += list(smoke.diffusion_coefficents(int(smoke.curr_met[3]), smoke.walkinglength, smoke.windspeed)) mass.append(smoke.mass) for point in points: if mass: X,Y,Z = point PI = math.pi POSX, POSY, POSZ = numpy.array(pos[0::3]).astype(numpy.float32), numpy.array(pos[1::3]).astype(numpy.float32), numpy.array(pos[2::3]).astype(numpy.float32) DIFFX, DIFFZ = numpy.array(diffc[0::2]).astype(numpy.float32), numpy.array(diffc[1::2]).astype(numpy.float32) MASS = numpy.array(mass).astype(numpy.float32) temp_conc = numexpr.evaluate("sum(MASS / ((2*PI)**1.5*DIFFX*DIFFX*DIFFZ) * exp(-0.5*((X-POSX)/DIFFX)**2) * exp(-0.5*((Y-POSY)/DIFFX)**2) * (exp(-0.5*((Z-POSZ)/DIFFZ)**2) + exp(-0.5*((Z+POSZ)/DIFFZ)**2)))") dest[point][tick] = temp_conc else: dest[point][tick] = 0 tick += 1 return dest
def run_core_contour(self, receipter_height=1, envelop=False, ticks=None, loc=[], force_no_debug=False): """ Three modes are defined in core_contour funtion: 1 contour mode [default] -> compute contours every tick 2 given time mode [set ticks parameter] -> only compute contours at given ticks 3 envelop mode [set envelop=True and give LOCs] -> override Mode 1 and 2, compute contours in Mode 1 and generate envelops based on given LOCs """ #计算包络线覆盖区域 make_envelop = lambda r, loc: numexpr("sum(where(r>loc,1,0),0)") #判断当前时刻是否需要计算浓度 bOutput = lambda : ((not envelop) and (not ticks is None) and (tick in ticks)) or ((ticks is None or envelop) and (tick % OUTSTEP == 0)) #是否使用GPU计算 bUseGPU = not cuda_disabled self.isRunning = True result_list = [] output_tick = [] tick = 0 #Total Estimation Time is DURATION seconds while tick * TIMESTEP < DURATION: #烟团释放过程未结束并且此刻烟团质量大于0则加入烟团列表 if tick < len(self.release) and self.release[tick] > 0: self.smoke_list.append(smoke_def(self.release[tick], self.met, tick, pos=(0.0, 0.0, self.src_height))) #追踪当前每个烟团的位置,并且计算浓度场 if filter(lambda x:not x.invalid, self.smoke_list): map(smoke_def.walk, self.smoke_list) if bOutput(): empty_conc_matrix = numpy.zeros_like(CentralPositionMatrixX) gdiffc = []; gmass = []; gpos = []; for smoke in filter(lambda x:not x.invalid, self.smoke_list): #if we use cpu, we compute each concentration field inside the loop if not bUseGPU: X, Y, Z = smoke.pos mass = smoke.mass #计算扩散系数 diffc = smoke.diffusion_coefficents(int(smoke.curr_met[3]), smoke.walkinglength, smoke.windspeed) x, z = diffc; y = x PI = math.pi height = receipter_height empty_conc_matrix = numexpr.evaluate("empty_conc_matrix + (mass/((2*PI)**1.5*x*y*z)*exp(-0.5*((CentralPositionMatrixX-X)/x)**2)*exp(-0.5*((CentralPositionMatrixY-Y)/y)**2)*(exp(-0.5*((Z-height)/z)**2) + exp(-0.5*((Z+height)/z)**2)))") #otherwise, we just record each smoke and submit them to gpu once for all. else: gpos += list(smoke.pos) #计算扩散系数 gdiffc += list(smoke.diffusion_coefficents(int(smoke.curr_met[3]), smoke.walkinglength, smoke.windspeed)) gmass.append(smoke.mass) #Submit job to kernel. if bUseGPU and len(gmass) > 0: dest = run_gpu_conc(pos=numpy.array(gpos).astype(numpy.float32), diffc=numpy.array(gdiffc).astype(numpy.float32), mass=numpy.array(gmass).astype(numpy.float32), height=receipter_height, GRID_WIDTH=GRID_SIZE, gridw=GRID_INTERVAL, smoke_count=len(gmass)) empty_conc_matrix = dest.reshape((GRID_SIZE,GRID_SIZE), order='C') result_list.append(empty_conc_matrix) output_tick.append(tick) self.cpulog.debug("current time-tick is %d" % tick) tick += 1 #Post process: return envelops or fields if envelop: envelop_list = [] for l in loc: envelop_list.append(make_envelop(result_list, l)) final_result = dict(zip(loc, envelop_list)) else: final_result = dict(zip(output_tick, result_list)) self.isRunning = False return final_result