diff --git a/Simulation.cpp b/Simulation.cpp
index fe6d6fd2f314490662f20886df93e3c352ea1bad..f4979881d4780e193b2d291ab6014db96ece296e 100644
--- a/Simulation.cpp
+++ b/Simulation.cpp
@@ -420,6 +420,7 @@ void Simulation::RunHeader(long nPed)
 
     //first initialisation needed by the linked-cells
     UpdateRoutesAndLocations();
+    _routingEngine.get()->PrepareForSimulation(_building.get());
     ProcessAgentsQueue();
 }
 
diff --git a/routing/CognitiveMapRouter.cpp b/routing/CognitiveMapRouter.cpp
index 3c187876b422c2e41b54fc41888221a7d980450a..de68b0c0a5bea9d5a32dd15ee1d2e09ceedc4551 100644
--- a/routing/CognitiveMapRouter.cpp
+++ b/routing/CognitiveMapRouter.cpp
@@ -165,6 +165,7 @@ bool CognitiveMapRouter::Init(Building * b)
      return true;
 }
 
+virtual void CognitiveMapRouter::PrepareForSimulation(Building *b) {}
 
 const optStorage &CognitiveMapRouter::getOptions() const
 {
diff --git a/routing/CognitiveMapRouter.h b/routing/CognitiveMapRouter.h
index dc4a029430fc743c85ed69a2f434d185106b2fc5..942f28cf8dadb27ae93e63f399993cee18528cce 100644
--- a/routing/CognitiveMapRouter.h
+++ b/routing/CognitiveMapRouter.h
@@ -60,6 +60,7 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
+     virtual void PrepareForSimulation(Building* b);
 
      /**
       * @return options involved in the routing algorithm
diff --git a/routing/DummyRouter.cpp b/routing/DummyRouter.cpp
index 183136c76defbef42aa5e1be649fa84a5efd5425..fa37059ee2cd4ed6a92665e03db2dc897464be25 100644
--- a/routing/DummyRouter.cpp
+++ b/routing/DummyRouter.cpp
@@ -75,4 +75,4 @@ bool DummyRouter::Init(Building* b)
      return true;
 }
 
-
+virtual void DummyRouter::PrepareForSimulation(Building* b) {}
diff --git a/routing/DummyRouter.h b/routing/DummyRouter.h
index 407d54962491d35b16979748e6272edc006f6c8c..1e5767afb013f9ccd99c7518479e23469b66cc2f 100644
--- a/routing/DummyRouter.h
+++ b/routing/DummyRouter.h
@@ -44,6 +44,7 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
+     virtual void PrepareForSimulation(Building* b);
 
 };
 
diff --git a/routing/GlobalRouter.cpp b/routing/GlobalRouter.cpp
index 9f23e04705cdf81ea9f096928a22543a9268b87c..ebdd53de752377bfa5edc218d879addafe1757c6 100644
--- a/routing/GlobalRouter.cpp
+++ b/routing/GlobalRouter.cpp
@@ -547,6 +547,8 @@ void GlobalRouter::Reset(){
      _mapIdToFinalDestination.clear();
 }
 
+virtual void GlobalRouter::PrepareForSimulation(Building* b) {}
+
 void GlobalRouter::SetEdgeCost(double cost)
 {
      _edgeCost=cost;
diff --git a/routing/GlobalRouter.h b/routing/GlobalRouter.h
index f2c9f9f65694c276a028b1e2788dbe7838d47b1b..0109283a2704a1832fd78774ee1242b3904e228f 100644
--- a/routing/GlobalRouter.h
+++ b/routing/GlobalRouter.h
@@ -65,6 +65,8 @@ public:
 
      virtual bool Init(Building* building);
 
+     virtual void PrepareForSimulation(Building* b);
+
      virtual int FindExit(Pedestrian* p);
 
      /**
diff --git a/routing/MeshRouter.cpp b/routing/MeshRouter.cpp
index ac6efd9bdfa8400be3ce91538e9067bdc345ced0..fcb31cb975d6660eeb9da127848042decbf7e82d 100644
--- a/routing/MeshRouter.cpp
+++ b/routing/MeshRouter.cpp
@@ -968,6 +968,8 @@ bool MeshRouter::Init(Building* b)
      return true;
 }
 
+virtual void MeshRouter::PrepareForSimulation(Building* b) {}
+
 void MeshRouter::WriteMeshToFile(const string& filename)
 {
     // in the case the navigation mesh should be written to a file
diff --git a/routing/MeshRouter.h b/routing/MeshRouter.h
index 18ff19c1298a211344be0194e949d845919fd03d..c83f3e083b6278aad50e5002d1d14401a7ffc830 100644
--- a/routing/MeshRouter.h
+++ b/routing/MeshRouter.h
@@ -53,6 +53,7 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
+     virtual void PrepareForSimulation(Building* b);
 
 };
 
diff --git a/routing/Router.h b/routing/Router.h
index 23667eec9ecd39992c6cfb5c48e3fd26fce05eab..53a2c26dd0986ef8d74f086527598ae211b5e2e5 100644
--- a/routing/Router.h
+++ b/routing/Router.h
@@ -133,6 +133,13 @@ public:
       */
      virtual bool ParseAdditionalParameters(){return true;};
 
+     /**
+      * Each implementation can do some pre-simulation calculation. When calling this
+      * function, the exit route for each pedestrian (present at the beginning of the
+      * simulation) is already known.
+      */
+     virtual void PrepareForSimulation(Building* b) = 0;
+
 };
 
 #endif  /* _ROUTING_H */
