C ---------------------------------------------------------------------- INTEGER FUNCTION LINK_LINKUPDATE(io,sim,net,act,veh,i) C ---------------------------------------------------------------------- C - Updates the state variables (# veh, avg speed, etc) of link i C - based on the changes which occured during the previous timestep C - INCLUDED FILES: #include "dyna.inc" #include "io.inc" #include "sim.inc" #include "network.inc" #include "activity.inc" #include "vehicle.inc" C - UNMODIFIED ARGUMENTS: RECORD /Io_Data/ io RECORD /Sim_Data/ sim RECORD /Activity/ act RECORD /Vehicle_Data/ veh(NU_VE) INTEGER i ! link number being updated C - MODIFIED ARGUMENTS: RECORD /Road_Network/ net C - MODIFIED GLOBAL DATA: ! NONE C - LOCAL VARIABLES: INTEGER kj REAL length INTEGER ictmp,tmpnode REAL vtmp(NU_LI),ctmp(NU_LI) INTEGER j,k C - FUNCTIONS CALLED: ! NONE C - RETURN VALUE: ! Simulation status C ---------------------------------------------------------------------- IF(net.link(i).nenaflg.EQ.1) + net.link(i).nenac1 = net.link(i).nenac1 + 1 C --- HERE WE COUNT THE VEHICLES ON THE LINK, THOSE IN THE ENDQ, AND C --- THOSE IN THE GENERATION QUEUE. THIS RECOUNTING SEEMS C --- INEFFICIENT. WE SHOULD BE GENERATE THIS DATA DURING LINK PASSES 1 C --- & 2 net.link(i).volume = 0 c - get the number of vehicles on each links kj = net.link(i).on_link.first DO WHILE(kj.NE.NULLP) net.link(i).volume = net.link(i).volume + 1 kj = veh(kj).nextveh ENDDO net.link(i).vehicle_queue = 0 kj = net.link(i).on_endq.first DO WHILE(kj.NE.NULLP) net.link(i).vehicle_queue = net.link(i).vehicle_queue + 1 kj = veh(kj).nextveh ENDDO C - Get the number of vehicles in the link entry queue kj = net.link(i).on_genq.first DO WHILE(kj.NE.NULLP) net.link(i).entry_queue = net.link(i).entry_queue + 1 kj = veh(kj).nextveh ENDDO net.link(i).intoo = 0 C ********************************************************************** C ********************************************************************** C CALCULATE THE CONCENTRATION AND VELOCITY AT THE END OF **** C THE INTERVAL. **** C c Jay used the whole volume to calculate the concentration c -- The calculation will be performed in two ways : c -- 1. In the simulation, we use the total number of vehicles c -- to calculate the concentration and velocity. c -- 2. For short term prediction, we provide some current information c -- for the left-turn K-shortest path algorithms c -- This includes two parts : moving and queueing, moving part will c -- only consider the portion of moving vehicles to calculate c -- the concentration. C ********************************************************************** C ********************************************************************** net.link(i).iflag = 0 ctmp(i) = 0.0 vtmp(i) = 0.0 net.link(i).conc = (net.link(i).npar*MTNUM)/net.link(i).xl c -- !!! Be careful, XL(I) is not the length c -- !!! XL(i) : the total length of link i c -- xl(i) = nlanes(i)*s(i) length = net.link(i).xl-(net.link(i).vehicle_queue + * AVGVEHLEN/(5280)) if (length.lt.0.001) length = 0.0001 ctmp(i) = + (net.link(i).volume-net.link(i).vehicle_queue) * MTNUM + / length ictmp = 0 IF (net.link(i).conc.GE.net.link(i).cmax) net.link(i).iflag = 1 IF (net.link(i).conc.GT.DENSMAX) net.link(i).conc = DENSMAX IF (ctmp(i).GE.net.link(i).cmax) ictmp = 1 IF (ctmp(i).GT.DENSMAX) ctmp(i) = DENSMAX IF (net.link(i).iflag.EQ.1) THEN net.link(i).speed = EPS ELSE net.link(i).speed = (net.link(i).vmax-EPS) + * ((1.0-net.link(i).conc/net.link(i).cmax)**net.link(i).p) + + EPS ENDIF IF (ictmp.EQ.1) THEN vtmp(i) = EPS ELSE vtmp(i) = + (net.link(i).vmax-EPS) * ((1.0-ctmp(i) + / net.link(i).cmax)**net.link(i).p)+EPS ENDIF length = net.link(i).length - + REAL(net.link(i).vehicle_queue*AVGVEHLEN) + / (net.link(i).nlanes*5280.0) CR: - THIS NEXT STATEMENT IS REQUIRED FOR SHARED SIM EXIT LINKS. IF CR: - IT IS OMITTED AND THE EXIT LINK BACKS UP, WE CAN END UP WITH CR: - NEGATIVE LENGTH CAUSING NEGATIVE TRAVEL TIME WHICH MESSES UP CR: - THE SHORTEST PATH CALC. if (length.lt.0.001) length = 0.001 tmpnode = net.link(i).idnod net.link(i).statmpt = 0.0 c -- preapre the travel time along link to backstr(link,2) net.spd.bsd.backstr2( + net.link(i).backindex) = + length/vtmp(i) IF (net.spd.bsd.backstr2(net.link(i).backindex).LT.0) THEN CALL DYNA_ERROR( + 'ERROR: SHRT PATH LINK COST < 0!!!'// + 'ERROR: (PROBABLY TOO MANY VEH ON LINK)!!!'// + CHAR(0) + ,DYNA_FATAL_ERROR + ,DYNA_OPERATIONS_BUG) ENDIF net.link(i).statmpt=length/vtmp(i) CALL POST_LINK_HOOKS(io,sim,net,i) LINK_LINKUPDATE = sim.status RETURN END