Exemplo n.º 1
0
 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
Exemplo n.º 2
0
    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