diff --git a/routing/RoutingEngine.cpp b/routing/RoutingEngine.cpp
index 43059e14812f9e2de00fd8e95b5e6ee48d92dbbe..38768f57e8f9107e82c99c5d200d1ba6f7ec2415 100644
--- a/routing/RoutingEngine.cpp
+++ b/routing/RoutingEngine.cpp
@@ -124,3 +124,9 @@ bool RoutingEngine::Init(Building* building)
      }
      return status;
 }
+
+void RoutingEngine::PrepareForSimulation(Building *building) {
+     for (auto router: _routersCollection) {
+          router->PrepareForSimulation(building);
+     }
+}
diff --git a/routing/RoutingEngine.h b/routing/RoutingEngine.h
index 64760f3d866d3f6a1b4abd19ab1a053938248963..bf81f74b015acb1f5281f2e828bf2aedd24d937d 100644
--- a/routing/RoutingEngine.h
+++ b/routing/RoutingEngine.h
@@ -106,6 +106,12 @@ public:
       */
      bool Init(Building* building);
 
+     /**
+      * Allow the routers to do some preparation
+      * @param building
+      */
+     void PrepareForSimulation(Building* building);
+
 private:
      /// collections of all routers used
      std::vector<Router*> _routersCollection;
diff --git a/routing/ffRouter.cpp b/routing/ffRouter.cpp
index 624f453367dfaf7b9589d041eccf1d7cf2b2476c..f7bba3e31bd7d848d0dbbff1c9f1993c6699335e 100644
--- a/routing/ffRouter.cpp
+++ b/routing/ffRouter.cpp
@@ -338,6 +338,7 @@ bool FFRouter::Init(Building* building)
           matrixfile << _CroTrByUID.at(_pathsMatrix[mapItem.first])->GetID() << std::endl;
      }
      matrixfile.close();
+
      Log->Write("INFO: \tFF Router Init done.");
      return true;
 }
@@ -561,6 +562,10 @@ bool FFRouter::ReInit()
      return true;
 }
 
+virtual void FFRouter::PrepareForSimulation(Building* building) {
+     // collect all <room, door> pairs needed
+     // calculate the ff in a parallelized way
+}
 
 int FFRouter::FindExit(Pedestrian* p)
 {
diff --git a/routing/ffRouter.h b/routing/ffRouter.h
index 33d37d435a9c8ba60897ec8f5caa5fbb6b3856f2..e7d70bdf0d8ad620d6f2c16acd264d510d9e86ae 100644
--- a/routing/ffRouter.h
+++ b/routing/ffRouter.h
@@ -153,6 +153,14 @@ public:
       */
      virtual bool ReInit();
 
+     /*!
+      * \brief Calculates some needed floorfields
+      *
+      * PrepareForSimulation() will look up the exit route of each pedestrian (which is not yet
+      * known in Init()) and calculate the floorfields needed for these routes.
+      */
+     virtual void PrepareForSimulation(Building* building);
+
      /*!
       * \brief interface used by __Pedestrian__, sets (*p).exitline/.exitindex
       *