diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 13a468492fb446d054a6830cf0cff3d5d34b4051..7c0cbf8f2ef703353e83ea71efde9538189e5333 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -5119,55 +5119,6 @@ DynamicModel::toNonlinearPart(DynamicModel &non_linear_equations_dynamic_model)
     non_linear_equations_dynamic_model.AddLocalVariable(it->first, it->second);
 }
 
-void
-DynamicModel::toStatic(StaticModel &static_model) const
-{
-  /* Ensure that we are using the same symbol table, because at many places we manipulate
-     symbol IDs rather than strings */
-  assert(&symbol_table == &static_model.symbol_table);
-
-  // Convert model local variables (need to be done first)
-  for (int it : local_variables_vector)
-    static_model.AddLocalVariable(it, local_variables_table.find(it)->second->toStatic(static_model));
-
-  // Convert equations
-  int static_only_index = 0;
-  for (int i = 0; i < (int) equations.size(); i++)
-    {
-      // Detect if equation is marked [dynamic]
-      bool is_dynamic_only = false;
-      vector<pair<string, string>> eq_tags;
-      for (const auto & equation_tag : equation_tags)
-        if (equation_tag.first == i)
-          {
-            eq_tags.push_back(equation_tag.second);
-            if (equation_tag.second.first == "dynamic")
-              is_dynamic_only = true;
-          }
-
-      try
-        {
-          // If yes, replace it by an equation marked [static]
-          if (is_dynamic_only)
-            {
-              static_model.addEquation(static_only_equations[static_only_index]->toStatic(static_model), static_only_equations_lineno[static_only_index], static_only_equations_equation_tags[static_only_index]);
-              static_only_index++;
-            }
-          else
-            static_model.addEquation(equations[i]->toStatic(static_model), equations_lineno[i], eq_tags);
-        }
-      catch (DataTree::DivisionByZeroException)
-        {
-          cerr << "...division by zero error encountred when converting equation " << i << " to static" << endl;
-          exit(EXIT_FAILURE);
-        }
-    }
-
-  // Convert auxiliary equations
-  for (auto aux_equation : aux_equations)
-    static_model.addAuxEquation(aux_equation->toStatic(static_model));
-}
-
 bool
 DynamicModel::ParamUsedWithLeadLag() const
 {
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index cad78c579a0c72a0542d56ff897397e174b61d0f..9e1b553a10172c6ca689435794f13410929e3105 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -39,7 +39,7 @@ private:
   constexpr static double zero_band{1e-8};
 
   //! Stores equations declared as [static]
-  /*! They will be used in toStatic() to replace equations marked as [dynamic] */
+  /*! They will be used in the conversion to StaticModel to replace equations marked as [dynamic] */
   vector<BinaryOpNode *> static_only_equations;
 
   //! Stores line numbers of equations declared as [static]
@@ -363,11 +363,6 @@ public:
   //! Writes file containing parameters derivatives
   void writeParamsDerivativesFile(const string &basename, bool julia) const;
 
-  //! Converts to static model (only the equations)
-  /*! It assumes that the static model given in argument has just been allocated */
-  void toStatic(StaticModel &static_model) const;
-
-  
   //! Converts to nonlinear model (only the equations)
   /*! It assumes that the nonlinear model given in argument has just been allocated */
   void toNonlinearPart(DynamicModel &non_linear_equations_dynamic_model) const;
@@ -473,6 +468,8 @@ public:
   //! Fills eval context with values of model local variables and auxiliary variables
   void fillEvalContext(eval_context_t &eval_context) const;
 
+  auto getStaticOnlyEquationsInfo() const { return make_tuple(static_only_equations, static_only_equations_lineno, static_only_equations_equation_tags); };
+
   //! Return the number of blocks
   unsigned int
   getNbBlocks() const override
diff --git a/src/ModFile.cc b/src/ModFile.cc
index dc6a48411ef20ecfe5e2c0a6e6bad02edde7a944..1a36ca6853f193da1303fd4b489c35984b36d17f 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -693,7 +693,7 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
         trend_dynamic_model.runTrendTest(global_eval_context);
 
       // Compute static model and its derivatives
-      dynamic_model.toStatic(static_model);
+      static_model = static_cast<StaticModel>(dynamic_model);
 	  if (linear_decomposition)
         {
           non_linear_equations_dynamic_model = dynamic_model;
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 83fb76352368133fd06767825e02363a65a7bb87..3a4a2f6987dd2c51d2204d47eb20d6f0da093cd9 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -28,6 +28,7 @@
 #include <boost/filesystem.hpp>
 
 #include "StaticModel.hh"
+#include "DynamicModel.hh"
 
 void
 StaticModel::copyHelper(const StaticModel &m)
@@ -163,6 +164,59 @@ StaticModel::operator=(const StaticModel &m)
   return *this;
 }
 
+StaticModel::StaticModel(const DynamicModel &m) :
+  ModelTree {m.symbol_table, m.num_constants, m.external_functions_table}
+{
+  // Convert model local variables (need to be done first)
+  for (int it : m.local_variables_vector)
+    AddLocalVariable(it, m.local_variables_table.find(it)->second->toStatic(*this));
+
+  // Convert equations
+  int static_only_index = 0;
+  for (int i = 0; i < static_cast<int>(m.equations.size()); i++)
+    {
+      // Detect if equation is marked [dynamic]
+      bool is_dynamic_only = false;
+      vector<pair<string, string>> eq_tags;
+      for (const auto & equation_tag : equation_tags)
+        if (equation_tag.first == i)
+          {
+            eq_tags.push_back(equation_tag.second);
+            if (equation_tag.second.first == "dynamic")
+              is_dynamic_only = true;
+          }
+
+      try
+        {
+          // If yes, replace it by an equation marked [static]
+          if (is_dynamic_only)
+            {
+              auto tuple = m.getStaticOnlyEquationsInfo();
+              auto static_only_equations = get<0>(tuple);
+              auto static_only_equations_lineno = get<1>(tuple);
+              auto static_only_equations_equation_tags = get<2>(tuple);
+
+              // With C++17, rather use structured bindings, as:
+              //auto [ static_only_equations, static_only_equations_lineno, static_only_equations_equation_tags ] = m.getStaticOnlyEquationsInfo();
+
+              addEquation(static_only_equations[static_only_index]->toStatic(*this), static_only_equations_lineno[static_only_index], static_only_equations_equation_tags[static_only_index]);
+              static_only_index++;
+            }
+          else
+            addEquation(m.equations[i]->toStatic(*this), m.equations_lineno[i], eq_tags);
+        }
+      catch (DataTree::DivisionByZeroException)
+        {
+          cerr << "...division by zero error encountred when converting equation " << i << " to static" << endl;
+          exit(EXIT_FAILURE);
+        }
+    }
+
+  // Convert auxiliary equations
+  for (auto aux_eq : m.aux_equations)
+    addAuxEquation(aux_eq->toStatic(*this));
+}
+
 void
 StaticModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, map_idx_t &map_idx, temporary_terms_t temporary_terms) const
 {
diff --git a/src/StaticModel.hh b/src/StaticModel.hh
index 300d3dad50b2a583d3716dae42a129af477763a7..b7d6aba30c0f17802de89c5af121a7e51b3cde34 100644
--- a/src/StaticModel.hh
+++ b/src/StaticModel.hh
@@ -26,6 +26,8 @@ using namespace std;
 
 #include "ModelTree.hh"
 
+class DynamicModel;
+
 //! Stores a static model, as derived from the "model" block when leads and lags have been removed
 class StaticModel : public ModelTree
 {
@@ -172,7 +174,15 @@ public:
   StaticModel(const StaticModel &m);
   StaticModel(StaticModel &&) = delete;
   StaticModel & operator=(const StaticModel &m);
-  StaticModel & operator=(StaticModel &&) = delete;
+  /* The move assignment operator is not explicitly deleted, otherwise the
+    static_cast from DynamicModel does not work. However it looks like this
+    operator will not be used in the end. See
+    https://en.cppreference.com/w/cpp/language/copy_initialization
+    With C++17, it should be possible to explicitly delete it */
+  //StaticModel & operator=(StaticModel &&) = delete;
+
+  //! Creates the static version of a dynamic model
+  explicit StaticModel(const DynamicModel &m);
 
   //! Writes information on block decomposition when relevant
   void writeOutput(ostream &output, bool block) const;