diff --git a/src/aevol_modify.cpp b/src/aevol_modify.cpp
index ae1fe162e9e62729678dd50e0f148180fa69d7e4..1247561ceb616c5f4723a21980958ce472d0fd2b 100644
--- a/src/aevol_modify.cpp
+++ b/src/aevol_modify.cpp
@@ -25,6 +25,12 @@
 // ****************************************************************************
 
 
+#include "AeTime.h"
+#include "DnaMutator.h"
+#include "Individual_7.h"
+#include "MutationParams.h"
+#include "ae_enums.h"
+#include "legacy/population/Individual.h"
 const char* DEFAULT_PARAM_FILE_NAME = "param.in";
 
 // ============================================================================
@@ -34,6 +40,7 @@ const char* DEFAULT_PARAM_FILE_NAME = "param.in";
 #include <cstdio>
 #include <cstring>
 #include <fstream>
+#include <filesystem>
 
 #include <getopt.h>
 
@@ -234,11 +241,203 @@ int main(int argc, char* argv[]) {
       exp_manager->output_m()->set_big_backup_step(atol(line->words[1]));
     }
     else if (strcmp(line->words[0], "POPULATION_SIZE") == 0) {
-      printf("ERROR in param file \"%s\" on line %" PRId32
-      ": the change of population size is not implemented yet\n"
-      " for spatially structured populations",
-          param_file_name, cur_line);
-      exit(EXIT_FAILURE);
+      if (exp_manager->sel()->selection_scope() != aevol::SCOPE_GLOBAL) {
+        Utils::ExitWithDevMsg("changes of population size supports only (for now) global selection scope", param_file_name, cur_line);
+      }
+
+      if (line->nb_words < 2) {
+        Utils::ExitWithDevMsg("population size parameter is missing.", param_file_name, cur_line);
+      } else if (line->nb_words < 3) {
+        Utils::ExitWithDevMsg("sampling type parameter is missing.", param_file_name, cur_line);
+      } 
+	  
+      bool custom_name = false;
+      if (line->nb_words == 4) {
+        if (strncmp(line->words[3], "custom", 6)) {
+          custom_name = true;
+        }
+      }
+
+      if (strncmp(line->words[2], "with", 4) != 0 && strncmp(line->words[2], "no", 2) != 0) {
+        std::string error_msg("unknown sampling type \"");
+        error_msg += line->words[2];
+        error_msg += "\".";
+        Utils::ExitWithUsrMsg(error_msg);
+      }
+
+      int32_t new_pop_size = atoi(line->words[1]);
+      if (floor(sqrt((double)new_pop_size)) != ceil(sqrt((double)new_pop_size))) {
+        Utils::ExitWithUsrMsg("Population size should be a perfect square.");
+      }
+
+      std::string population_changes_filename("population_changes");
+      if (custom_name) {
+        population_changes_filename += "_";
+        population_changes_filename += AeTime::time();
+      }
+      population_changes_filename += ".csv";
+
+      std::filesystem::path population_changes_path(population_changes_filename);
+      if (std::filesystem::exists(population_changes_path)) {
+        std::string error_msg("'");
+        error_msg += population_changes_path;
+        error_msg += "' already exists.";
+        Utils::ExitWithUsrMsg(error_msg);
+      }
+
+      bool with_selection = strncmp(line->words[2], "no", 2) != 0;
+
+      grid_width_ = (int)sqrt((double)new_pop_size);
+      grid_height_ = grid_width_;
+
+      World *old_world = exp_manager->non_const_world();
+      int32_t old_pop_size = old_world->width() * old_world->height();
+
+      World *new_world = new World();
+      new_world->set_prng(old_world->non_const_prng());
+      new_world->set_mut_prng(old_world->non_const_mut_prng());
+      new_world->set_stoch_prng(old_world->non_const_stoch_prng());
+      new_world->InitGrid(grid_width_, grid_height_, old_world->grid(0, 0)->habitat_non_const(), true);
+
+      for (int32_t x = 0; x < grid_width_; x++) {
+        for (int32_t y = 0; y < grid_height_; y++) {
+          int32_t seed = new_world->prng()->random(1000000);
+
+          new_world->grid(x, y)->set_reprod_prng(std::make_unique<JumpingMT>(seed));
+          new_world->grid(x, y)->set_reprod_prng_simd(std::make_unique<JumpingMT>(seed));
+        }
+      }
+
+      DnaFactory *dna_factory = new DnaFactory(DnaFactory_Policy::FIRSTFIT, 32, 5000);
+      FuzzyFactory_7 *fuzzy_factory = new FuzzyFactory_7(exp_manager->exp_s()->get_fuzzy_flavor(), old_pop_size * 4, exp_manager->world()->phenotypic_target_handler()->sampling());
+
+      double *fitness_array = new double[old_pop_size];
+      double *probas = new double[old_pop_size];
+      double fitness_sum = 0.0;
+
+      for (int32_t indiv_id = 0; indiv_id < old_pop_size; indiv_id++) {
+        if (!with_selection) {
+          fitness_array[indiv_id] = 1;
+          fitness_sum += 1;
+        } else {
+          int32_t x = indiv_id % old_world->height();
+          int32_t y = indiv_id / old_world->height();
+
+          Individual *indiv = new Individual(*old_world->grid(x, y)->individual());
+          indiv->Evaluate();
+
+          fitness_array[indiv_id] = indiv->fitness();
+          fitness_sum += indiv->fitness();
+
+          delete indiv;
+        }
+      }
+
+      for (int32_t indiv_id = 0; indiv_id < old_pop_size; indiv_id++) {
+        probas[indiv_id] = fitness_array[indiv_id] / fitness_sum;
+      }
+
+      int32_t *nb_offsprings = new int32_t[old_pop_size];
+      exp_manager->world()->grid(0, 0)->reprod_prng_simd_->multinomial_drawing(nb_offsprings, probas, new_pop_size, old_pop_size);
+      
+      int64_t index = 0;
+
+      std::ofstream pop_changes;
+      pop_changes.open(population_changes_path, std::ofstream::trunc);
+      if(!pop_changes.is_open()) {
+        std::ostringstream error_msg("Couldn't open file '");
+        error_msg << population_changes_path;
+        error_msg << "'.";
+        Utils::ExitWithUsrMsg(error_msg.str());
+      }
+      pop_changes << "Generation,old_index,new_index" << std::endl;
+
+      for (int32_t indiv_id = 0; indiv_id < old_pop_size; indiv_id++) {
+        for (int32_t offspring_nb = 0; offspring_nb < nb_offsprings[indiv_id]; offspring_nb++) {
+          pop_changes << AeTime::time() << "," << indiv_id << "," << index << std::endl;
+
+          int32_t x = index % grid_height_;
+          int32_t y = index / grid_height_;
+          int32_t old_x = indiv_id % old_world->height();
+          int32_t old_y = indiv_id / old_world->height();
+
+          Individual* indiv = new Individual(old_world->indiv_at(old_x, old_y),
+                                             index,
+                                             new_world->grid(x, y)->mut_prng(),
+                                             new_world->grid(x, y)->stoch_prng());
+          new_world->PlaceIndiv(indiv, x, y, true);
+
+          index++;
+        }
+      }
+
+      pop_changes.close();
+
+      Individual_7** previous_individuals = new Individual_7*[new_pop_size];
+      DnaMutator** dna_mutator_array = new DnaMutator*[new_pop_size];
+
+      for (int32_t indiv_id = 0; indiv_id < std::min(old_pop_size, new_pop_size); ++indiv_id) {
+        previous_individuals[indiv_id] = exp_manager->exp_m_7_->previous_individuals[indiv_id];
+        dna_mutator_array[indiv_id]    = exp_manager->dna_mutator_array_[indiv_id];
+      }
+
+      for (int32_t indiv_id = old_pop_size; indiv_id < new_pop_size; ++indiv_id) {
+        Individual_7* indiv = new Individual_7(previous_individuals[0]->w_max_, dna_factory, fuzzy_factory);
+        indiv->dna_         = dna_factory->get_dna(old_world->grid(0, 0)->individual()->genetic_unit_seq_length(0));
+        indiv->dna_->set_indiv(old_world->grid(0, 0)->individual()->genetic_unit(0).dna(), dna_factory);
+        indiv->dna_->set_indiv(indiv);
+        indiv->parent_id = 0;
+
+        dna_mutator_array[indiv_id] = new DnaMutator(old_world->grid(0, 0)->mut_prng(),
+                                                     indiv->dna_->length(),
+                                                     exp_s->mut_params()->duplication_rate(),
+                                                     exp_s->mut_params()->deletion_rate(),
+                                                     exp_s->mut_params()->translocation_rate(),
+                                                     exp_s->mut_params()->inversion_rate(),
+                                                     exp_s->mut_params()->point_mutation_rate(),
+                                                     exp_s->mut_params()->small_insertion_rate(),
+                                                     exp_s->mut_params()->small_deletion_rate(),
+                                                     exp_s->mut_params()->max_indel_size(),
+                                                     exp_s->min_genome_length(),
+                                                     exp_s->max_genome_length(),
+                                                     indiv_id,
+                                                     0,
+                                                     0);
+
+        previous_individuals[indiv_id] = indiv;
+      }
+
+      for (int32_t indiv_id = new_pop_size; indiv_id < old_pop_size; indiv_id++) {
+        delete exp_manager->exp_m_7_->previous_individuals[indiv_id];
+        exp_manager->exp_m_7_->previous_individuals[indiv_id] = nullptr;
+
+        delete exp_manager->dna_mutator_array_[indiv_id];
+      }
+
+      delete[] exp_manager->exp_m_7_->previous_individuals;
+      delete[] exp_manager->dna_mutator_array_;
+      exp_manager->exp_m_7_->previous_individuals = previous_individuals;
+      exp_manager->dna_mutator_array_ = dna_mutator_array;
+
+      delete[] nb_offsprings;
+      delete[] fitness_array;
+      delete[] probas;
+
+      new_world->update_best();
+      exp_manager->set_world(new_world);
+
+      delete old_world;
+
+      std::ofstream log_file;
+	    log_file.open("aevol_modify.log", std::ofstream::app);
+      log_file  << "Change of population size at generation " << AeTime::time() << " : "
+                << "from " << old_pop_size << " to " << new_pop_size << " "
+                << (with_selection ? "with" : "without")
+                << " selection." << std::endl;
+      log_file.close();
+
+      exp_manager->output_m()->init_tree(exp_manager,exp_manager->output_m()->tree()->tree_step());
+      tree = exp_manager->tree();
     }
     else if (strcmp(line->words[0], "SELECTION_SCHEME") == 0) {
       if (strncmp(line->words[1], "lin", 3) == 0) {