21 package org.matsim.core.mobsim.qsim.qnetsimengine;
23 import org.apache.log4j.Logger;
50 import javax.inject.Inject;
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.List;
58 import java.util.concurrent.ExecutionException;
59 import java.util.concurrent.ExecutorService;
60 import java.util.concurrent.Executors;
61 import java.util.concurrent.Future;
62 import java.util.concurrent.Phaser;
63 import java.util.concurrent.ThreadFactory;
149 switch(vehicleBehavior) {
157 dpHandler =
new VehicularDepartureHandler(
this, vehicleBehavior, qSimConfigGroup);
160 log.info(
"Seepage is allowed. Seep mode(s) is(are) " + qSimConfigGroup.
getSeepModes() +
".");
162 log.warn(
"Seep mode(s) " + qSimConfigGroup.
getSeepModes() +
" does not take storage space thus only considered for flow capacities.");
166 if (netsimNetworkFactory != null){
184 if (this.vehicles.put(veh.
getId(), (
QVehicle) veh) != null) {
187 log.warn(
"existing vehicle in mobsim was just overwritten by other vehicle with same ID. Not clear what this means. Continuing anyways ...") ;
193 throw new RuntimeException(
"requested link with id=" + startLinkId +
" does not exist in network. Possible vehicles " 194 +
"or activities or facilities are registered to a different network.") ;
201 switch(snapshotStyle) {
203 return new QueueAgentSnapshotInfoBuilder(scenario, linkWidthCalculator);
205 case withHolesAndShowHoles:
208 return new QueueAgentSnapshotInfoBuilder(scenario, linkWidthCalculator);
210 log.warn(
"The snapshotStyle \"" + snapshotStyle +
"\" is not explicitly supported. Using \""+
SnapshotStyle.
withHoles+
"\" instead.");
211 return new QueueAgentSnapshotInfoBuilder(scenario, linkWidthCalculator);
213 return new EquiDistAgentSnapshotInfoBuilder(scenario, linkWidthCalculator);
215 log.warn(
"The snapshotStyle \"" + snapshotStyle +
"\" is not supported. Using equiDist");
216 return new EquiDistAgentSnapshotInfoBuilder(scenario, linkWidthCalculator);
239 for (QNetsimEngineRunner engine : this.engines) {
243 if (this.usingThreadpool) {
244 this.pool.shutdown();
251 this.startBarrier.arriveAndAwaitAdvance();
260 link.clearVehicles();
272 this.printSimLog(time);
285 private void run(
double time) {
311 for (QNetsimEngineRunner engine : this.engines) {
312 engine.setTime(time);
315 if (this.usingThreadpool) {
317 for (QNetsimEngineRunner engine : this.engines) {
318 engine.setMovingNodes(
true);
320 for (Future<Boolean> future : pool.invokeAll(
this.engines)) {
323 for (QNetsimEngineRunner engine : this.engines) {
324 engine.setMovingNodes(
false);
326 for (Future<Boolean> future : pool.invokeAll(
this.engines)) {
329 }
catch (InterruptedException e) {
331 }
catch (ExecutionException e) {
335 this.startBarrier.arriveAndAwaitAdvance();
336 this.endBarrier.arriveAndAwaitAdvance();
341 void printSimLog(
double time) {
342 if (time >= this.infoTime) {
346 log.info(
"SIMULATION (QNetsimEngine) AT " +
Time.
writeTime(time)
347 +
" : #links=" + nofActiveLinks
348 +
" #nodes=" + nofActiveNodes);
356 for (QNetsimEngineRunner engine : this.engines) {
357 numLinks = numLinks + engine.getNumberOfSimulatedLinks();
367 for (QNetsimEngineRunner engine : this.engines) {
368 numNodes = numNodes + engine.getNumberOfSimulatedNodes();
388 return Collections.unmodifiableMap(this.vehicles);
393 if (linkId != null) {
396 throw new RuntimeException(
"netsim link lookup failed; agentId=" + planAgent.
getId() +
"; linkId=" + linkId ) ;
403 if (linkId == null) {
422 this.engines =
new ArrayList<>();
424 this.startBarrier =
new Phaser(this.numOfThreads + 1);
425 Phaser separationBarrier =
new Phaser(this.numOfThreads);
426 this.endBarrier =
new Phaser(this.numOfThreads + 1);
429 if (this.usingThreadpool) {
433 this.pool = Executors.newFixedThreadPool(
440 QNetsimEngineRunner engine ;
441 if (this.usingThreadpool) {
442 engine =
new QNetsimEngineRunner();
444 engine =
new QNetsimEngineRunner(this.startBarrier, separationBarrier, endBarrier);
446 thread.setName(
"QNetsimEngineRunner_" + i);
447 thread.setDaemon(
true);
450 this.engines.add(engine);
475 if( node instanceof AbstractQNode){
476 ((AbstractQNode) node).setNetElementActivationRegistry(this.engines.get(i));
481 for (
Link outLink : node.getNode().getOutLinks().values()) {
482 AbstractQLink qLink = (AbstractQLink) network.
getNetsimLink(outLink.getId());
486 qLink.setNetElementActivationRegistry(this.engines.get(i));
492 if (linksToActivateInitially.remove(qLink)
494 this.engines.get(i).registerLinkAsActive(qLink);
505 for (
int i = 0; i < this.engines.size(); i++) {
506 log.info(
"Assigned " + nodes[i] +
" nodes and " + links[i] +
" links to QSimEngineRunner #" + i);
509 this.linksToActivateInitially.clear();
515 if (printRunTimesPerTimeStep) log.info(
"detailed QNetsimEngineRunner run times per time step:");
517 StringBuffer sb =
new StringBuffer();
520 for (
int i = 0; i < this.engines.size(); i++) {
522 sb.append(
"thread_");
523 sb.append(Integer.toString(i));
529 if (printRunTimesPerTimeStep) log.info(sb.toString());
535 StringBuffer sb =
new StringBuffer();
537 long min = Long.MAX_VALUE;
538 long max = Long.MIN_VALUE;
539 for (QNetsimEngineRunner runner : this.engines) {
540 long runTime = runner.runTimes[i];
542 if (runTime < min) min = runTime;
543 if (runTime > max) max = runTime;
545 sb.append(Long.toString(runTime));
548 sb.append(Long.toString(min));
550 sb.append(Long.toString(max));
551 if (printRunTimesPerTimeStep) log.info(sb.toString());
555 log.info(
"sum min run times: " + sumMin);
556 log.info(
"sum max run times: " + sumMax);
557 log.info(
"sum all run times / num threads: " + sum / this.numOfThreads);
561 private int count = 0;
565 return new Thread( r ,
"QNetsimEngine_PooledThread_" + count++);
final VehicularDepartureHandler dpHandler
void initialize(QNetsimEngine simEngine, AgentCounter agentCounter, MobsimTimer simTimer)
static final int INFO_PERIOD
final Map< Id< Vehicle >, QVehicle > getVehicles()
static final String ONLYONCE
static boolean analyzeRunTimes
final double getSimStartTime()
void letVehicleArrive(QVehicle veh)
Thread newThread(Runnable r)
int getNumberOfSimulatedLinks()
boolean isSeepModeStorageFree
void initializeFactory(AgentCounter agentCounter, MobsimTimer mobsimTimer, NetsimInternalInterface netsimEngine1)
final void arrangeNextAgentState(MobsimAgent pp)
QLinkI getNetsimLink(final Id< Link > id)
Map< Id< Link >, QLinkI > getNetsimLinks()
void addParkedVehicle(MobsimVehicle vehicle)
MobsimAgent unregisterAdditionalAgentOnLink(Id< Person > mobsimAgentId)
QNetsimEngine(final QSim sim)
void doSimStep(final double time)
int getNumberOfSimulatedNodes()
LinkDynamics getLinkDynamics()
void setDriver(DriverAgent driver)
void arrangeNextAgentState(MobsimAgent agent)
void initQSimEngineThreads()
void registerAdditionalAgentOnLink(MobsimAgent planAgent)
QNetwork getNetsimNetwork()
Map< Id< Node >, QNodeI > getNetsimNodes()
Id< Link > getCurrentLinkId()
MobsimTimer getSimTimer()
void processEvent(final Event event)
void assignNetElementActivators()
final void registerAdditionalAgentOnLink(final MobsimAgent planAgent)
StarttimeInterpretation getSimStarttimeInterpretation()
VehicleBehavior getVehicleBehavior()
QNetsimEngine(final QSim sim, QNetworkFactory netsimNetworkFactory)
List< QNetsimEngineRunner > engines
InternalInterface internalInterface
final boolean usingThreadpool
void endLegAndComputeNextState(final double now)
Collection< String > getSeepModes()
SnapshotStyle getSnapshotStyle()
VehicularDepartureHandler getDepartureHandler()
static final String writeTime(final double seconds, final String timeformat)
MobsimAgent unregisterAdditionalAgentOnLink(Id< Person > agentId, Id< Link > linkId)
EventsManager getEventsManager()
static boolean printRunTimesPerTimeStep
void letVehicleArrive(QVehicle veh)
AgentCounter getAgentCounter()
MobsimDriverAgent getDriver()
void arrangeNextAgentState(MobsimAgent pp)
static int numObservedTimeSteps
void setInternalInterface(InternalInterface internalInterface)
void addParkedVehicle(MobsimVehicle veh, Id< Link > startLinkId)
boolean isUsingThreadpool()
final Set< QLinkI > linksToActivateInitially
NetsimNetwork getNetsimNetwork()
final Map< Id< Vehicle >, QVehicle > vehicles
void printEngineRunTimes()