diff --git a/Cell2Fire/Cell2Fire.cpp b/Cell2Fire/Cell2Fire.cpp index 68a6b8a2..3ea1dae2 100644 --- a/Cell2Fire/Cell2Fire.cpp +++ b/Cell2Fire/Cell2Fire.cpp @@ -511,6 +511,29 @@ Cell2Fire::Cell2Fire(arguments _args) : CSVForest(_args.InFolder + "fuels", " ") } } + /* Active front: read a set of cells to ignite simultaneously (ActiveFront.csv) */ + if (this->args.ActiveFront) + { + std::string sepAF = ","; + std::string activeFile = args.InFolder + "ActiveFront.csv"; + CSVReader CSVActive(activeFile, sepAF); + std::vector> ActiveDF = CSVActive.getData(activeFile); + this->ActiveFrontCells.clear(); + for (size_t rr = 1; rr < ActiveDF.size(); ++rr) // skip header row + { + if (ActiveDF[rr].size() >= 2 && !ActiveDF[rr][1].empty()) + this->ActiveFrontCells.push_back(std::stoi(ActiveDF[rr][1])); + } + if (!this->ActiveFrontCells.empty()) + { + this->args.TotalYears = 1; // the front is a single scenario + this->IgnitionPoints = std::vector(1, this->ActiveFrontCells[0]); + this->IgnitionSets = std::vector>(1); + std::cout << "Active front: " << this->ActiveFrontCells.size() + << " seed cells will ignite simultaneously" << std::endl; + } + } + /* BBO Tuning factors (only the ones present in the instances*/ if (this->args.BBOTuning) { @@ -1051,6 +1074,46 @@ Cell2Fire::RunIgnition(boost::random::mt19937 generator, int ep) } } + // --- Active front: ignite all remaining seed cells simultaneously --- + if (this->args.ActiveFront) + { + bool anyAF = false; + for (size_t k = 0; k < this->ActiveFrontCells.size(); ++k) + { + int fc = this->ActiveFrontCells[k]; + if (fc < 1 || fc > this->nCells) + continue; + if (this->burntCells.find(fc) != this->burntCells.end()) // already lit (e.g. first cell) + { + anyAF = true; + continue; + } + if (this->statusCells[fc - 1] >= 3) // non-burnable / harvested / firebreak + continue; + if (this->Cells_Obj.find(fc) == this->Cells_Obj.end()) + InitCell(fc); + std::unordered_map::iterator itf = this->Cells_Obj.find(fc); + if (itf->second.getStatus() != "Available" || itf->second.fType == 0) + continue; + std::vector ipf = { fc }; + if (itf->second.ignition(this->fire_period[this->year - 1], + this->year, ipf, &df[fc - 1], + this->coef_ptr, this->args_ptr, + &(this->wdf[this->weatherPeriod]), + this->activeCrown, this->perimeterCells)) + { + this->statusCells[fc - 1] = 1; + this->nIgnitions++; + this->burningCells.insert(fc); + this->burntCells.insert(fc); + this->availCells.erase(fc); + anyAF = true; + } + } + if (anyAF) + this->noIgnition = false; + } + // Plotter placeholder if (this->args.OutputGrids) { diff --git a/Cell2Fire/Cell2Fire.h b/Cell2Fire/Cell2Fire.h index fecd1d84..c1ab7175 100644 --- a/Cell2Fire/Cell2Fire.h +++ b/Cell2Fire/Cell2Fire.h @@ -103,6 +103,7 @@ class Cell2Fire std::vector fTypeCells2; // (long int&, const char [9]); std::vector> WeatherData; std::vector IgnitionPoints; + std::vector ActiveFrontCells; // seed cells of an active front vector burnedOutList; std::vector FSCell; std::vector crownMetrics; diff --git a/Cell2Fire/ReadArgs.cpp b/Cell2Fire/ReadArgs.cpp index 184da890..90dab6b0 100644 --- a/Cell2Fire/ReadArgs.cpp +++ b/Cell2Fire/ReadArgs.cpp @@ -110,6 +110,7 @@ parseArgs(int argc, char* argv[], arguments* args_ptr) bool verbose_input = false; bool iplog_input = false; bool input_ignitions = false; + bool active_front = false; bool out_grids = false; bool out_fl = false; bool out_intensity = false; @@ -201,6 +202,14 @@ parseArgs(int argc, char* argv[], arguments* args_ptr) printf("Ignitions: %s \n", btoa(input_ignitions)); } + //--active-front (ignite a set of cells simultaneously, read from ActiveFront.csv) + if (cmdOptionExists(argv, argv + argc, "--active-front")) + { + active_front = true; + input_ignitions = true; // active front uses the ignition-from-file path + printf("Active front: %s \n", btoa(active_front)); + } + //--grids if (cmdOptionExists(argv, argv + argc, "--grids")) { @@ -607,6 +616,7 @@ parseArgs(int argc, char* argv[], arguments* args_ptr) args_ptr->verbose = verbose_input; args_ptr->IgnitionsLog = iplog_input; args_ptr->Ignitions = input_ignitions; + args_ptr->ActiveFront = active_front; args_ptr->OutputGrids = out_grids; args_ptr->FinalGrid = out_finalgrid; args_ptr->PromTuned = prom_tuned; diff --git a/Cell2Fire/ReadArgs.h b/Cell2Fire/ReadArgs.h index 00a824aa..6038e9f2 100644 --- a/Cell2Fire/ReadArgs.h +++ b/Cell2Fire/ReadArgs.h @@ -16,7 +16,7 @@ typedef struct { std::string InFolder, OutFolder, WeatherOpt, HarvestPlan, Simulator, WeatherWeightsFile; bool OutMessages, OutFl, OutIntensity, OutRos, OutCrown, OutCrownConsumption, OutSurfConsumption, Trajectories, - NoOutput, verbose, IgnitionsLog, Ignitions, OutputGrids, FinalGrid, PromTuned, Stats, BBOTuning, AllowCROS, UseWeatherWeights; + NoOutput, verbose, IgnitionsLog, Ignitions, OutputGrids, FinalGrid, PromTuned, Stats, BBOTuning, AllowCROS, UseWeatherWeights, ActiveFront; float ROSCV, ROSThreshold, CROSThreshold, HFIThreshold, HFactor, FFactor, BFactor, EFactor, FirePeriodLen; float CBDFactor, CCFFactor, ROS10Factor, CROSActThreshold; int MinutesPerWP, MaxFirePeriods, TotalYears, TotalSims, NWeatherFiles, IgnitionRadius, seed, nthreads, FMC,