From e5c615c76e40e4ed1f4cb8666694e159783ad896 Mon Sep 17 00:00:00 2001 From: fdo Date: Tue, 14 Jan 2025 15:18:37 -0300 Subject: [PATCH] Clang format modern (#103) * clang-format * black like changes to .clang-format * binpack argument .clang format * Include cell header in fbp model --------- Co-authored-by: mati --- .clang-format | 191 ++ CODING.md | 28 + Cell2Fire/Cell2Fire.cpp | 3912 +++++++++++++++------------ Cell2Fire/Cell2Fire.h | 238 +- Cell2Fire/Cells.cpp | 2306 ++++++++-------- Cell2Fire/Cells.h | 282 +- Cell2Fire/DataGenerator.cpp | 731 +++-- Cell2Fire/DataGenerator.h | 53 +- Cell2Fire/Ellipse.cpp | 280 +- Cell2Fire/Ellipse.h | 27 +- Cell2Fire/Forest.cpp | 60 +- Cell2Fire/Forest.h | 55 +- Cell2Fire/FuelModelFBP.cpp | 1942 ++++++++------ Cell2Fire/FuelModelFBP.h | 91 +- Cell2Fire/FuelModelKitral.cpp | 626 +++-- Cell2Fire/FuelModelKitral.h | 66 +- Cell2Fire/FuelModelSpain.cpp | 4769 +++++++++++++++++---------------- Cell2Fire/FuelModelSpain.h | 71 +- Cell2Fire/Lightning.cpp | 48 +- Cell2Fire/Lightning.h | 24 +- Cell2Fire/ReadArgs.cpp | 1168 ++++---- Cell2Fire/ReadArgs.h | 35 +- Cell2Fire/ReadCSV.cpp | 1283 +++++---- Cell2Fire/ReadCSV.h | 128 +- Cell2Fire/Spotting.cpp | 203 +- Cell2Fire/Spotting.h | 22 +- Cell2Fire/WriteCSV.cpp | 515 ++-- Cell2Fire/WriteCSV.h | 73 +- 28 files changed, 10490 insertions(+), 8737 deletions(-) create mode 100644 .clang-format create mode 100644 CODING.md diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..9a8fbaa0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,191 @@ +--- +Language: Cpp +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: All +AlwaysBreakAfterReturnType: AllDefinitions +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Allman +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: 'Google' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: false + AfterForeachMacros: false + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: false + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: 1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Cpp11 +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/CODING.md b/CODING.md new file mode 100644 index 00000000..9a14304c --- /dev/null +++ b/CODING.md @@ -0,0 +1,28 @@ +# Coding practices + +https://clang.llvm.org/docs/ClangFormat.html + +Details at `clang-format` [documentation](https://clang.llvm.org/docs/ClangFormat.html) + +# setup clang-format +```bash +sudo apt-get install clang-format +clang-format -style=gnu -dump-config > .clang-format +``` + +## setup clang-format for vim using ALE plugin +Add the following configuration to your `.vimrc` +```bash +" Enable ALE +let g:ale_linters = { +\ 'cpp': ['clang-format'], +\} + +" Automatically fix files on save +let g:ale_fix_on_save = 1 + +" Specify the fixer to use for C++ +let g:ale_fixers = { +\ 'cpp': ['clang-format'], +\} +``` diff --git a/Cell2Fire/Cell2Fire.cpp b/Cell2Fire/Cell2Fire.cpp index 710abf0c..285fc158 100644 --- a/Cell2Fire/Cell2Fire.cpp +++ b/Cell2Fire/Cell2Fire.cpp @@ -3,497 +3,563 @@ __version__ = "3.0" __author__ = "Cristobal Pais" __maintainer__ = "Jaime Carrasco, Cristobal Pais, David Woodruff, David Palacios" */ -//Unified version by David Palacios -// Include classes +// Unified version by David Palacios +// Include classes #include "Cell2Fire.h" #include "Cells.h" -#include "Spotting.h" -#include "FuelModelSpain.h" +#include "DataGenerator.h" #include "FuelModelKitral.h" +#include "FuelModelSpain.h" +#include "Lightning.h" +#include "ReadArgs.h" #include "ReadCSV.h" +#include "Spotting.h" #include "WriteCSV.h" -#include "ReadArgs.h" -#include "Lightning.h" -#include "DataGenerator.h" // Include libraries +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include +#include #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include - +#include using namespace std; // Global Variables (DFs with cells and weather info) -inputs * df_ptr; -weatherDF * wdf_ptr; -weatherDF wdf[100000]; //hard to dynamic allocate memory since it changes from file to file, better to keep constant size; -inputs * df; +inputs* df_ptr; +weatherDF* wdf_ptr; +weatherDF wdf[100000]; // hard to dynamic allocate memory since it changes from + // file to file, better to keep constant size; +inputs* df; int currentSim = 0; std::unordered_map> BBOFactors; -std::unordered_map> HarvestedCells; +std::unordered_map> HarvestedCells; std::vector NFTypesCells; -std::unordered_map IgnitionHistory; +std::unordered_map IgnitionHistory; /****************************************************************************** - Utils + Utils *******************************************************************************/ /** * * */ -void printSets(std::unordered_set availCells, std::unordered_set nonBurnableCells, - std::unordered_set burningCells, std::unordered_set burntCells, std::unordered_set harvestCells) +void +printSets(std::unordered_set availCells, + std::unordered_set nonBurnableCells, + std::unordered_set burningCells, + std::unordered_set burntCells, + std::unordered_set harvestCells) { - std::cout << "\nSet information period" << std::endl; - std::cout << "Available Cells:"; - for (auto & ac : availCells){ - std::cout << " " << ac; - } - std::cout << std::endl; - - std::cout << "nonBurnable Cells:"; - for (auto & nbc : nonBurnableCells){ - std::cout << " " << nbc; - } - std::cout << std::endl; - - std::cout << "Burning Cells:"; - for (auto & bc : burningCells){ - std::cout << " " << bc; - } - std::cout << std::endl; - - std::cout << "Burnt Cells:"; - for (auto & bc : burntCells){ - std::cout << " " << bc; - } - std::cout << std::endl; - - - std::cout << "Firebreak Cells:"; - for (auto & hc : harvestCells){ - std::cout << " " << hc; - } - std::cout << std::endl; + std::cout << "\nSet information period" << std::endl; + std::cout << "Available Cells:"; + for (auto& ac : availCells) + { + std::cout << " " << ac; + } + std::cout << std::endl; + + std::cout << "nonBurnable Cells:"; + for (auto& nbc : nonBurnableCells) + { + std::cout << " " << nbc; + } + std::cout << std::endl; + + std::cout << "Burning Cells:"; + for (auto& bc : burningCells) + { + std::cout << " " << bc; + } + std::cout << std::endl; + + std::cout << "Burnt Cells:"; + for (auto& bc : burntCells) + { + std::cout << " " << bc; + } + std::cout << std::endl; + + std::cout << "Firebreak Cells:"; + for (auto& hc : harvestCells) + { + std::cout << " " << hc; + } + std::cout << std::endl; } // Output grids -void CSVGrid(int rows, int cols, int gridNumber, std::string gridFolder, std::vector & statusCellsCSV, bool verbose){ - std::string gridName; - if (gridNumber < 10){ - gridName = gridFolder+ "ForestGrid0" + std::to_string(gridNumber) + ".csv"; - } - - else { - gridName = gridFolder+ "ForestGrid" + std::to_string(gridNumber) + ".csv"; - } - - if(verbose){ - std::cout << "We are plotting the current forest to a csv file " << gridName << std::endl; - } - CSVWriter CSVPloter(gridName, ","); - CSVPloter.printCSV_V2(rows, cols, statusCellsCSV); +void +CSVGrid(int rows, int cols, int gridNumber, std::string gridFolder, std::vector& statusCellsCSV, bool verbose) +{ + std::string gridName; + if (gridNumber < 10) + { + gridName = gridFolder + "ForestGrid0" + std::to_string(gridNumber) + ".csv"; + } + + else + { + gridName = gridFolder + "ForestGrid" + std::to_string(gridNumber) + ".csv"; + } + + if (verbose) + { + std::cout << "We are plotting the current forest to a csv file " << gridName << std::endl; + } + CSVWriter CSVPloter(gridName, ","); + CSVPloter.printCSV_V2(rows, cols, statusCellsCSV); } -inline char separator() +inline char +separator() { #if defined _WIN32 || defined __CYGWIN__ - return '\\'; + return '\\'; #else - return '/'; + return '/'; #endif } - - /****************************************************************************** - Constructor + Constructor *******************************************************************************/ /** * @brief Constructs and initializes the Cell2Fire object to run a simulation. * - * This constructor initializes the `Cell2Fire` object by reading configuration and data files - * required for simulating fire spread in a forested environment. It populates various member variables, - * including fuel coefficients, forest structure, weather data, ignition points, and other - * simulation-related parameters. It also performs preprocessing steps to categorize cells - * into burnable and non-burnable types and to establish fire ignition sets. + * This constructor initializes the `Cell2Fire` object by reading configuration + * and data files required for simulating fire spread in a forested + * environment. It populates various member variables, including fuel + * coefficients, forest structure, weather data, ignition points, and other + * simulation-related parameters. It also performs preprocessing steps to + * categorize cells into burnable and non-burnable types and to establish fire + * ignition sets. * - * @param _args List of command line arguments containing configuration and file paths needed for the simulation. + * @param _args List of command line arguments containing configuration and + * file paths needed for the simulation. * * @return A fully initialized `Cell2Fire` object ready for simulation. * * ### Notes: * - Initializes forest data from the `fuels` data and `Data.csv` files. - * - Initializes weather data from `Weather.csv` and optionally `WeatherDistribution.csv`. - * - Processes ignition points from `Ignitions.csv` (if provided) and computes adjacent cells based on the ignition radius. - * - Categorizes cells as burnable, non-burnable, or harvested based on input data. + * - Initializes weather data from `Weather.csv` and optionally + * `WeatherDistribution.csv`. + * - Processes ignition points from `Ignitions.csv` (if provided) and computes + * adjacent cells based on the ignition radius. + * - Categorizes cells as burnable, non-burnable, or harvested based on input + * data. * - If BBO tuning is enabled, initializes tuning factors using `BBOFuels.csv`. - * - Validates and adjusts simulation parameters based on the weather file consistency. + * - Validates and adjusts simulation parameters based on the weather file + * consistency. */ -Cell2Fire::Cell2Fire(arguments _args) : CSVWeather(_args.InFolder + "Weather.csv", ","), - CSVForest(_args.InFolder + "fuels", " ") - { - // Aux - int i; - +Cell2Fire::Cell2Fire(arguments _args) + : CSVWeather(_args.InFolder + "Weather.csv", ","), CSVForest(_args.InFolder + "fuels", " ") +{ + // Aux + int i; + // Populate arguments from command line into the Cell2Fire object - this->args = _args; - this->args_ptr = &this->args; - - /******************************************************************** - * - * Initialization steps - * - ********************************************************************/ - //DEBUGstd::cout << "------------------ Simulator C++ Beta version ----------------------\n" << std::endl; - /* - Command line arguments (all of them inside args structure) - */ - //DEBUGstd::cout << "------ Command line values ------\n"; - //DEBUGprintArgs(this->args); - - /******************************************************************** - Initialize fuel coefficients for Spread Model - ********************************************************************/ - // fuel_coefs coefs[18]; - this->coef_ptr = &this->coefs[0]; - - /******************************************************************** - Global Values (Forest) and Instance (in memory for the moment) - ********************************************************************/ - //DEBUGstd::cout << "\n------ Instance from file initialization ------\n"; - this->sim = 1; - /******************************************************************** - Read Instance from csv files... - ********************************************************************/ - // Create forest structure - forestDF frdf; - //DEBUG - std::cout << "------------------Forest Data ----------------------\n" << std::endl; - std::vector> FDF = this->CSVForest.getData(); - //DEBUGthis->CSVForest.printData(FDF); - this->CSVForest.parseForestDF(&frdf, FDF); - - //DEBUGstd::cout << "------------------Detailed Data ----------------------\n" << std::endl; - this->rows = frdf.rows; - this->cols = frdf.cols; - this->widthSims=std::to_string(this->args.TotalSims).length(); - this->nCells = rows * cols; - this->cellSide = frdf.cellside; - this->areaCells= cellSide * cellSide; - this->perimeterCells = 4 * cellSide; - this->xllcorner = frdf.xllcorner; - this->yllcorner = frdf.yllcorner; - - this->coordCells = frdf.coordCells; - //this->adjCells = frdf.adjCells; - - /******************************************************************** - Dataframes initialization: Forest and Weather - ********************************************************************/ - //DEBUGstd::cout << "\n------ Read DataFrames: Forest and Weather ------\n"; - - /* Forest DataFrame */ - std::string filename = this->args.InFolder + "Data.csv"; - std::string sep = ","; - CSVReader CSVParser(filename, sep); - - // Populate DF - std::vector> DF = CSVParser.getData(); - std::cout << "Forest DataFrame from instance " << filename << std::endl; - //DEBUGCSVParser.printData(DF); - std::cout << "Number of cells: " << this->nCells << std::endl; - df = new inputs[this->nCells]; - - // Create empty df with size of NCells - df_ptr = & df[0]; //access reference for the first element of df - - // Populate the df [nCells] objects - CSVParser.parseDF(df_ptr, DF,this->args_ptr, this->nCells); //iterates from the first element of df, using DF, args_ptr and the number of cells - - // Initialize and populate relevant vectors - this->fTypeCells = std::vector (this->nCells, 1); - this->fTypeCells2 = std::vector (this->nCells, "Burnable"); - this->statusCells = std::vector (this->nCells, 0); - //Outputs - this->crownState = std::vector (this->nCells, 0); - this->crownFraction = std::vector (this->nCells, 0); - this->surfFraction = std::vector (this->nCells, 0); - this->Intensities = std::vector (this->nCells, 0); - this->RateOfSpreads = std::vector (this->nCells, 0); - this->FlameLengths = std::vector (this->nCells, 0); - - this->ignProb = std::vector(this->nCells, 1); - CSVParser.parsePROB(this->ignProb, DF, this->nCells); - - // Non burnable types: populate relevant fields such as status and ftype - std::string NoFuel = "NF "; - std::string NoData = "ND "; - std::string Empty = ""; - const char * NF = NoFuel.c_str(); - const char * ND = NoData.c_str(); - const char * EM = Empty.c_str(); - - for(int l=0; l< this->nCells; l++){ - if (strcmp(df[l].fueltype,NF) == 0 || strcmp(df[l].fueltype, ND) == 0) { - this->fTypeCells[l] = 0; - this->fTypeCells2[l] = "NonBurnable"; - this->statusCells[l] = 4; - } - } - - // Harvested cells - if(strcmp(this->args.HarvestPlan.c_str(), EM) != 0){ - std::string sep = ","; - CSVReader CSVHPlan(this->args.HarvestPlan, sep); - - // Populate Ignitions vector - std::vector> HarvestedDF = CSVHPlan.getData(); - //CSVHPlan.printData(HarvestedDF); - - // Cells - int HCellsP = HarvestedDF.size() - 1; - CSVHPlan.parseHarvestedDF(HarvestedCells, HarvestedDF, HCellsP); - - // Print-out - std::cout << "\nFirebreak Cells :" << std::endl; - for (auto it = HarvestedCells.begin(); it != HarvestedCells.end(); it++ ){ - std::cout << " " << it->first << ": "; - for (auto & it2 : it->second){ - std::cout << it2 << " "; - this->fTypeCells[it2-1] = 0; - this->fTypeCells2[it2-1] = "NonBurnable"; - this->statusCells[it2-1] = 3; - } - } - std::cout << std::endl; - } - - // Relevant sets: Initialization - this->availCells.clear(); - this->nonBurnableCells.clear(); - this->burningCells.clear(); - this->burntCells.clear(); - this->harvestCells.clear(); - for (i=0; i < this->statusCells.size(); i++){ - if(this->statusCells[i] < 3) this->availCells.insert (i+1); - else if (this->statusCells[i] == 4) this->nonBurnableCells.insert(i+1); - else if (this->statusCells[i] == 3) this->harvestCells.insert(i+1); - } - - /* Weather DataFrame */ - this->WeatherDF = this->CSVWeather.getData(); - std::cout << "\nWeather DataFrame from instance " << this->CSVWeather.fileName << std::endl; - - if (this->args.WeatherOpt.compare("distribution") == 0) { - CSVReader CSVWeatherDistribution(_args.InFolder + "WeatherDistribution.csv", ","); - this->WDist = CSVWeatherDistribution.getData(); - CSVWeatherDistribution.printData(WDist); - } - - std::vector WeatherHistory; - this->counter_wt = 0; - - // Populate WDF - int WPeriods = WeatherDF.size() - 1; // -1 due to header - wdf_ptr = &wdf[0]; - std::cout << "Weather Periods: " << WPeriods << std::endl; - - // Populate the wdf objects - this->CSVWeather.parseWeatherDF(wdf_ptr,this->args_ptr, this->WeatherDF, WPeriods); - //std::cout << "\nPass Debug " << std::endl; - //DEBUGthis->CSVWeather.printData(this->WeatherDF); - - /* Ignitions */ - int IgnitionYears; - std::vector IgnitionPoints; - - if(this->args.Ignitions){ - //DEBUGstd::cout << "\nWe have specific ignition points:" << std::endl; - - /* Ignition points */ - std::string ignitionFile = args.InFolder + "Ignitions.csv"; - std::string sep = ","; - CSVReader CSVIgnitions(ignitionFile, sep); - - // Populate Ignitions vector - std::vector> IgnitionsDF = CSVIgnitions.getData(); - //DEBUGstd::cout << "Ignition points from file " << ignitionFile << std::endl; - //DEBUGCSVIgnitions.printData(IgnitionsDF); - - // Total Years - IgnitionYears = IgnitionsDF.size() - 1; - //DEBUGstd::cout << "Ignition Years: " << IgnitionYears << std::endl; - //DEBUGstd::cout << "Total Years: " << this->args.TotalYears << std::endl; - args.TotalYears = std::min(args.TotalYears, IgnitionYears); - //DEBUGstd::cout << "Setting TotalYears to " << args.TotalYears << " for consistency with Ignitions file" << std::endl; - - // Ignition points - this->IgnitionPoints = std::vector(IgnitionYears, 0); - CSVIgnitions.parseIgnitionDF(this->IgnitionPoints, IgnitionsDF, IgnitionYears); - //this->IgnitionSets = std::vector>(this->IgnitionPoints.size()); - this->IgnitionSets = std::vector>(this->args.TotalYears); - - - // Ignition radius - if (this->args.IgnitionRadius > 0){ - // Aux - int i, a, igVal; - //std::unordered_set auxSet; - std::vector auxSet; - int auxIg = 0; - - // Debug - //for (i=0; iargs.TotalYears; i++) - // std::cout << this->IgnitionPoints[i] << std::endl; - - // Loop - for (i=0; iargs.TotalYears; i++){ - auxSet.clear(); - igVal = this->IgnitionPoints[i]; - std::vector adjacentCellsVector=adjacentCells(igVal, this->rows, this->cols); - if (this->args.IgnitionRadius == 1){ - for (auto & nb : adjacentCellsVector) { - if (nb != -1) { - //this->IgnitionSets[auxIg].insert(nb.second); - this->IgnitionSets[auxIg].push_back(nb); - } - } - //this->IgnitionSets[auxIg].insert(igVal); - this->IgnitionSets[auxIg].push_back(igVal); - } - - if (this->args.IgnitionRadius > 1){ - // Initial ignition set (first year for 1 degree) - for (auto & nb : adjacentCellsVector) { - if (nb != -1) { - //this->IgnitionSets[auxIg].insert(nb.second); - this->IgnitionSets[auxIg].push_back(nb); - } - } - int auxR = 1; - //auxSet.insert(igVal); - auxSet.push_back(igVal); - - // loop over radius of adjacents - while (auxR < args.IgnitionRadius){ - //unordered_set IgnitionSetsAux = this->IgnitionSets[auxIg]; - std::vector IgnitionSetsAux = this->IgnitionSets[auxIg]; - - for (auto & c : IgnitionSetsAux) { - // Populate Aux Set - std::vector adjacentCellsVector=adjacentCells(c, this->rows, this->cols); - for (auto & na : adjacentCellsVector) { - if (na != -1) { - //auxSet.insert(na.second); - auxSet.push_back(na); - } - } - } - // Save aux set as Ignition Set - this->IgnitionSets[auxIg] = auxSet; - auxR += 1; - } - } - // Next iteration (year) - auxIg++; - } - } - - // Clean vectors - for (auto & v : this->IgnitionSets){ - std::sort(v.begin(), v.end()); - v.erase(std::unique(v.begin(), v.end()), v.end()); - } - - // IgRadius Information - if (this->args.verbose){ - for (auto & nb : this->IgnitionSets[0]){ - std::cout << "Ignition sets[0] example:" << nb << std::endl; - } - } - } - - /* BBO Tuning factors (only the ones present in the instances*/ - if(this->args.BBOTuning){ - // Get fuel types numbers - CSVParser.parseNDF(NFTypesCells, DF, this->nCells); - - // BBO File - std::string BBOFile = args.InFolder + "BBOFuels.csv"; - std::string sep = ","; - CSVReader CSVBBO(BBOFile, sep); - - // Populate BBO vector - std::vector> BBODF = CSVBBO.getData(); - int BBONTypes = BBODF.size() - 1; - CSVBBO.parseBBODF(BBOFactors, BBODF, BBONTypes); - - // Print-out - std::cout << "BBO Factors:" << std::endl; - for (auto it = BBOFactors.begin(); it != BBOFactors.end(); it++ ){ - std::cout << " " << it->first << ": "; - for (auto & it2 : it->second){ - std::cout << it2 << " "; - } - } - std::cout << std::endl; - - } - /******************************************************************** - * - * Global Parameters for loop - * - *********************************************************************/ - // Global parameters for the loop - this->year = 1; - this->weatherPeriod = 0; - this->noIgnition = true; // None = -1 - this->activeCrown=false; - this->gridNumber = 0; - this->fire_period = vector(this->args.TotalYears, 0); - - // Check maxFirePeriods and Weather File consistency - if(this->args.WeatherOpt.compare("rows") == 0 || this->args.WeatherOpt.compare("random") == 0) { - int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; - if (this->args.MaxFirePeriods > maxFP) { - this->args.MaxFirePeriods = maxFP ; - if (this->args.verbose){ - std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods << " based on the weather file, Fire Period Length, and Minutes per WP" << std::endl; - } - } - } -} + this->args = _args; + this->args_ptr = &this->args; + + /******************************************************************** + * + * Initialization + *steps + * + ********************************************************************/ + // DEBUGstd::cout << "------------------ Simulator C++ Beta version + // ----------------------\n" << std::endl; + /* + Command line arguments (all of them inside args structure) + */ + // DEBUGstd::cout << "------ Command line values ------\n"; + // DEBUGprintArgs(this->args); + + /******************************************************************** + Initialize fuel + coefficients for Spread Model + ********************************************************************/ + // fuel_coefs coefs[18]; + this->coef_ptr = &this->coefs[0]; + + /******************************************************************** + Global Values (Forest) and Instance (in + memory for the moment) + ********************************************************************/ + // DEBUGstd::cout << "\n------ Instance from file initialization ------\n"; + this->sim = 1; + /******************************************************************** + Read Instance from csv files... + ********************************************************************/ + // Create forest structure + forestDF frdf; + // DEBUG + std::cout << "------------------Forest Data ----------------------\n" << std::endl; + std::vector> FDF = this->CSVForest.getData(); + // DEBUGthis->CSVForest.printData(FDF); + this->CSVForest.parseForestDF(&frdf, FDF); + + // DEBUGstd::cout << "------------------Detailed Data + // ----------------------\n" << std::endl; + this->rows = frdf.rows; + this->cols = frdf.cols; + this->widthSims = std::to_string(this->args.TotalSims).length(); + this->nCells = rows * cols; + this->cellSide = frdf.cellside; + this->areaCells = cellSide * cellSide; + this->perimeterCells = 4 * cellSide; + this->xllcorner = frdf.xllcorner; + this->yllcorner = frdf.yllcorner; + + this->coordCells = frdf.coordCells; + // this->adjCells = frdf.adjCells; + + /******************************************************************** + Dataframes initialization: + Forest and Weather + ********************************************************************/ + // DEBUGstd::cout << "\n------ Read DataFrames: Forest and Weather ------\n"; + + /* Forest DataFrame */ + std::string filename = this->args.InFolder + "Data.csv"; + std::string sep = ","; + CSVReader CSVParser(filename, sep); + + // Populate DF + std::vector> DF = CSVParser.getData(); + std::cout << "Forest DataFrame from instance " << filename << std::endl; + // DEBUGCSVParser.printData(DF); + std::cout << "Number of cells: " << this->nCells << std::endl; + df = new inputs[this->nCells]; + + // Create empty df with size of NCells + df_ptr = &df[0]; // access reference for the first element of df + + // Populate the df [nCells] objects + CSVParser.parseDF(df_ptr, + DF, + this->args_ptr, + this->nCells); // iterates from the first element of df, using DF, + // args_ptr and the number of cells + + // Initialize and populate relevant vectors + this->fTypeCells = std::vector(this->nCells, 1); + this->fTypeCells2 = std::vector(this->nCells, "Burnable"); + this->statusCells = std::vector(this->nCells, 0); + // Outputs + this->crownState = std::vector(this->nCells, 0); + this->crownFraction = std::vector(this->nCells, 0); + this->surfFraction = std::vector(this->nCells, 0); + this->Intensities = std::vector(this->nCells, 0); + this->RateOfSpreads = std::vector(this->nCells, 0); + this->FlameLengths = std::vector(this->nCells, 0); + + this->ignProb = std::vector(this->nCells, 1); + CSVParser.parsePROB(this->ignProb, DF, this->nCells); + + // Non burnable types: populate relevant fields such as status and ftype + std::string NoFuel = "NF "; + std::string NoData = "ND "; + std::string Empty = ""; + const char* NF = NoFuel.c_str(); + const char* ND = NoData.c_str(); + const char* EM = Empty.c_str(); + + for (int l = 0; l < this->nCells; l++) + { + if (strcmp(df[l].fueltype, NF) == 0 || strcmp(df[l].fueltype, ND) == 0) + { + this->fTypeCells[l] = 0; + this->fTypeCells2[l] = "NonBurnable"; + this->statusCells[l] = 4; + } + } + + // Harvested cells + if (strcmp(this->args.HarvestPlan.c_str(), EM) != 0) + { + std::string sep = ","; + CSVReader CSVHPlan(this->args.HarvestPlan, sep); + + // Populate Ignitions vector + std::vector> HarvestedDF = CSVHPlan.getData(); + // CSVHPlan.printData(HarvestedDF); + + // Cells + int HCellsP = HarvestedDF.size() - 1; + CSVHPlan.parseHarvestedDF(HarvestedCells, HarvestedDF, HCellsP); + + // Print-out + std::cout << "\nFirebreak Cells :" << std::endl; + for (auto it = HarvestedCells.begin(); it != HarvestedCells.end(); it++) + { + std::cout << " " << it->first << ": "; + for (auto& it2 : it->second) + { + std::cout << it2 << " "; + this->fTypeCells[it2 - 1] = 0; + this->fTypeCells2[it2 - 1] = "NonBurnable"; + this->statusCells[it2 - 1] = 3; + } + } + std::cout << std::endl; + } + // Relevant sets: Initialization + this->availCells.clear(); + this->nonBurnableCells.clear(); + this->burningCells.clear(); + this->burntCells.clear(); + this->harvestCells.clear(); + for (i = 0; i < this->statusCells.size(); i++) + { + if (this->statusCells[i] < 3) + this->availCells.insert(i + 1); + else if (this->statusCells[i] == 4) + this->nonBurnableCells.insert(i + 1); + else if (this->statusCells[i] == 3) + this->harvestCells.insert(i + 1); + } + + /* Weather DataFrame */ + this->WeatherDF = this->CSVWeather.getData(); + std::cout << "\nWeather DataFrame from instance " << this->CSVWeather.fileName << std::endl; + + if (this->args.WeatherOpt.compare("distribution") == 0) + { + CSVReader CSVWeatherDistribution(_args.InFolder + "WeatherDistribution.csv", ","); + this->WDist = CSVWeatherDistribution.getData(); + CSVWeatherDistribution.printData(WDist); + } + std::vector WeatherHistory; + this->counter_wt = 0; + + // Populate WDF + int WPeriods = WeatherDF.size() - 1; // -1 due to header + wdf_ptr = &wdf[0]; + std::cout << "Weather Periods: " << WPeriods << std::endl; + + // Populate the wdf objects + this->CSVWeather.parseWeatherDF(wdf_ptr, this->args_ptr, this->WeatherDF, WPeriods); + // std::cout << "\nPass Debug " << std::endl; + // DEBUGthis->CSVWeather.printData(this->WeatherDF); + + /* Ignitions */ + int IgnitionYears; + std::vector IgnitionPoints; + + if (this->args.Ignitions) + { + // DEBUGstd::cout << "\nWe have specific ignition points:" << std::endl; + + /* Ignition points */ + std::string ignitionFile = args.InFolder + "Ignitions.csv"; + std::string sep = ","; + CSVReader CSVIgnitions(ignitionFile, sep); + + // Populate Ignitions vector + std::vector> IgnitionsDF = CSVIgnitions.getData(); + // DEBUGstd::cout << "Ignition points from file " << ignitionFile << + // std::endl; DEBUGCSVIgnitions.printData(IgnitionsDF); + + // Total Years + IgnitionYears = IgnitionsDF.size() - 1; + // DEBUGstd::cout << "Ignition Years: " << IgnitionYears << std::endl; + // DEBUGstd::cout << "Total Years: " << this->args.TotalYears << + // std::endl; + args.TotalYears = std::min(args.TotalYears, IgnitionYears); + // DEBUGstd::cout << "Setting TotalYears to " << args.TotalYears << " for + // consistency with Ignitions file" << std::endl; + + // Ignition points + this->IgnitionPoints = std::vector(IgnitionYears, 0); + CSVIgnitions.parseIgnitionDF(this->IgnitionPoints, IgnitionsDF, IgnitionYears); + // this->IgnitionSets = + // std::vector>(this->IgnitionPoints.size()); + this->IgnitionSets = std::vector>(this->args.TotalYears); + + // Ignition radius + if (this->args.IgnitionRadius > 0) + { + // Aux + int i, a, igVal; + // std::unordered_set auxSet; + std::vector auxSet; + int auxIg = 0; + + // Debug + // for (i=0; iargs.TotalYears; i++) + // std::cout << this->IgnitionPoints[i] << std::endl; + + // Loop + for (i = 0; i < this->args.TotalYears; i++) + { + auxSet.clear(); + igVal = this->IgnitionPoints[i]; + std::vector adjacentCellsVector = adjacentCells(igVal, this->rows, this->cols); + if (this->args.IgnitionRadius == 1) + { + for (auto& nb : adjacentCellsVector) + { + if (nb != -1) + { + // this->IgnitionSets[auxIg].insert(nb.second); + this->IgnitionSets[auxIg].push_back(nb); + } + } + // this->IgnitionSets[auxIg].insert(igVal); + this->IgnitionSets[auxIg].push_back(igVal); + } + + if (this->args.IgnitionRadius > 1) + { + // Initial ignition set (first year for 1 degree) + for (auto& nb : adjacentCellsVector) + { + if (nb != -1) + { + // this->IgnitionSets[auxIg].insert(nb.second); + this->IgnitionSets[auxIg].push_back(nb); + } + } + int auxR = 1; + // auxSet.insert(igVal); + auxSet.push_back(igVal); + + // loop over radius of adjacents + while (auxR < args.IgnitionRadius) + { + // unordered_set IgnitionSetsAux = + // this->IgnitionSets[auxIg]; + std::vector IgnitionSetsAux = this->IgnitionSets[auxIg]; + + for (auto& c : IgnitionSetsAux) + { + // Populate Aux Set + std::vector adjacentCellsVector = adjacentCells(c, this->rows, this->cols); + for (auto& na : adjacentCellsVector) + { + if (na != -1) + { + // auxSet.insert(na.second); + auxSet.push_back(na); + } + } + } + // Save aux set as Ignition Set + this->IgnitionSets[auxIg] = auxSet; + auxR += 1; + } + } + // Next iteration (year) + auxIg++; + } + } + + // Clean vectors + for (auto& v : this->IgnitionSets) + { + std::sort(v.begin(), v.end()); + v.erase(std::unique(v.begin(), v.end()), v.end()); + } + + // IgRadius Information + if (this->args.verbose) + { + for (auto& nb : this->IgnitionSets[0]) + { + std::cout << "Ignition sets[0] example:" << nb << std::endl; + } + } + } + + /* BBO Tuning factors (only the ones present in the instances*/ + if (this->args.BBOTuning) + { + // Get fuel types numbers + CSVParser.parseNDF(NFTypesCells, DF, this->nCells); + + // BBO File + std::string BBOFile = args.InFolder + "BBOFuels.csv"; + std::string sep = ","; + CSVReader CSVBBO(BBOFile, sep); + + // Populate BBO vector + std::vector> BBODF = CSVBBO.getData(); + int BBONTypes = BBODF.size() - 1; + CSVBBO.parseBBODF(BBOFactors, BBODF, BBONTypes); + + // Print-out + std::cout << "BBO Factors:" << std::endl; + for (auto it = BBOFactors.begin(); it != BBOFactors.end(); it++) + { + std::cout << " " << it->first << ": "; + for (auto& it2 : it->second) + { + std::cout << it2 << " "; + } + } + std::cout << std::endl; + } + /******************************************************************** + * + * Global + *Parameters for loop + * + *********************************************************************/ + // Global parameters for the loop + this->year = 1; + this->weatherPeriod = 0; + this->noIgnition = true; // None = -1 + this->activeCrown = false; + this->gridNumber = 0; + this->fire_period = vector(this->args.TotalYears, 0); + + // Check maxFirePeriods and Weather File consistency + if (this->args.WeatherOpt.compare("rows") == 0 || this->args.WeatherOpt.compare("random") == 0) + { + int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; + if (this->args.MaxFirePeriods > maxFP) + { + this->args.MaxFirePeriods = maxFP; + if (this->args.verbose) + { + std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods + << " based on the weather file, Fire Period Length, " + "and Minutes per WP" + << std::endl; + } + } + } +} /****************************************************************************** - Methods + Methods *******************************************************************************/ /** - * @brief Initializes a cell within the simulation and adds it to the cell collection. + * @brief Initializes a cell within the simulation and adds it to the cell + * collection. * - * This method creates a `Cells` object for the specified cell ID, populates it with the necessary - * parameters, and stores it in the `Cells_Obj` unordered map. It also initializes the fire-related - * fields for the cell and, if verbose mode is enabled, prints debugging information about the cell. + * This method creates a `Cells` object for the specified cell ID, populates it + * with the necessary parameters, and stores it in the `Cells_Obj` unordered + * map. It also initializes the fire-related fields for the cell and, if + * verbose mode is enabled, prints debugging information about the cell. * * @param id The ID of the cell to initialize. * @@ -510,30 +576,39 @@ Cell2Fire::Cell2Fire(arguments _args) : CSVWeather(_args.InFolder + "Weather.csv * */ -void Cell2Fire::InitCell(int id){ - // Declare an iterator to unordered_map - std::unordered_map::iterator it2; - - // Initialize cell, insert it inside the unordered map - Cells Cell(id-1, this->areaCells, this->coordCells[id-1], this->fTypeCells[id-1], this->fTypeCells2[id-1], - this->perimeterCells, this->statusCells[id-1], id); - this->Cells_Obj.insert(std::make_pair(id, Cell)); - - // Get object from unordered map - it2 = this->Cells_Obj.find(id); - - // Initialize the fire fields for the selected cel - it2->second.initializeFireFields(this->coordCells, this->availCells,this->cols,this->rows); - - // Print info for debugging - if (this->args.verbose) it2->second.print_info(); - +void +Cell2Fire::InitCell(int id) +{ + // Declare an iterator to unordered_map + std::unordered_map::iterator it2; + + // Initialize cell, insert it inside the unordered map + Cells Cell(id - 1, + this->areaCells, + this->coordCells[id - 1], + this->fTypeCells[id - 1], + this->fTypeCells2[id - 1], + this->perimeterCells, + this->statusCells[id - 1], + id); + this->Cells_Obj.insert(std::make_pair(id, Cell)); + + // Get object from unordered map + it2 = this->Cells_Obj.find(id); + + // Initialize the fire fields for the selected cel + it2->second.initializeFireFields(this->coordCells, this->availCells, this->cols, this->rows); + + // Print info for debugging + if (this->args.verbose) + it2->second.print_info(); } /** * @brief Resets the simulation environment for a new run. * - * This method initializes and resets all relevant parameters, structures, and files needed for the simulation. It handles: + * This method initializes and resets all relevant parameters, structures, and + * files needed for the simulation. It handles: * - Global simulation parameters * - Output directories and files * - Weather configuration @@ -541,304 +616,362 @@ void Cell2Fire::InitCell(int id){ * - Data structures related to cells and fire metrics * * @param rnumber Random seed or identifier for weather selection. - * @param rnumber2 Random value for initializing ROS (Rate of Spread) variations. + * @param rnumber2 Random value for initializing ROS (Rate of Spread) + * variations. * @param simExt Simulation extension identifier (default: 1). * */ -void Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1){ - // Reset info - //DEBUGstd::cout << "--------------------- Reseting environment -----------------------" << std::endl; - - // Aux - int i; - - // Reset global parameters for the simulation - this->year = 1; - this->weatherPeriod = 0; - this->noIgnition = true; // None = -1 - this->nIgnitions = 0; - this->gridNumber = 0; - this->activeCrown=false; - this->done = false; - this->fire_period = vector(this->args.TotalYears, 0); - this->sim = simExt; - // Initial status grid folder - if(this->args.OutputGrids || this->args.FinalGrid){ - CSVWriter CSVFolder("",""); - this->gridFolder = this->args.OutFolder + "Grids" + separator(); - CSVFolder.MakeDir(this->gridFolder); - this->gridFolder = this->args.OutFolder + "Grids" + separator() + "Grids" + std::to_string(this->sim) + separator(); - CSVFolder.MakeDir(this->gridFolder); - //DEBUGstd::cout << "\nInitial Grid folder was generated in " << this->gridFolder << std::endl; - } - - // Messages Folder - if(this->args.OutMessages){ - CSVWriter CSVFolder("",""); - this->messagesFolder = this->args.OutFolder + "Messages"; - CSVFolder.MakeDir(this->messagesFolder); - this->messagesFolder = this->args.OutFolder + "Messages" + separator(); - - } - //ROS Folder - if (this->args.OutRos) { - CSVWriter CSVFolder("", ""); - this->rosFolder = this->args.OutFolder + "RateOfSpread" ; - CSVFolder.MakeDir(this->rosFolder); - this->rosFolder = this->args.OutFolder + "RateOfSpread"+separator(); - } - //Byram Intensity Folder - if (this->args.OutIntensity) { - CSVWriter CSVFolder("", ""); - this->intensityFolder = this->args.OutFolder + "Intensity" ; - CSVFolder.MakeDir(this->intensityFolder); - this->intensityFolder = this->args.OutFolder + "Intensity" + separator(); - } - //Flame Length Folder - if (this->args.OutFl) { - CSVWriter CSVFolder("", ""); - this->flFolder = this->args.OutFolder + "FlameLength" ; - CSVFolder.MakeDir(this->flFolder); - this->flFolder = this->args.OutFolder + "FlameLength"+separator(); - } - //Crown Folder - if (this->args.OutCrown && this->args.AllowCROS) { - CSVWriter CSVFolder("", ""); - this->crownFolder = this->args.OutFolder + "CrownFire" ; - CSVFolder.MakeDir(this->crownFolder); - this->crownFolder = this->args.OutFolder + "CrownFire" + separator(); - } - //Crown Fraction Burn Folder - if (this->args.OutCrownConsumption && this->args.AllowCROS) { - CSVWriter CSVFolder("", ""); - this->cfbFolder = this->args.OutFolder + "CrownFractionBurn" ; - CSVFolder.MakeDir(this->cfbFolder); - this->cfbFolder = this->args.OutFolder + separator() +"CrownFractionBurn" + separator(); - } - //Surf Fraction Burn Folder - if (this->args.OutSurfConsumption && this->args.Simulator=="C") { - CSVWriter CSVFolder("", ""); - this->sfbFolder = this->args.OutFolder + "SurfFractionBurn" ; - CSVFolder.MakeDir(this->sfbFolder); - this->sfbFolder = this->args.OutFolder + separator() +"SurfFractionBurn" + separator(); - } - - // Random Weather - /*std::cout << "Weather Option:" << this->args.WeatherOpt << std::endl; - std::cout << "Weather Option random check:" << (this->args.WeatherOpt.compare("random") == 0) << std::endl; - std::cout << "Weather Option rows check:" << (this->args.WeatherOpt.compare("rows") == 0) << std::endl; - */ - - if (this->args.WeatherOpt.compare("random") == 0) { - // Random Weather - this->CSVWeather.fileName = this->args.InFolder + "Weathers" + separator() + "Weather" + std::to_string(rnumber) + ".csv"; - - /* Weather DataFrame */ - try { - this->WeatherDF = this->CSVWeather.getData(); - } - catch (std::invalid_argument& e) { - std::cerr << e.what() << std::endl; - std::abort(); - } - std::cout << "\nWeather file selected: " << this->CSVWeather.fileName << std::endl; - - // Populate WDF - int WPeriods = this->WeatherDF.size() - 1; // -1 due to header - wdf_ptr = &wdf[0]; - std::cout << "Weather Periods: " << WPeriods << std::endl; - std::string weather_name = ""; - for (int i = this->CSVWeather.fileName.size() - 1; i >= 0; i--) { - std::string bol = std::to_string(this->CSVWeather.fileName[i]); - int bol2 = std::stoi(bol); - char check = '\\'; - int intcheck = (int)check; - if (bol2 == intcheck) { - break; - } - else { - weather_name.push_back(this->CSVWeather.fileName[i]); - } - - } - reverse(weather_name.begin(), weather_name.end()); - WeatherHistory.push_back(weather_name); - - // Populate the wdf objects - this->CSVWeather.parseWeatherDF(wdf_ptr,this->args_ptr, this->WeatherDF, WPeriods); - //DEBUGthis->CSVWeather.printData(this->WeatherDF); - - // Check maxFirePeriods and Weather File consistency (reset MaxFirePeriods and recalculate) - int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; - this->args.MaxFirePeriods = 10000000; - //DEBUGstd::cout << "Int MaxFP: " << maxFP << std::endl; - //DEBUGstd::cout << "MinutesPerWP: " << this->args.MinutesPerWP << std::endl; - //DEBUGstd::cout << "FirePeriodLen: " << this->args.FirePeriodLen << std::endl; - //DEBUGstd::cout << "MaxfirePeriods: " << this->args.MaxFirePeriods << std::endl; - if (this->args.MaxFirePeriods > maxFP) { - this->args.MaxFirePeriods = maxFP; - if (this->args.verbose) { - std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods << " based on the weather file, Fire Period Length, and Minutes per WP" << std::endl; - } - } - - } - - - if (this->args.WeatherOpt.compare("distribution") == 0) { - bool selectWeather = false; - int countCases = 0; - std::string weather_name; - while (!selectWeather) { - std::default_random_engine generator3(args.seed * simExt * time(NULL)); //creates a different generator solving cases when parallel running creates simulations at same time - std::uniform_int_distribution distribution(1, this->WDist.size() - 1); - int weather_idx = distribution(generator3); - - float rd_number = (float)rand() / ((float)(RAND_MAX / 0.999999999)); - float probability_weather = std::stof(this->WDist[weather_idx][1]); - //DEBUGstd::cout<<"prob: "<<(probability_weather)< rd_number) { //rd_number cannot be 1, but can be 0. So if prob weather has prob=0 it does not have a chance of being selected, and if it is 1, it will always be selected - weather_name = this->WDist[weather_idx][0]; - //DEBUGstd::cout << "Weather name selected: " << weather_name << std::endl; - selectWeather = true; - } - countCases++; - if (countCases > 1000) { - weather_name = this->WDist[weather_idx][0]; - selectWeather = true; - } - selectWeather = true; - } - - // Random Weather - this->CSVWeather.fileName = this->args.InFolder + "Weathers"+ separator() + weather_name + ".csv"; - WeatherHistory.push_back(weather_name); - - - /* Weather DataFrame */ - try { - this->WeatherDF = this->CSVWeather.getData(); - } - catch (std::invalid_argument& e) { - std::cerr << e.what() << std::endl; - std::abort(); - } - std::cout << "\nWeather file selected: " << this->CSVWeather.fileName << std::endl; - - // Populate WDF - int WPeriods = this->WeatherDF.size() - 1; // -1 due to header - wdf_ptr = &wdf[0]; - std::cout << "Weather Periods: " << WPeriods << std::endl; - - // Populate the wdf objects - this->CSVWeather.parseWeatherDF(wdf_ptr,this->args_ptr, this->WeatherDF, WPeriods); - //DEBUGthis->CSVWeather.printData(this->WeatherDF); - - // Check maxFirePeriods and Weather File consistency (reset MaxFirePeriods and recalculate) - int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; - this->args.MaxFirePeriods = 10000000; - //DEBUGstd::cout << "Int MaxFP: " << maxFP << std::endl; - //DEBUGstd::cout << "MinutesPerWP: " << this->args.MinutesPerWP << std::endl; - //DEBUGstd::cout << "FirePeriodLen: " << this->args.FirePeriodLen << std::endl; - //DEBUGstd::cout << "MaxfirePeriods: " << this->args.MaxFirePeriods << std::endl; - - if (this->args.MaxFirePeriods > maxFP) { - this->args.MaxFirePeriods = maxFP; - if (this->args.verbose) { - std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods << " based on the weather file, Fire Period Length, and Minutes per WP" << std::endl; - } - } - - } - // Random ROS-CV - this->ROSRV = std::abs(rnumber2); - //std::cout << "ROSRV: " << this->ROSRV << std::endl; - - // Cells dictionary - this->Cells_Obj.clear(); - - // Declare an iterator to unordered_map - std::unordered_map::iterator it; - - // Reset status - this->fTypeCells = std::vector (this->nCells, 1); - this->fTypeCells2 = std::vector (this->nCells, "Burnable"); - this->statusCells = std::vector (this->nCells, 0); - this->crownState = std::vector (this->nCells, 0); - this->crownFraction = std::vector (this->nCells, 0); - this->surfFraction = std::vector (this->nCells, 0); - this->Intensities = std::vector (this->nCells, 0); - this->RateOfSpreads = std::vector (this->nCells, 0); - this->FlameLengths = std::vector (this->nCells, 0); - - this->FSCell.clear(); - this->crownMetrics.clear();//intensity and crown - - // Non burnable types: populate relevant fields such as status and ftype - std::string NoFuel = "NF "; - std::string NoData = "ND "; - const char * NF = NoFuel.c_str(); - const char * ND = NoData.c_str(); - - for(i=0; i < this->nCells; i++){ - if (strcmp(df[i].fueltype, NF) == 0 || strcmp(df[i].fueltype, ND) == 0) { - this->fTypeCells[i] = 0; - this->fTypeCells2[i] = "NonBurnable"; - this->statusCells[i] = 4; - } - } - - // Relevant sets: Initialization - this->availCells.clear(); - this->nonBurnableCells.clear(); - this->burningCells.clear(); - this->burntCells.clear(); - this->harvestCells.clear(); - - // Harvest Cells - for (auto it = HarvestedCells.begin(); it != HarvestedCells.end(); it++ ){ - for (auto & it2 : it->second){ - this->fTypeCells[it2-1] = 0; - this->fTypeCells2[it2-1] = "NonBurnable"; - this->statusCells[it2-1] = 3; - } - } - - for (i=0; i < this->statusCells.size(); i++){ - if(this->statusCells[i] < 3) this->availCells.insert (i+1); - else if (this->statusCells[i] == 4) this->nonBurnableCells.insert(i+1); - else if (this->statusCells[i] == 3) this->harvestCells.insert(i+1); - } - - // Print-out sets information - if (this->args.verbose){ - printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - } -} +void +Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1) +{ + // Reset info + // DEBUGstd::cout << "--------------------- Reseting environment + // -----------------------" << std::endl; + + // Aux + int i; + + // Reset global parameters for the simulation + this->year = 1; + this->weatherPeriod = 0; + this->noIgnition = true; // None = -1 + this->nIgnitions = 0; + this->gridNumber = 0; + this->activeCrown = false; + this->done = false; + this->fire_period = vector(this->args.TotalYears, 0); + this->sim = simExt; + // Initial status grid folder + if (this->args.OutputGrids || this->args.FinalGrid) + { + CSVWriter CSVFolder("", ""); + this->gridFolder = this->args.OutFolder + "Grids" + separator(); + CSVFolder.MakeDir(this->gridFolder); + this->gridFolder + = this->args.OutFolder + "Grids" + separator() + "Grids" + std::to_string(this->sim) + separator(); + CSVFolder.MakeDir(this->gridFolder); + // DEBUGstd::cout << "\nInitial Grid folder was generated in " << + // this->gridFolder << std::endl; + } + + // Messages Folder + if (this->args.OutMessages) + { + CSVWriter CSVFolder("", ""); + this->messagesFolder = this->args.OutFolder + "Messages"; + CSVFolder.MakeDir(this->messagesFolder); + this->messagesFolder = this->args.OutFolder + "Messages" + separator(); + } + // ROS Folder + if (this->args.OutRos) + { + CSVWriter CSVFolder("", ""); + this->rosFolder = this->args.OutFolder + "RateOfSpread"; + CSVFolder.MakeDir(this->rosFolder); + this->rosFolder = this->args.OutFolder + "RateOfSpread" + separator(); + } + // Byram Intensity Folder + if (this->args.OutIntensity) + { + CSVWriter CSVFolder("", ""); + this->intensityFolder = this->args.OutFolder + "Intensity"; + CSVFolder.MakeDir(this->intensityFolder); + this->intensityFolder = this->args.OutFolder + "Intensity" + separator(); + } + // Flame Length Folder + if (this->args.OutFl) + { + CSVWriter CSVFolder("", ""); + this->flFolder = this->args.OutFolder + "FlameLength"; + CSVFolder.MakeDir(this->flFolder); + this->flFolder = this->args.OutFolder + "FlameLength" + separator(); + } + // Crown Folder + if (this->args.OutCrown && this->args.AllowCROS) + { + CSVWriter CSVFolder("", ""); + this->crownFolder = this->args.OutFolder + "CrownFire"; + CSVFolder.MakeDir(this->crownFolder); + this->crownFolder = this->args.OutFolder + "CrownFire" + separator(); + } + // Crown Fraction Burn Folder + if (this->args.OutCrownConsumption && this->args.AllowCROS) + { + CSVWriter CSVFolder("", ""); + this->cfbFolder = this->args.OutFolder + "CrownFractionBurn"; + CSVFolder.MakeDir(this->cfbFolder); + this->cfbFolder = this->args.OutFolder + separator() + "CrownFractionBurn" + separator(); + } + // Surf Fraction Burn Folder + if (this->args.OutSurfConsumption && this->args.Simulator == "C") + { + CSVWriter CSVFolder("", ""); + this->sfbFolder = this->args.OutFolder + "SurfFractionBurn"; + CSVFolder.MakeDir(this->sfbFolder); + this->sfbFolder = this->args.OutFolder + separator() + "SurfFractionBurn" + separator(); + } + + // Random Weather + /*std::cout << "Weather Option:" << this->args.WeatherOpt << std::endl; + std::cout << "Weather Option random check:" << + (this->args.WeatherOpt.compare("random") == 0) << std::endl; std::cout << + "Weather Option rows check:" << (this->args.WeatherOpt.compare("rows") == 0) + << std::endl; + */ + + if (this->args.WeatherOpt.compare("random") == 0) + { + // Random Weather + this->CSVWeather.fileName + = this->args.InFolder + "Weathers" + separator() + "Weather" + std::to_string(rnumber) + ".csv"; + + /* Weather DataFrame */ + try + { + this->WeatherDF = this->CSVWeather.getData(); + } + catch (std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + std::abort(); + } + std::cout << "\nWeather file selected: " << this->CSVWeather.fileName << std::endl; + + // Populate WDF + int WPeriods = this->WeatherDF.size() - 1; // -1 due to header + wdf_ptr = &wdf[0]; + std::cout << "Weather Periods: " << WPeriods << std::endl; + std::string weather_name = ""; + for (int i = this->CSVWeather.fileName.size() - 1; i >= 0; i--) + { + std::string bol = std::to_string(this->CSVWeather.fileName[i]); + int bol2 = std::stoi(bol); + char check = '\\'; + int intcheck = (int)check; + if (bol2 == intcheck) + { + break; + } + else + { + weather_name.push_back(this->CSVWeather.fileName[i]); + } + } + reverse(weather_name.begin(), weather_name.end()); + WeatherHistory.push_back(weather_name); + + // Populate the wdf objects + this->CSVWeather.parseWeatherDF(wdf_ptr, this->args_ptr, this->WeatherDF, WPeriods); + // DEBUGthis->CSVWeather.printData(this->WeatherDF); + + // Check maxFirePeriods and Weather File consistency (reset + // MaxFirePeriods and recalculate) + int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; + this->args.MaxFirePeriods = 10000000; + // DEBUGstd::cout << "Int MaxFP: " << maxFP << std::endl; + // DEBUGstd::cout << "MinutesPerWP: " << this->args.MinutesPerWP << + // std::endl; DEBUGstd::cout << "FirePeriodLen: " << + // this->args.FirePeriodLen << std::endl; DEBUGstd::cout << + // "MaxfirePeriods: " << this->args.MaxFirePeriods << std::endl; + if (this->args.MaxFirePeriods > maxFP) + { + this->args.MaxFirePeriods = maxFP; + if (this->args.verbose) + { + std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods + << " based on the weather file, Fire Period Length, " + "and Minutes per WP" + << std::endl; + } + } + } + + if (this->args.WeatherOpt.compare("distribution") == 0) + { + bool selectWeather = false; + int countCases = 0; + std::string weather_name; + while (!selectWeather) + { + std::default_random_engine generator3(args.seed * simExt + * time(NULL)); // creates a different generator solving cases when + // parallel running creates simulations at same time + std::uniform_int_distribution distribution(1, this->WDist.size() - 1); + int weather_idx = distribution(generator3); + + float rd_number = (float)rand() / ((float)(RAND_MAX / 0.999999999)); + float probability_weather = std::stof(this->WDist[weather_idx][1]); + // DEBUGstd::cout<<"prob: "<<(probability_weather)< rd_number) + { // rd_number cannot be 1, but can be 0. So if prob weather has + // prob=0 it does not have a chance of being selected, and if it + // is 1, it will always be selected + weather_name = this->WDist[weather_idx][0]; + // DEBUGstd::cout << "Weather name selected: " << weather_name << + // std::endl; + selectWeather = true; + } + countCases++; + if (countCases > 1000) + { + weather_name = this->WDist[weather_idx][0]; + selectWeather = true; + } + selectWeather = true; + } + + // Random Weather + this->CSVWeather.fileName = this->args.InFolder + "Weathers" + separator() + weather_name + ".csv"; + WeatherHistory.push_back(weather_name); + + /* Weather DataFrame */ + try + { + this->WeatherDF = this->CSVWeather.getData(); + } + catch (std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + std::abort(); + } + std::cout << "\nWeather file selected: " << this->CSVWeather.fileName << std::endl; + + // Populate WDF + int WPeriods = this->WeatherDF.size() - 1; // -1 due to header + wdf_ptr = &wdf[0]; + std::cout << "Weather Periods: " << WPeriods << std::endl; + + // Populate the wdf objects + this->CSVWeather.parseWeatherDF(wdf_ptr, this->args_ptr, this->WeatherDF, WPeriods); + // DEBUGthis->CSVWeather.printData(this->WeatherDF); + + // Check maxFirePeriods and Weather File consistency (reset + // MaxFirePeriods and recalculate) + int maxFP = this->args.MinutesPerWP / this->args.FirePeriodLen * WPeriods; + this->args.MaxFirePeriods = 10000000; + // DEBUGstd::cout << "Int MaxFP: " << maxFP << std::endl; + // DEBUGstd::cout << "MinutesPerWP: " << this->args.MinutesPerWP << + // std::endl; DEBUGstd::cout << "FirePeriodLen: " << + // this->args.FirePeriodLen << std::endl; DEBUGstd::cout << + // "MaxfirePeriods: " << this->args.MaxFirePeriods << std::endl; + + if (this->args.MaxFirePeriods > maxFP) + { + this->args.MaxFirePeriods = maxFP; + if (this->args.verbose) + { + std::cout << "Maximum fire periods are set to: " << this->args.MaxFirePeriods + << " based on the weather file, Fire Period Length, " + "and Minutes per WP" + << std::endl; + } + } + } + // Random ROS-CV + this->ROSRV = std::abs(rnumber2); + // std::cout << "ROSRV: " << this->ROSRV << std::endl; + + // Cells dictionary + this->Cells_Obj.clear(); + + // Declare an iterator to unordered_map + std::unordered_map::iterator it; + + // Reset status + this->fTypeCells = std::vector(this->nCells, 1); + this->fTypeCells2 = std::vector(this->nCells, "Burnable"); + this->statusCells = std::vector(this->nCells, 0); + this->crownState = std::vector(this->nCells, 0); + this->crownFraction = std::vector(this->nCells, 0); + this->surfFraction = std::vector(this->nCells, 0); + this->Intensities = std::vector(this->nCells, 0); + this->RateOfSpreads = std::vector(this->nCells, 0); + this->FlameLengths = std::vector(this->nCells, 0); + + this->FSCell.clear(); + this->crownMetrics.clear(); // intensity and crown + + // Non burnable types: populate relevant fields such as status and ftype + std::string NoFuel = "NF "; + std::string NoData = "ND "; + const char* NF = NoFuel.c_str(); + const char* ND = NoData.c_str(); + + for (i = 0; i < this->nCells; i++) + { + if (strcmp(df[i].fueltype, NF) == 0 || strcmp(df[i].fueltype, ND) == 0) + { + this->fTypeCells[i] = 0; + this->fTypeCells2[i] = "NonBurnable"; + this->statusCells[i] = 4; + } + } + // Relevant sets: Initialization + this->availCells.clear(); + this->nonBurnableCells.clear(); + this->burningCells.clear(); + this->burntCells.clear(); + this->harvestCells.clear(); + + // Harvest Cells + for (auto it = HarvestedCells.begin(); it != HarvestedCells.end(); it++) + { + for (auto& it2 : it->second) + { + this->fTypeCells[it2 - 1] = 0; + this->fTypeCells2[it2 - 1] = "NonBurnable"; + this->statusCells[it2 - 1] = 3; + } + } + + for (i = 0; i < this->statusCells.size(); i++) + { + if (this->statusCells[i] < 3) + this->availCells.insert(i + 1); + else if (this->statusCells[i] == 4) + this->nonBurnableCells.insert(i + 1); + else if (this->statusCells[i] == 3) + this->harvestCells.insert(i + 1); + } + + // Print-out sets information + if (this->args.verbose) + { + printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } +} /** - * @brief Simulates the ignition phase of the fire spread model for a single simulation year. + * @brief Simulates the ignition phase of the fire spread model for a single + * simulation year. * - * This method is responsible for selecting ignition points, either randomly or from predefined - * data (e.g., CSV files), and attempting to ignite those points based on the conditions of the cells - * (availability, burnability, etc.). The simulation state is updated accordingly, including - * tracking ignited, burnt, and available cells, as well as the fire and weather periods. + * This method is responsible for selecting ignition points, either randomly or + * from predefined data (e.g., CSV files), and attempting to ignite those + * points based on the conditions of the cells (availability, burnability, + * etc.). The simulation state is updated accordingly, including tracking + * ignited, burnt, and available cells, as well as the fire and weather + * periods. * - * @param generator A random engine used to generate random values for ignition point selection. - * @param ep The current simulation epoch, used to seed the secondary random generator for parallel simulations. + * @param generator A random engine used to generate random values for ignition + * point selection. + * @param ep The current simulation epoch, used to seed the secondary random + * generator for parallel simulations. * @return true If no ignition occurs during the current simulation year. - * @return false If at least one ignition occurs during the current simulation year. + * @return false If at least one ignition occurs during the current simulation + * year. * * ### Detailed Behavior: - * - If no ignition points are provided (args.Ignitions == 0), a random point is selected - * repeatedly until a valid ignition is found or a limit is reached. - * - If ignition points are provided, the algorithm selects a point directly or samples - * from a specified radius around the predefined points. - * - The ignition process updates the state of the forest, including burning and burnt cells, - * and prepares for the next period or year if no ignition occurs. + * - If no ignition points are provided (args.Ignitions == 0), a random point + * is selected repeatedly until a valid ignition is found or a limit is + * reached. + * - If ignition points are provided, the algorithm selects a point directly or + * samples from a specified radius around the predefined points. + * - The ignition process updates the state of the forest, including burning + * and burnt cells, and prepares for the next period or year if no ignition + * occurs. * * ### Key Updates: * - Ignition history (IgnitionHistory) @@ -846,391 +979,522 @@ void Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1){ * - Fire and weather periods * * ### Verbose Mode: - * When `args.verbose` is true, detailed logs of the ignition process, including selected points, - * random values, and status updates, are printed to the console. + * When `args.verbose` is true, detailed logs of the ignition process, + * including selected points, random values, and status updates, are printed to + * the console. */ -bool Cell2Fire::RunIgnition(std::default_random_engine generator, int ep){ - if (this->args.verbose) { - printf("\n----------------------------- Simulating Year %d -----------------------------\n", this->year); - printf("---------------------- Step 1: Ignition ----------------------\n"); - } - /******************************************************************* - * - * Step 1: Ignition - * - *******************************************************************/ - // Ignitions - int aux = 0; - int selected = 0; - int loops = 0; - int microloops = 0; - this->noIgnition = false; - currentSim = currentSim+1; - std::default_random_engine generator2(args.seed * ep*this->nCells);// * time(NULL)); //creates a different generator solving cases when parallel running creates simulations at same time - std::unordered_map::iterator it; - std::uniform_int_distribution distribution(1, this->nCells); - - // No Ignitions provided - if (this->args.Ignitions == 0) { - while (true) { - microloops = 0; - while (true) { - selected = distribution(generator2); - float rd_number = (float)rand() / ((float)(RAND_MAX / 0.999999999)); - //DEBUGstd::cout << "selectedPoint: " << selected << std::endl; - //DEBUGstd::cout << "selectedProbability: " << ignProb[selected-1] << std::endl; - //DEBUGstd::cout << "randomNumber: " << rd_number << std::endl; - //if (ignProb[selected - 1] / static_cast(100) > rd_number) { //If probabilities enter as integers, e.g: 80 as 0.8 - if (this->ignProb[selected - 1] > rd_number) { - aux = selected; - //DEBUSstd::cout << "selected_point" << std::endl; - break; - } - microloops++; - if (microloops > this->nCells * 100) { - this->noIgnition = true; - break; - } - - } - // Check information (Debugging) - if (this->args.verbose){ - std::cout << "aux: " << aux << std::endl; - } - - // If cell is available and not initialized, initialize it - if (this->statusCells[aux - 1] < 3 && this->burntCells.find(aux) == this->burntCells.end()) { - if (this->Cells_Obj.find(aux) == this->Cells_Obj.end()) { - InitCell(aux); - it = this->Cells_Obj.find(aux); - } - - if (it->second.getStatus() == "Available" && it->second.fType != 0) { - IgnitionHistory[sim] = aux; - std::cout << "\nSelected (Random) ignition point for Year " << this->year << ", sim " << this->sim << ": "<< aux; - std::vector ignPts = {aux}; - if (it->second.ignition(this->fire_period[year - 1], this->year, ignPts, & df[aux - 1], this->coef_ptr, this->args_ptr, & wdf[this->weatherPeriod],this->activeCrown,this->perimeterCells)) { - //Printing info about ignitions - if (this->args.verbose){ - std::cout << "Cell " << it->second.realId << " Ignites" << std::endl; - std::cout << "Cell " << it->second.realId << " Status: "<< it->second.getStatus() << std::endl; - } - - // Status - this->statusCells[it->second.realId - 1] = 1; - - // Plotter placeholder - if (this->args.OutputGrids){ - this->outputGrid(); - } - - break; - } - } - } - - loops++; - if (loops > this->nCells * 100) { - this->noIgnition = true; - break; - } - - - } - } - - // Ignitions with provided points from CSV - else { - int temp = IgnitionPoints[this->year-1]; - - // If ignition Radius != 0, sample from the Radius set - if (this->args.IgnitionRadius > 0){ - // Pick any at random and set temp with that cell - std::uniform_int_distribution udistribution(0, this->IgnitionSets[this->year - 1].size()-1); - temp = this->IgnitionSets[this->year - 1][udistribution(generator)]; - } - - std::cout << "\nSelected ignition point for Year " << this->year << ", sim " << this->sim << ": "<< temp; - //this-> - IgnitionHistory[sim] = temp; - - // If cell is available - if (this->burntCells.find(temp) == this->burntCells.end() && this->statusCells[temp - 1] < 3) { - if (this->Cells_Obj.find(temp) == this->Cells_Obj.end()) { - // Initialize cell, insert it inside the unordered map - InitCell(temp); - } - - // Iterator - it = this->Cells_Obj.find(temp); - - // Not available or non burnable: no ignition - if (it->second.getStatus() != "Available" || it->second.fType == 0) { - this->noIgnition = true; - } - - // Available and Burnable: ignition - if (it->second.getStatus() == "Available" && it->second.fType != 0) { - std::vector ignPts = {temp}; - if (it->second.ignition(this->fire_period[year - 1], this->year, ignPts, & df[temp-1], this->coef_ptr, this->args_ptr, &wdf[this->weatherPeriod],this->activeCrown,this->perimeterCells)) { - - //Printing info about ignitions - if (this->args.verbose){ - std::cout << "Cell " << it->second.realId << " Ignites" << std::endl; - std::cout << "Cell " << it->second.realId << " Status: "<< it->second.getStatus() << std::endl; - } - - // Status - this->statusCells[it->second.realId-1] = 1; - - } - - } - - } else { - this->noIgnition = true; - std::cout <<"Next year..." << std::endl; - if (this->args.verbose){ - std::cout << "No ignition during year " << this->year << ", Cell " << this->IgnitionPoints[this->year-1] << " is already burnt or non-burnable type" << std::endl; - } - this->year++; - this->weatherPeriod = 0; - } - - } - - - // If ignition occurs, we update the forest status - if (!this->noIgnition) { - int newId = it->second.realId; - if (this->args.verbose) std:cout << "New ID for burning cell: " << newId << std::endl; - - this->nIgnitions++; - this->burningCells.insert(newId); - this->burntCells.insert(newId); - this->availCells.erase(newId); - - // Print sets information - if (this->args.verbose){ - printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - } - } - - // Plotter placeholder - if (this->args.OutputGrids){ - //DEBUGstd::cout << "Grid post ignition" << std::endl; - this->outputGrid(); - } - - // Next period - //this->fire_period[year - 1] += 1; // DEBUGGING!!! - if (this->args.verbose){ - std::cout << "Fire period updated to " << this->fire_period[year - 1] << std::endl; - } - - // Check weather period consistency - updateWeather(); - - // Print-out information regarding the weather and fire period - if (this->args.verbose){ - std::cout << "Fire Period Starts: " << this->fire_period[year-1] << std::endl; - std::cout << "\nCurrent weather conditions:" << std::endl; - this->CSVWeather.printWeatherDF(wdf[this->weatherPeriod]); - - if (this->args.WeatherOpt.compare("constant") == 0) - std::cout << "(NOTE: current weather is not used for ROS with constant option)" << std::endl; - - // End of the ignition step - std::cout << "\nNext Fire Period: " << this->fire_period[year-1] << std::endl; - } - - // If no ignition occurs, go to next year (no multiple ignitions per year, only one) - if(this->noIgnition){ - if (this->args.verbose){ - std::cout << "No ignition in year " << this->year << std::endl; - std::cout << "-------------------------------------------------------------------------\n" << std::endl; - std::cout << " End of the fire year " << this->year << " " << std::endl; - std::cout << "-------------------------------------------------------------------------" << std::endl; - } - - // Next year - this->year+=1; - } - - //std::cout << endl << "el punto de ignicion es: " << aux << std::endl; - - - return this->noIgnition; -} +bool +Cell2Fire::RunIgnition(std::default_random_engine generator, int ep) +{ + if (this->args.verbose) + { + printf("\n----------------------------- Simulating Year %d " + "-----------------------------\n", + this->year); + printf("---------------------- Step 1: Ignition ----------------------\n"); + } + /******************************************************************* + * + * Step + *1: Ignition + * + *******************************************************************/ + // Ignitions + int aux = 0; + int selected = 0; + int loops = 0; + int microloops = 0; + this->noIgnition = false; + currentSim = currentSim + 1; + std::default_random_engine generator2(args.seed * ep * this->nCells); // * time(NULL)); //creates a different + // generator solving cases when parallel + // running creates simulations at same time + std::unordered_map::iterator it; + std::uniform_int_distribution distribution(1, this->nCells); + + // No Ignitions provided + if (this->args.Ignitions == 0) + { + while (true) + { + microloops = 0; + while (true) + { + selected = distribution(generator2); + float rd_number = (float)rand() / ((float)(RAND_MAX / 0.999999999)); + // DEBUGstd::cout << "selectedPoint: " << selected << std::endl; + // DEBUGstd::cout << "selectedProbability: " << + // ignProb[selected-1] << std::endl; DEBUGstd::cout << + // "randomNumber: " << rd_number << std::endl; if + // (ignProb[selected - 1] / static_cast(100) > rd_number) + // { //If probabilities enter as integers, e.g: 80 as 0.8 + if (this->ignProb[selected - 1] > rd_number) + { + aux = selected; + // DEBUSstd::cout << "selected_point" << std::endl; + break; + } + microloops++; + if (microloops > this->nCells * 100) + { + this->noIgnition = true; + break; + } + } + // Check information (Debugging) + if (this->args.verbose) + { + std::cout << "aux: " << aux << std::endl; + } + + // If cell is available and not initialized, initialize it + if (this->statusCells[aux - 1] < 3 && this->burntCells.find(aux) == this->burntCells.end()) + { + if (this->Cells_Obj.find(aux) == this->Cells_Obj.end()) + { + InitCell(aux); + it = this->Cells_Obj.find(aux); + } + + if (it->second.getStatus() == "Available" && it->second.fType != 0) + { + IgnitionHistory[sim] = aux; + std::cout << "\nSelected (Random) ignition point for Year " << this->year << ", sim " << this->sim + << ": " << aux; + std::vector ignPts = { aux }; + if (it->second.ignition(this->fire_period[year - 1], + this->year, + ignPts, + &df[aux - 1], + this->coef_ptr, + this->args_ptr, + &wdf[this->weatherPeriod], + this->activeCrown, + this->perimeterCells)) + { + // Printing info about ignitions + if (this->args.verbose) + { + std::cout << "Cell " << it->second.realId << " Ignites" << std::endl; + std::cout << "Cell " << it->second.realId << " Status: " << it->second.getStatus() + << std::endl; + } + + // Status + this->statusCells[it->second.realId - 1] = 1; + + // Plotter placeholder + if (this->args.OutputGrids) + { + this->outputGrid(); + } + + break; + } + } + } + + loops++; + if (loops > this->nCells * 100) + { + this->noIgnition = true; + break; + } + } + } + // Ignitions with provided points from CSV + else + { + int temp = IgnitionPoints[this->year - 1]; + + // If ignition Radius != 0, sample from the Radius set + if (this->args.IgnitionRadius > 0) + { + // Pick any at random and set temp with that cell + std::uniform_int_distribution udistribution(0, this->IgnitionSets[this->year - 1].size() - 1); + temp = this->IgnitionSets[this->year - 1][udistribution(generator)]; + } + + std::cout << "\nSelected ignition point for Year " << this->year << ", sim " << this->sim << ": " << temp; + // this-> + IgnitionHistory[sim] = temp; + + // If cell is available + if (this->burntCells.find(temp) == this->burntCells.end() && this->statusCells[temp - 1] < 3) + { + if (this->Cells_Obj.find(temp) == this->Cells_Obj.end()) + { + // Initialize cell, insert it inside the unordered map + InitCell(temp); + } + + // Iterator + it = this->Cells_Obj.find(temp); + + // Not available or non burnable: no ignition + if (it->second.getStatus() != "Available" || it->second.fType == 0) + { + this->noIgnition = true; + } + + // Available and Burnable: ignition + if (it->second.getStatus() == "Available" && it->second.fType != 0) + { + std::vector ignPts = { temp }; + if (it->second.ignition(this->fire_period[year - 1], + this->year, + ignPts, + &df[temp - 1], + this->coef_ptr, + this->args_ptr, + &wdf[this->weatherPeriod], + this->activeCrown, + this->perimeterCells)) + { + + // Printing info about ignitions + if (this->args.verbose) + { + std::cout << "Cell " << it->second.realId << " Ignites" << std::endl; + std::cout << "Cell " << it->second.realId << " Status: " << it->second.getStatus() << std::endl; + } + + // Status + this->statusCells[it->second.realId - 1] = 1; + } + } + } + else + { + this->noIgnition = true; + std::cout << "Next year..." << std::endl; + if (this->args.verbose) + { + std::cout << "No ignition during year " << this->year << ", Cell " + << this->IgnitionPoints[this->year - 1] << " is already burnt or non-burnable type" + << std::endl; + } + this->year++; + this->weatherPeriod = 0; + } + } + + // If ignition occurs, we update the forest status + if (!this->noIgnition) + { + int newId = it->second.realId; + if (this->args.verbose) + std: + cout << "New ID for burning cell: " << newId << std::endl; + + this->nIgnitions++; + this->burningCells.insert(newId); + this->burntCells.insert(newId); + this->availCells.erase(newId); + + // Print sets information + if (this->args.verbose) + { + printSets( + this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } + } + + // Plotter placeholder + if (this->args.OutputGrids) + { + // DEBUGstd::cout << "Grid post ignition" << std::endl; + this->outputGrid(); + } + + // Next period + // this->fire_period[year - 1] += 1; // DEBUGGING!!! + if (this->args.verbose) + { + std::cout << "Fire period updated to " << this->fire_period[year - 1] << std::endl; + } + + // Check weather period consistency + updateWeather(); + + // Print-out information regarding the weather and fire period + if (this->args.verbose) + { + std::cout << "Fire Period Starts: " << this->fire_period[year - 1] << std::endl; + std::cout << "\nCurrent weather conditions:" << std::endl; + this->CSVWeather.printWeatherDF(wdf[this->weatherPeriod]); + + if (this->args.WeatherOpt.compare("constant") == 0) + std::cout << "(NOTE: current weather is not used for ROS with " + "constant option)" + << std::endl; + + // End of the ignition step + std::cout << "\nNext Fire Period: " << this->fire_period[year - 1] << std::endl; + } + + // If no ignition occurs, go to next year (no multiple ignitions per year, + // only one) + if (this->noIgnition) + { + if (this->args.verbose) + { + std::cout << "No ignition in year " << this->year << std::endl; + std::cout << "------------------------------------------------------" + "-------------------\n" + << std::endl; + std::cout << " End of the fire year " << this->year << " " + << std::endl; + std::cout << "------------------------------------------------------" + "-------------------" + << std::endl; + } + + // Next year + this->year += 1; + } + + // std::cout << endl << "el punto de ignicion es: " << aux << std::endl; + + return this->noIgnition; +} /** * @brief Message-sending phase of the fire spread model, where burning cells * propagate fire messages to neighboring cells. * - * This method iterates through all burning cells, updates their fire progress, and determines - * whether fire messages should be sent to neighboring cells. A fire message is sent to a cell - * if fire reaches its center. Burnt-out cells are also identified and removed from the burning set. + * This method iterates through all burning cells, updates their fire progress, + * and determines whether fire messages should be sent to neighboring cells. A + * fire message is sent to a cell if fire reaches its center. Burnt-out cells + * are also identified and removed from the burning set. * - * @return A map of cell IDs to lists of neighboring cell IDs that received fire messages. - * Each key is the ID of a burning cell, and the value is a list of neighboring cell IDs - * affected by the fire. + * @return A map of cell IDs to lists of neighboring cell IDs that received + * fire messages. Each key is the ID of a burning cell, and the value is a list + * of neighboring cell IDs affected by the fire. * * ### Detailed Behavior: - * - Iterates over all currently burning cells to manage fire propagation using either the - * `manageFire` or `manageFireBBO` methods, depending on tuning options. - * - Builds a list of neighboring cells (`sendMessageList`) that receive fire messages for - * potential ignition. - * - Tracks cells that burn out during this phase and removes them from the active burning set. + * - Iterates over all currently burning cells to manage fire propagation using + * either the `manageFire` or `manageFireBBO` methods, depending on tuning + * options. + * - Builds a list of neighboring cells (`sendMessageList`) that receive fire + * messages for potential ignition. + * - Tracks cells that burn out during this phase and removes them from the + * active burning set. * - Handles special conditions where repeat fire propagation may occur. * * ### Key Updates: * - `burningCells`: Updated to exclude cells that have burnt out. - * - `burnedOutList`: Contains cells that are no longer burning after this phase. - * - `messagesSent`: A flag indicating if any fire messages were sent during this phase. + * - `burnedOutList`: Contains cells that are no longer burning after this + * phase. + * - `messagesSent`: A flag indicating if any fire messages were sent during + * this phase. * * ### Verbose Mode: * When `args.verbose` is enabled: - * - Prints detailed logs of the fire progress and messages sent by each burning cell. - * - Outputs the current fire period, sets of cells (available, non-burnable, burning, burnt, harvested), - * and fire message details. + * - Prints detailed logs of the fire progress and messages sent by each + * burning cell. + * - Outputs the current fire period, sets of cells (available, non-burnable, + * burning, burnt, harvested), and fire message details. * * ### Warning: - * - A warning is issued if the fire period approaches the maximum allowed (`args.MaxFirePeriods`). + * - A warning is issued if the fire period approaches the maximum allowed + * (`args.MaxFirePeriods`). */ -std::unordered_map> Cell2Fire::SendMessages(){ - // Iterator - std::unordered_map::iterator it; - - // Clean list - this->burnedOutList.clear(); - - // Check ending - if (fire_period[year - 1] == args.MaxFirePeriods - 1 && this->args.verbose) { - std::cout << "*** WARNING!!! About to hit MaxFirePeriods: " << this->args.MaxFirePeriods << std::endl; - } - - /// Send messages logic - this->messagesSent = false; - std::unordered_map> sendMessageList; - - // Repeat fire flag - this->repeatFire = false; - - // Printing info before sending messages - if (this->args.verbose){ - std::cout << "\n---------------------- Step 2: Sending Messages from Ignition ----------------------" << std::endl; - std::cout << "Current Fire Period:" << this->fire_period[this->year - 1] << std::endl; - printSets(this->availCells, this->nonBurnableCells, this->burningCells, - this->burntCells, this->harvestCells); - - } - - /* - Potential parallel zone: Send messages - Burning cells loop: sending messages (Embarrasingly parallel?: CP: should be) - Each burning cell updates its fire progress and (if needed) populates their message - */ - for (int cell : this->burningCells) { - std::vector aux_list; - // Get object from unordered map - it = this->Cells_Obj.find(cell); - - // Cell's info - if (this->args.verbose) { - it->second.print_info(); - } - - /* - Manage Fire method main step - */ - if (it->second.ROSAngleDir.size() > 0) { - //std::cout << "Entra a Manage Fire" << std::endl; - if (!this->args.BBOTuning){ //&df[cell-1] replaced by full df for getting the slopes - aux_list = it->second.manageFire(this->fire_period[this->year-1], this->availCells, df, this->coef_ptr, - this->coordCells, this->Cells_Obj, this->args_ptr, &wdf[this->weatherPeriod], - &this->FSCell, &this->crownMetrics,this->activeCrown, this->ROSRV,this->perimeterCells,this->crownState, this->crownFraction,this->surfFraction, this->Intensities, this->RateOfSpreads, this->FlameLengths); - } - - - else{ - // TODO MAY 11: Pass the slope factor or the slopes of the adjacent cells - auto factors = BBOFactors.find(NFTypesCells[cell-1]); - aux_list = it->second.manageFireBBO(this->fire_period[this->year-1], this->availCells, & df[cell-1], this->coef_ptr, - this->coordCells, this->Cells_Obj, this->args_ptr, &wdf[this->weatherPeriod], - &this->FSCell, &this->crownMetrics,this->activeCrown, this->ROSRV,this->perimeterCells, factors->second,this->crownState, this->crownFraction,this->surfFraction, this->Intensities, this->RateOfSpreads, this->FlameLengths); - } - //std::cout << "Sale de Manage Fire" << std::endl; - } - - else{ - if(this->args.verbose) std::cout << "\nCell " << cell << " does not have any neighbor available for receiving messages" << std::endl; - } - - // If message and not a true flag - if (aux_list.size() > 0 && aux_list[0] != -100) { - if (this->args.verbose) std::cout <<"\nList is not empty" << std::endl; - this->messagesSent = true; - sendMessageList[it->second.realId] = aux_list; - if (this->args.verbose){ - std::cout << "Message list content" << std::endl; - for (auto & msg : sendMessageList[it->second.realId]){ - std::cout << " Fire reaches the center of the cell " << msg << " Distance to cell (in meters) was 100.0" << " " << std::endl; - } - } - - } - - // Repeat fire conditions if true flag - if (aux_list.size() > 0 && aux_list[0] == -100) { - this->repeatFire = true; - } - - // Burnt out inactive burning cells - if (aux_list.size() == 0) { - // not parallel here - this->burnedOutList.push_back(it->second.realId); - if (this->args.verbose){ - std::cout << "\nMessage and Aux Lists are empty; adding to BurnedOutList" << std::endl; - } - } - - } - /* End sending messages loop */ - - - // Check for burnt out updates via sets' difference - for(auto &bc : this->burnedOutList){ - auto lt = this->burningCells.find(bc); - if (lt != this->burningCells.end()) { - this->burningCells.erase(bc); - } - } - if (this->args.verbose) printSets(this->availCells, this->nonBurnableCells, - this->burningCells, this->burntCells, - this->harvestCells); - - return sendMessageList; -} +std::unordered_map> +Cell2Fire::SendMessages() +{ + // Iterator + std::unordered_map::iterator it; + + // Clean list + this->burnedOutList.clear(); + + // Check ending + if (fire_period[year - 1] == args.MaxFirePeriods - 1 && this->args.verbose) + { + std::cout << "*** WARNING!!! About to hit MaxFirePeriods: " << this->args.MaxFirePeriods << std::endl; + } + + /// Send messages logic + this->messagesSent = false; + std::unordered_map> sendMessageList; + + // Repeat fire flag + this->repeatFire = false; + + // Printing info before sending messages + if (this->args.verbose) + { + std::cout << "\n---------------------- Step 2: Sending Messages from " + "Ignition ----------------------" + << std::endl; + std::cout << "Current Fire Period:" << this->fire_period[this->year - 1] << std::endl; + printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } + + /* + Potential parallel zone: Send messages + Burning cells loop: sending messages (Embarrasingly + parallel?: CP: should be) Each burning cell updates its fire progress and + (if needed) populates their message + */ + for (int cell : this->burningCells) + { + std::vector aux_list; + // Get object from unordered map + it = this->Cells_Obj.find(cell); + + // Cell's info + if (this->args.verbose) + { + it->second.print_info(); + } + + /* + Manage Fire method main step + */ + if (it->second.ROSAngleDir.size() > 0) + { + // std::cout << "Entra a Manage Fire" << std::endl; + if (!this->args.BBOTuning) + { //&df[cell-1] replaced by full df for getting the slopes + aux_list = it->second.manageFire(this->fire_period[this->year - 1], + this->availCells, + df, + this->coef_ptr, + this->coordCells, + this->Cells_Obj, + this->args_ptr, + &wdf[this->weatherPeriod], + &this->FSCell, + &this->crownMetrics, + this->activeCrown, + this->ROSRV, + this->perimeterCells, + this->crownState, + this->crownFraction, + this->surfFraction, + this->Intensities, + this->RateOfSpreads, + this->FlameLengths); + } + + else + { + // TODO MAY 11: Pass the slope factor or the slopes of the + // adjacent cells + auto factors = BBOFactors.find(NFTypesCells[cell - 1]); + aux_list = it->second.manageFireBBO(this->fire_period[this->year - 1], + this->availCells, + &df[cell - 1], + this->coef_ptr, + this->coordCells, + this->Cells_Obj, + this->args_ptr, + &wdf[this->weatherPeriod], + &this->FSCell, + &this->crownMetrics, + this->activeCrown, + this->ROSRV, + this->perimeterCells, + factors->second, + this->crownState, + this->crownFraction, + this->surfFraction, + this->Intensities, + this->RateOfSpreads, + this->FlameLengths); + } + // std::cout << "Sale de Manage Fire" << std::endl; + } + + else + { + if (this->args.verbose) + std::cout << "\nCell " << cell + << " does not have any neighbor available for receiving " + "messages" + << std::endl; + } + + // If message and not a true flag + if (aux_list.size() > 0 && aux_list[0] != -100) + { + if (this->args.verbose) + std::cout << "\nList is not empty" << std::endl; + this->messagesSent = true; + sendMessageList[it->second.realId] = aux_list; + if (this->args.verbose) + { + std::cout << "Message list content" << std::endl; + for (auto& msg : sendMessageList[it->second.realId]) + { + std::cout << " Fire reaches the center of the cell " << msg + << " Distance to cell (in meters) was 100.0" + << " " << std::endl; + } + } + } + + // Repeat fire conditions if true flag + if (aux_list.size() > 0 && aux_list[0] == -100) + { + this->repeatFire = true; + } + + // Burnt out inactive burning cells + if (aux_list.size() == 0) + { + // not parallel here + this->burnedOutList.push_back(it->second.realId); + if (this->args.verbose) + { + std::cout << "\nMessage and Aux Lists are empty; adding to " + "BurnedOutList" + << std::endl; + } + } + } + /* End sending messages loop */ + + // Check for burnt out updates via sets' difference + for (auto& bc : this->burnedOutList) + { + auto lt = this->burningCells.find(bc); + if (lt != this->burningCells.end()) + { + this->burningCells.erase(bc); + } + } + if (this->args.verbose) + printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + return sendMessageList; +} /** - * @brief Processes incoming fire messages to determine the ignition and progression of fire in cells. + * @brief Processes incoming fire messages to determine the ignition and + * progression of fire in cells. * - * This method handles the reception and processing of messages sent by burning cells. Based on the received messages, - * cells may ignite, continue burning, or be marked as burnt out. The method also manages the transitions between - * fire periods and updates relevant cell sets (e.g., available, burning, burnt). + * This method handles the reception and processing of messages sent by burning + * cells. Based on the received messages, cells may ignite, continue burning, + * or be marked as burnt out. The method also manages the transitions between + * fire periods and updates relevant cell sets (e.g., available, burning, + * burnt). * - * @param sendMessageList A map where each key is the ID of a burning cell, and the associated value is a list of - * neighboring cell IDs that received fire messages from that cell. + * @param sendMessageList A map where each key is the ID of a burning cell, and + * the associated value is a list of neighboring cell IDs that received fire + * messages from that cell. * * ### Detailed Behavior: * * - For each cell receiving messages: * - Initializes the cell if it hasn't been processed before. * - Checks ignition conditions and marks the cell as burnt if applicable. - * - Updates fire-related metadata, ensuring fire does not propagate back to the sender cell. + * - Updates fire-related metadata, ensuring fire does not propagate back to + * the sender cell. * * ### Key Updates: * - `burntCells`: Updated with cells that are fully burnt. @@ -1241,199 +1505,264 @@ std::unordered_map> Cell2Fire::SendMessages(){ * * ### Verbose Mode: * When `args.verbose` is enabled: - * - Logs detailed information about fire messages, ignition, and cell state transitions. - * - Prints the current state of cell sets (available, non-burnable, burning, burnt, harvested). + * - Logs detailed information about fire messages, ignition, and cell state + * transitions. + * - Prints the current state of cell sets (available, non-burnable, burning, + * burnt, harvested). * * ### Weather Updates: - * - Calls `updateWeather` to apply weather conditions for the next fire period. - * - Provides a note if the weather is constant, indicating its effect on the fire model. + * - Calls `updateWeather` to apply weather conditions for the next fire + * period. + * - Provides a note if the weather is constant, indicating its effect on the + * fire model. */ -void Cell2Fire::GetMessages(std::unordered_map> sendMessageList){ - // Iterator - std::unordered_map::iterator it; - - // Information of the current step - if (this->args.verbose){ - std::cout << "\n---------------------- Step 3: Receiving and processing messages from Ignition ----------------------" << std::endl; - std::cout << "Current Fire Period: " << this->fire_period[this->year-1] << std::endl; - printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - } - - // Conditions depending on number of messages and repeatFire flag - // No messages but repetition - if (this->repeatFire && !this->messagesSent) { - if(this->args.verbose){ - std::cout << "Fires are still alive, no message generated" << std::endl; - std::cout << "Current fire period: " << this->fire_period[this->year - 1] << std::endl; - } - this->fire_period[this->year - 1] += 1; - - // Check if we need to update the weather - this->updateWeather(); - } - - // Messages and repetition - if (this->repeatFire && this->messagesSent) { - if (this->args.verbose) std::cout << "Messages have been sent, next step. Current period: " << this->fire_period[this->year - 1] << std::endl; - this->repeatFire = false; - } - - // No messages, no repeat (break and next year) - if (!this->messagesSent && !this->repeatFire) { - if (this->args.verbose){ - std::cout << "\nNo messages during the fire period, end of year "<< this->year << std::endl; - } - // Next year, reset weeks, weather period, and update burnt cells from burning cells - this->year += 1; - this->weatherPeriod = 0; - this->noMessages = true; - // Update sets - for(auto &bc : this->burningCells){ - this->burntCells.insert(bc); - } - this->burningCells.clear(); - if (this->args.verbose) printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - } - - // Mesages and no repeat - if (this->messagesSent && !this->repeatFire) { - - // frequency array - std::unordered_map globalMessagesList; - for (auto & sublist : sendMessageList) { - for (int val : sublist.second) { - if (globalMessagesList.find(val) == globalMessagesList.end()){ - globalMessagesList[val] = 1; - } else { - globalMessagesList[val] = globalMessagesList[val] + 1; - } - } - } - - // Initialize cells if needed (getting messages) - for (auto & _bc : globalMessagesList) { - int bc = _bc.first; - if (this->Cells_Obj.find(bc) == this->Cells_Obj.end() && this->burntCells.find(bc) == this->burntCells.end()) { - // Initialize cell, insert it inside the unordered map - InitCell(bc); - it = this->Cells_Obj.find(bc); - } - } - - // Get burnt loop - if(this->args.verbose){ - for (auto & _bc : globalMessagesList) { - printf("CELL %d inside global message list \n", _bc.first); - } - } - - std::unordered_set burntList; - bool checkBurnt; - for (auto & _bc : globalMessagesList) { - //printf("\n\nWE ARE DEBUGGING!!!! CELL TO BE ANALYZED GET BURNT IS %d\n", _bc.first); - int bc = _bc.first; - if (this->burntCells.find(bc) == this->burntCells.end()) { - if (this->Cells_Obj.find(bc) == this->Cells_Obj.end()) { - - // Initialize cell, insert it inside the unordered map - InitCell(bc); - it = this->Cells_Obj.find(bc); - } - else it = this->Cells_Obj.find(bc); - - // Check if burnable, then check potential ignition - if (it->second.fType != 0) { - checkBurnt = it->second.get_burned(this->fire_period[this->year-1], 1, this->year, df, - this->coef_ptr, this->args_ptr, &wdf[this->weatherPeriod],this->activeCrown,this->perimeterCells); - - } else { - checkBurnt = false; - } - - // Print-out regarding the burnt cell - if(this->args.verbose){ - std::cout << "\nCell " << it->second.realId << " got burnt (1 true, 0 false): " << checkBurnt << std::endl; - } - - // Update the burntlist - if (checkBurnt) { - burntList.insert(it->second.realId); - - // Cleaning step - // Fire can't be propagated back - int cellNum = it->second.realId - 1; - for (auto & angle : it->second.angleToNb) { - int origToNew = angle.first; - // Which neighbor am I to the burnt cell - int newToOrig = (origToNew + 180) % 360; - int adjCellNum = angle.second; // Check - auto adjIt = Cells_Obj.find(adjCellNum); - if (adjIt != Cells_Obj.end()) { - adjIt->second.ROSAngleDir.erase(newToOrig); - } - } - } - - } - } - - - // Update sets - for(auto &bc : burntList) { - this->burntCells.insert(bc); - } - - for(auto &bc : this->burnedOutList) { - this->burntCells.insert(bc); - } - - for(auto &bc : burntList) { - this->burningCells.insert(bc); - } - - for(auto &bc : burningCells){ - auto lt = this->availCells.find(bc); - if (lt != this->availCells.end()) { - this->availCells.erase(bc); - } - } - - // Display info for debugging - if(this->args.verbose){ - printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - } - - /* - * Next Period - */ - this->fire_period[this->year - 1] += 1; - - // If weather is not constant (random weather to be supported in next commit...) - this->updateWeather(); - - // Message for constant weather - if (this->args.WeatherOpt.compare("constant") == 0 && this->args.verbose){ - std::cout << "(NOTE: current weather is not used for ROS with constant option)" << std::endl; - } - } -} +void +Cell2Fire::GetMessages(std::unordered_map> sendMessageList) +{ + // Iterator + std::unordered_map::iterator it; + + // Information of the current step + if (this->args.verbose) + { + std::cout << "\n---------------------- Step 3: Receiving and processing " + "messages from Ignition ----------------------" + << std::endl; + std::cout << "Current Fire Period: " << this->fire_period[this->year - 1] << std::endl; + printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } + + // Conditions depending on number of messages and repeatFire flag + // No messages but repetition + if (this->repeatFire && !this->messagesSent) + { + if (this->args.verbose) + { + std::cout << "Fires are still alive, no message generated" << std::endl; + std::cout << "Current fire period: " << this->fire_period[this->year - 1] << std::endl; + } + this->fire_period[this->year - 1] += 1; + + // Check if we need to update the weather + this->updateWeather(); + } + + // Messages and repetition + if (this->repeatFire && this->messagesSent) + { + if (this->args.verbose) + std::cout << "Messages have been sent, next step. Current period: " << this->fire_period[this->year - 1] + << std::endl; + this->repeatFire = false; + } + // No messages, no repeat (break and next year) + if (!this->messagesSent && !this->repeatFire) + { + if (this->args.verbose) + { + std::cout << "\nNo messages during the fire period, end of year " << this->year << std::endl; + } + // Next year, reset weeks, weather period, and update burnt cells from + // burning cells + this->year += 1; + this->weatherPeriod = 0; + this->noMessages = true; + // Update sets + for (auto& bc : this->burningCells) + { + this->burntCells.insert(bc); + } + this->burningCells.clear(); + if (this->args.verbose) + printSets( + this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } + + // Mesages and no repeat + if (this->messagesSent && !this->repeatFire) + { + + // frequency array + std::unordered_map globalMessagesList; + for (auto& sublist : sendMessageList) + { + for (int val : sublist.second) + { + if (globalMessagesList.find(val) == globalMessagesList.end()) + { + globalMessagesList[val] = 1; + } + else + { + globalMessagesList[val] = globalMessagesList[val] + 1; + } + } + } + + // Initialize cells if needed (getting messages) + for (auto& _bc : globalMessagesList) + { + int bc = _bc.first; + if (this->Cells_Obj.find(bc) == this->Cells_Obj.end() + && this->burntCells.find(bc) == this->burntCells.end()) + { + // Initialize cell, insert it inside the unordered map + InitCell(bc); + it = this->Cells_Obj.find(bc); + } + } + + // Get burnt loop + if (this->args.verbose) + { + for (auto& _bc : globalMessagesList) + { + printf("CELL %d inside global message list \n", _bc.first); + } + } + + std::unordered_set burntList; + bool checkBurnt; + for (auto& _bc : globalMessagesList) + { + // printf("\n\nWE ARE DEBUGGING!!!! CELL TO BE ANALYZED GET BURNT IS + // %d\n", _bc.first); + int bc = _bc.first; + if (this->burntCells.find(bc) == this->burntCells.end()) + { + if (this->Cells_Obj.find(bc) == this->Cells_Obj.end()) + { + + // Initialize cell, insert it inside the unordered map + InitCell(bc); + it = this->Cells_Obj.find(bc); + } + else + it = this->Cells_Obj.find(bc); + + // Check if burnable, then check potential ignition + if (it->second.fType != 0) + { + checkBurnt = it->second.get_burned(this->fire_period[this->year - 1], + 1, + this->year, + df, + this->coef_ptr, + this->args_ptr, + &wdf[this->weatherPeriod], + this->activeCrown, + this->perimeterCells); + } + else + { + checkBurnt = false; + } + + // Print-out regarding the burnt cell + if (this->args.verbose) + { + std::cout << "\nCell " << it->second.realId << " got burnt (1 true, 0 false): " << checkBurnt + << std::endl; + } + + // Update the burntlist + if (checkBurnt) + { + burntList.insert(it->second.realId); + + // Cleaning step + // Fire can't be propagated back + int cellNum = it->second.realId - 1; + for (auto& angle : it->second.angleToNb) + { + int origToNew = angle.first; + // Which neighbor am I to the burnt cell + int newToOrig = (origToNew + 180) % 360; + int adjCellNum = angle.second; // Check + auto adjIt = Cells_Obj.find(adjCellNum); + if (adjIt != Cells_Obj.end()) + { + adjIt->second.ROSAngleDir.erase(newToOrig); + } + } + } + } + } + + // Update sets + for (auto& bc : burntList) + { + this->burntCells.insert(bc); + } + + for (auto& bc : this->burnedOutList) + { + this->burntCells.insert(bc); + } + + for (auto& bc : burntList) + { + this->burningCells.insert(bc); + } + + for (auto& bc : burningCells) + { + auto lt = this->availCells.find(bc); + if (lt != this->availCells.end()) + { + this->availCells.erase(bc); + } + } + + // Display info for debugging + if (this->args.verbose) + { + printSets( + this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + } + + /* + * Next Period + */ + this->fire_period[this->year - 1] += 1; + + // If weather is not constant (random weather to be supported in next + // commit...) + this->updateWeather(); + + // Message for constant weather + if (this->args.WeatherOpt.compare("constant") == 0 && this->args.verbose) + { + std::cout << "(NOTE: current weather is not used for ROS with " + "constant option)" + << std::endl; + } + } +} /** - * @brief Generates and outputs simulation results, including fire behavior metrics, final grid status, and logs. + * @brief Generates and outputs simulation results, including fire behavior + * metrics, final grid status, and logs. * - * This method processes the results of the fire simulation, updating cell statuses and generating various outputs - * such as grid data, fire spread metrics, and intensity logs. It supports multiple file formats (e.g., CSV, ASCII) - * and organizes output into designated folders for easy analysis and debugging. + * This method processes the results of the fire simulation, updating cell + * statuses and generating various outputs such as grid data, fire spread + * metrics, and intensity logs. It supports multiple file formats (e.g., CSV, + * ASCII) and organizes output into designated folders for easy analysis and + * debugging. * * ### Behavior: * - Updates the status of cells: - * - `burntCells` and `burningCells` are marked as fully burnt (`status = 2`). + * - `burntCells` and `burningCells` are marked as fully burnt (`status = + * 2`). * - Computes summary statistics: - * - Reports the number and percentage of available, burnt, non-burnable, and firebreak cells. + * - Reports the number and percentage of available, burnt, non-burnable, and + * firebreak cells. * - Writes outputs to files: - * - **Grid Status**: Outputs the final grid state to a CSV file if `args.FinalGrid` is enabled. - * - **Network Messages**: Logs fire message data to a CSV file if `args.OutMessages` is enabled. + * - **Grid Status**: Outputs the final grid state to a CSV file if + * `args.FinalGrid` is enabled. + * - **Network Messages**: Logs fire message data to a CSV file if + * `args.OutMessages` is enabled. * - **Fire Spread Metrics**: * - Rate of Spread (ROS) * - Byram Intensity @@ -1444,11 +1773,14 @@ void Cell2Fire::GetMessages(std::unordered_map> sendMessag * - **Ignition Log**: Logs ignition history if `args.IgnitionsLog` is enabled. * * ### Outputs: - * - The output files are organized into subfolders under the designated output directory (`args.OutFolder`). - * - Naming conventions include simulation IDs (`sim`) to ensure unique file names. + * - The output files are organized into subfolders under the designated output + * directory (`args.OutFolder`). + * - Naming conventions include simulation IDs (`sim`) to ensure unique file + * names. * - File types: * - CSV for grids and messages. - * - ASCII for rate of spread, intensity, flame length, and other fire behavior metrics. + * - ASCII for rate of spread, intensity, flame length, and other fire + * behavior metrics. * * * ### Example Output: @@ -1461,217 +1793,268 @@ void Cell2Fire::GetMessages(std::unordered_map> sendMessag * ``` * * ### Notes: - * - Ensure the output directory structure exists before running the simulation to avoid file I/O errors. - * - This method supports optional outputs, which can be toggled using command-line arguments. + * - Ensure the output directory structure exists before running the simulation + * to avoid file I/O errors. + * - This method supports optional outputs, which can be toggled using + * command-line arguments. */ -void Cell2Fire::Results(){ - /***************************************************************************** - * - * Steps 4: Results and outputs - * - ******************************************************************************/ - // Iterator - // Declare an iterator to unordered_map - std::unordered_map::iterator it; - int i; - - for (auto & br : this->burntCells) { - if (this->Cells_Obj.find(br) != this->Cells_Obj.end()) { - // Get object from unordered map - it = this->Cells_Obj.find(br); - - // Initialize the fire fields for the selected cel - it->second.status = 2; - } - } - - for (auto & br : this->burningCells) { - if (this->Cells_Obj.find(br) != this->Cells_Obj.end()) { - // Get object from unordered map - it = this->Cells_Obj.find(br); - - // Initialize the fire fields for the selected cel - it->second.status = 2; - } - } - - // Final results for comparison with Python - //DEBUGstd::cout << "\n ------------------------ Final results for comparison with Python ------------------------"; - - // Final report - float ACells = this->availCells.size(); - float BCells = this->burntCells.size(); - float NBCells = this->nonBurnableCells.size(); - float HCells = this->harvestCells.size(); - - std::cout <<"\n----------------------------- Results -----------------------------" << std::endl; - std::cout << "Total Available Cells: " << ACells << " - % of the Forest: " << ACells/nCells*100.0 << "%" << std::endl; - std::cout << "Total Burnt Cells: " << BCells << " - % of the Forest: " << BCells/nCells*100.0 <<"%" << std::endl; - std::cout << "Total Non-Burnable Cells: " << NBCells << " - % of the Forest: " << NBCells/nCells*100.0 <<"%"<< std::endl; - std::cout << "Total Firebreak Cells: " << HCells << " - % of the Forest: " << HCells/nCells*100.0 <<"%"<< std::endl; - - // Final Grid - if(this->args.FinalGrid){ - CSVWriter CSVFolder("",""); - if (this->args.OutFolder.empty()) - this->gridFolder = this->args.InFolder + "simOuts" + separator() + "Grids" + separator() + "Grids" + std::to_string(this->sim) + separator(); - else - this->gridFolder = this->args.OutFolder + "Grids" + separator() + "Grids" + std::to_string(this->sim) + separator(); - //std::string gridName = this->gridFolder + "FinalStatus_" + std::to_string(this->sim) + ".csv"; - outputGrid(); - } - - // Messages - if(this->args.OutMessages){ - this->messagesFolder = this->args.OutFolder +"Messages"+separator(); - std::string messagesName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - messagesName= this->messagesFolder+"MessagesFile"+oss.str()+".csv"; - if(this->args.verbose){ - std::cout << "We are generating the network messages to a csv file " << messagesName << std::endl; - } - CSVWriter CSVPloter(messagesName, ","); - //CSVPloter.printCSVDouble_V2(this->FSCell.size() - this->nIgnitions, 4, this->FSCell); - CSVPloter.printCSVDouble_V2(this->FSCell.size()/4, 4, this->FSCell); - } - - // RateOfSpread - if (this->args.OutRos) { - this->rosFolder = this->args.OutFolder + "RateOfSpread" + separator(); - std::string rosName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - rosName= this->rosFolder+"ROSFile"+oss.str()+".asc"; - if (this->args.verbose) { - std::cout << "We are generating the Rate of Spread to a asc file " << rosName << std::endl; - } - CSVWriter CSVPloter(rosName, " "); - CSVPloter.printASCII(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->RateOfSpreads); - } - - // Intensity - if (this->args.OutIntensity) { - this->intensityFolder = this->args.OutFolder + "Intensity"+separator(); - std::string intensityName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - intensityName= this->intensityFolder+"Intensity"+oss.str()+".asc"; - - if (this->args.verbose) { - std::cout << "We are generating the Byram Intensity to a asc file " << intensityName << std::endl; - } - CSVWriter CSVPloter(intensityName, " "); - CSVPloter.printASCII(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->Intensities); - } - - if (this->args.OutFl) { - this->flFolder = this->args.OutFolder + "FlameLength"+separator(); - std::string flName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - flName= this->flFolder+"FL"+oss.str()+".asc"; - if (this->args.verbose) { - std::cout << "We are generating the Flame Lenght to a asc file " << flName << std::endl; - } - CSVWriter CSVPloter(flName, " "); - CSVPloter.printASCII(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->FlameLengths); - } - - // Intensity - if ((this->args.OutCrownConsumption) && (this->args.AllowCROS)) { - this->cfbFolder = this->args.OutFolder + "CrownFractionBurn"+separator(); - std::string cfbName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - cfbName= this->cfbFolder+"Cfb"+oss.str()+".asc"; - if (this->args.verbose) { - std::cout << "We are generating the Crown Fraction Burn to a asc file " << cfbName << std::endl; - } - CSVWriter CSVPloter(cfbName, " "); - CSVPloter.printASCII(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->crownFraction); - } - - // Intensity - if ((this->args.OutSurfConsumption) && (this->args.Simulator=="C")) { - this->sfbFolder = this->args.OutFolder + "SurfFractionBurn"+separator(); - std::string sfbName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - sfbName= this->sfbFolder+"Sfb"+oss.str()+".asc"; - if (this->args.verbose) { - std::cout << "We are generating the Surface Fraction Burn to a asc file " << sfbName << std::endl; - } - CSVWriter CSVPloter(sfbName, " "); - CSVPloter.printASCII(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->surfFraction); - } - - // Crown - if ((this->args.OutCrown) && (this->args.AllowCROS)) { - this->crownFolder = this->args.OutFolder + "CrownFire"+separator(); - std::string crownName; - std::ostringstream oss; - oss.str(""); - oss<widthSims)<sim; - crownName= this->crownFolder+"Crown"+oss.str()+".asc"; - if (this->args.verbose) { - std::cout << "We are generating the Crown behavior to a asc file " << crownName << std::endl; - } - CSVWriter CSVPloter(crownName, " "); - //CSVPloter.printCrownAscii(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->crownMetrics, statusCells2); /OLD VERSION - CSVPloter.printASCIIInt(this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->crownState); - } - - // Ignition Logfile - if (currentSim == args.TotalSims && this->args.IgnitionsLog){ - - std::cout << "Writing ignitions log csv..." << endl; - if (this->args.verbose) { - std::cout << "(simulation_id, cell_id): "; - for (i = 1; i < IgnitionHistory.size()+1; i++) { - std::cout << i << "," << IgnitionHistory[i] << "\t"; - } - } - - std::string filename = "ignitions_log.csv"; - CSVWriter igHistoryFolder("", ""); - this->ignitionsFolder = this->args.OutFolder + "IgnitionsHistory"+separator(); - igHistoryFolder.MakeDir(this->ignitionsFolder); - CSVWriter ignitionsFile(this->ignitionsFolder + filename); - ignitionsFile.printIgnitions(IgnitionHistory); +void +Cell2Fire::Results() +{ + /***************************************************************************** + * + * Steps + *4: Results and outputs + * + ******************************************************************************/ + // Iterator + // Declare an iterator to unordered_map + std::unordered_map::iterator it; + int i; + + for (auto& br : this->burntCells) + { + if (this->Cells_Obj.find(br) != this->Cells_Obj.end()) + { + // Get object from unordered map + it = this->Cells_Obj.find(br); + + // Initialize the fire fields for the selected cel + it->second.status = 2; + } + } + + for (auto& br : this->burningCells) + { + if (this->Cells_Obj.find(br) != this->Cells_Obj.end()) + { + // Get object from unordered map + it = this->Cells_Obj.find(br); + + // Initialize the fire fields for the selected cel + it->second.status = 2; + } + } + + // Final results for comparison with Python + // DEBUGstd::cout << "\n ------------------------ Final results for + // comparison with Python ------------------------"; + + // Final report + float ACells = this->availCells.size(); + float BCells = this->burntCells.size(); + float NBCells = this->nonBurnableCells.size(); + float HCells = this->harvestCells.size(); + + std::cout << "\n----------------------------- Results " + "-----------------------------" + << std::endl; + std::cout << "Total Available Cells: " << ACells << " - % of the Forest: " << ACells / nCells * 100.0 << "%" + << std::endl; + std::cout << "Total Burnt Cells: " << BCells << " - % of the Forest: " << BCells / nCells * 100.0 << "%" + << std::endl; + std::cout << "Total Non-Burnable Cells: " << NBCells << " - % of the Forest: " << NBCells / nCells * 100.0 << "%" + << std::endl; + std::cout << "Total Firebreak Cells: " << HCells << " - % of the Forest: " << HCells / nCells * 100.0 << "%" + << std::endl; + + // Final Grid + if (this->args.FinalGrid) + { + CSVWriter CSVFolder("", ""); + if (this->args.OutFolder.empty()) + this->gridFolder = this->args.InFolder + "simOuts" + separator() + "Grids" + separator() + "Grids" + + std::to_string(this->sim) + separator(); + else + this->gridFolder + = this->args.OutFolder + "Grids" + separator() + "Grids" + std::to_string(this->sim) + separator(); + // std::string gridName = this->gridFolder + "FinalStatus_" + + // std::to_string(this->sim) + ".csv"; + outputGrid(); + } + + // Messages + if (this->args.OutMessages) + { + this->messagesFolder = this->args.OutFolder + "Messages" + separator(); + std::string messagesName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + messagesName = this->messagesFolder + "MessagesFile" + oss.str() + ".csv"; + if (this->args.verbose) + { + std::cout << "We are generating the network messages to a csv file " << messagesName << std::endl; + } + CSVWriter CSVPloter(messagesName, ","); + // CSVPloter.printCSVDouble_V2(this->FSCell.size() - this->nIgnitions, 4, + // this->FSCell); + CSVPloter.printCSVDouble_V2(this->FSCell.size() / 4, 4, this->FSCell); + } + + // RateOfSpread + if (this->args.OutRos) + { + this->rosFolder = this->args.OutFolder + "RateOfSpread" + separator(); + std::string rosName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + rosName = this->rosFolder + "ROSFile" + oss.str() + ".asc"; + if (this->args.verbose) + { + std::cout << "We are generating the Rate of Spread to a asc file " << rosName << std::endl; + } + CSVWriter CSVPloter(rosName, " "); + CSVPloter.printASCII( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->RateOfSpreads); + } + + // Intensity + if (this->args.OutIntensity) + { + this->intensityFolder = this->args.OutFolder + "Intensity" + separator(); + std::string intensityName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + intensityName = this->intensityFolder + "Intensity" + oss.str() + ".asc"; + + if (this->args.verbose) + { + std::cout << "We are generating the Byram Intensity to a asc file " << intensityName << std::endl; + } + CSVWriter CSVPloter(intensityName, " "); + CSVPloter.printASCII( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->Intensities); + } + + if (this->args.OutFl) + { + this->flFolder = this->args.OutFolder + "FlameLength" + separator(); + std::string flName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + flName = this->flFolder + "FL" + oss.str() + ".asc"; + if (this->args.verbose) + { + std::cout << "We are generating the Flame Lenght to a asc file " << flName << std::endl; + } + CSVWriter CSVPloter(flName, " "); + CSVPloter.printASCII( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->FlameLengths); + } + + // Intensity + if ((this->args.OutCrownConsumption) && (this->args.AllowCROS)) + { + this->cfbFolder = this->args.OutFolder + "CrownFractionBurn" + separator(); + std::string cfbName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + cfbName = this->cfbFolder + "Cfb" + oss.str() + ".asc"; + if (this->args.verbose) + { + std::cout << "We are generating the Crown Fraction Burn to a asc file " << cfbName << std::endl; + } + CSVWriter CSVPloter(cfbName, " "); + CSVPloter.printASCII( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->crownFraction); + } + + // Intensity + if ((this->args.OutSurfConsumption) && (this->args.Simulator == "C")) + { + this->sfbFolder = this->args.OutFolder + "SurfFractionBurn" + separator(); + std::string sfbName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + sfbName = this->sfbFolder + "Sfb" + oss.str() + ".asc"; + if (this->args.verbose) + { + std::cout << "We are generating the Surface Fraction Burn to a asc file " << sfbName << std::endl; + } + CSVWriter CSVPloter(sfbName, " "); + CSVPloter.printASCII( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->surfFraction); } -} + // Crown + if ((this->args.OutCrown) && (this->args.AllowCROS)) + { + this->crownFolder = this->args.OutFolder + "CrownFire" + separator(); + std::string crownName; + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->sim; + crownName = this->crownFolder + "Crown" + oss.str() + ".asc"; + if (this->args.verbose) + { + std::cout << "We are generating the Crown behavior to a asc file " << crownName << std::endl; + } + CSVWriter CSVPloter(crownName, " "); + // CSVPloter.printCrownAscii(this->rows, this->cols, this->xllcorner, + // this->yllcorner, this->cellSide, this->crownMetrics, statusCells2); + // /OLD VERSION + CSVPloter.printASCIIInt( + this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->crownState); + } + + // Ignition Logfile + if (currentSim == args.TotalSims && this->args.IgnitionsLog) + { + + std::cout << "Writing ignitions log csv..." << endl; + if (this->args.verbose) + { + std::cout << "(simulation_id, cell_id): "; + for (i = 1; i < IgnitionHistory.size() + 1; i++) + { + std::cout << i << "," << IgnitionHistory[i] << "\t"; + } + } + + std::string filename = "ignitions_log.csv"; + CSVWriter igHistoryFolder("", ""); + this->ignitionsFolder = this->args.OutFolder + "IgnitionsHistory" + separator(); + igHistoryFolder.MakeDir(this->ignitionsFolder); + CSVWriter ignitionsFile(this->ignitionsFolder + filename); + ignitionsFile.printIgnitions(IgnitionHistory); + } +} /** * @brief Outputs the current state of the forest grid to a CSV file. * - * This method generates a binary representation of the forest grid, with cell statuses indicating their condition - * (burning, burnt, harvested, etc.) during the simulation. The file is saved with a unique name in the designated + * This method generates a binary representation of the forest grid, with cell + * statuses indicating their condition (burning, burnt, harvested, etc.) during + * the simulation. The file is saved with a unique name in the designated * output folder. * * ### Behavior: * - **Cell Status Update**: - * - Updates a vector (`statusCells2`) to reflect the current statuses of cells: + * - Updates a vector (`statusCells2`) to reflect the current statuses of + * cells: * - `1` for burning or burnt cells. * - `-1` for harvested cells. * - `0` for all other cells. * - **File Naming**: - * - Constructs a file name based on the simulation's `gridNumber` and saves it in the `gridFolder` directory. + * - Constructs a file name based on the simulation's `gridNumber` and saves + * it in the `gridFolder` directory. * - File names follow the pattern: `ForestGrid.csv`. * - **Verbose Mode**: - * - Logs the file name and output process to the console if `args.verbose` is enabled. + * - Logs the file name and output process to the console if `args.verbose` + * is enabled. * - **Output Format**: - * - The CSV file represents the forest grid in rows and columns, with each cell's status stored in `statusCells2`. + * - The CSV file represents the forest grid in rows and columns, with each + * cell's status stored in `statusCells2`. * * ### Outputs: - * - A CSV file is saved in the `gridFolder` directory, with the grid's state for the current simulation step. + * - A CSV file is saved in the `gridFolder` directory, with the grid's state + * for the current simulation step. * - Example CSV content: * ``` * 0, 0, 1, 0 @@ -1680,263 +2063,314 @@ void Cell2Fire::Results(){ * ``` * * ### Notes: - * - Ensure the `gridFolder` directory exists before calling this method to avoid file I/O errors. - * - The method automatically increments `gridNumber` after each call to ensure unique file names. + * - Ensure the `gridFolder` directory exists before calling this method to + * avoid file I/O errors. + * - The method automatically increments `gridNumber` after each call to ensure + * unique file names. */ -void Cell2Fire::outputGrid(){ - // FileName - std::string gridName; - std::vector statusCells2(this->nCells, 0); //(long int, int); - - // Update status - for (auto & bc : this->burningCells){ - statusCells2[bc-1] = 1; - } - for (auto & ac : this->burntCells){ - statusCells2[ac-1] = 1; - } - for (auto & hc : this->harvestCells){ - statusCells2[hc-1] = -1; - } - std::ostringstream oss; - oss.str(""); - oss<widthSims)<gridNumber; - gridName= this->gridFolder+"ForestGrid"+oss.str()+".csv"; - if(this->args.verbose){ - std::cout << "We are plotting the current forest to a csv file " << gridName << std::endl; - } - - CSVWriter CSVPloter(gridName, ","); - CSVPloter.printCSV(this->rows, this->cols, statusCells2); - this->gridNumber++; +void +Cell2Fire::outputGrid() +{ + // FileName + std::string gridName; + std::vector statusCells2(this->nCells, 0); //(long int, int); + + // Update status + for (auto& bc : this->burningCells) + { + statusCells2[bc - 1] = 1; + } + for (auto& ac : this->burntCells) + { + statusCells2[ac - 1] = 1; + } + for (auto& hc : this->harvestCells) + { + statusCells2[hc - 1] = -1; + } + std::ostringstream oss; + oss.str(""); + oss << std::setfill('0') << std::setw(this->widthSims) << this->gridNumber; + gridName = this->gridFolder + "ForestGrid" + oss.str() + ".csv"; + if (this->args.verbose) + { + std::cout << "We are plotting the current forest to a csv file " << gridName << std::endl; + } + CSVWriter CSVPloter(gridName, ","); + CSVPloter.printCSV(this->rows, this->cols, statusCells2); + this->gridNumber++; } - /** - * @brief Updates the weather conditions during the simulation based on specified criteria. + * @brief Updates the weather conditions during the simulation based on + * specified criteria. * - * This method dynamically updates the weather parameters used in the simulation based on the simulation's - * fire period and weather options. It can optionally output the current state of the forest grid and - * log weather updates if verbose mode is enabled. + * This method dynamically updates the weather parameters used in the + * simulation based on the simulation's fire period and weather options. It can + * optionally output the current state of the forest grid and log weather + * updates if verbose mode is enabled. * * ### Behavior: * - **Weather Update Check**: * - Weather is updated if: * - The `WeatherOpt` argument is not set to `"constant"`. - * - The fire period multiplied by the fire period length exceeds the current `weatherPeriod`. + * - The fire period multiplied by the fire period length exceeds the + * current `weatherPeriod`. * - When the conditions are met, the `weatherPeriod` is incremented. * - **Grid Output**: - * - If the `OutputGrids` argument is enabled, the current forest grid is output using the `outputGrid` method. + * - If the `OutputGrids` argument is enabled, the current forest grid is + * output using the `outputGrid` method. * - **Verbose Logging**: * - If `verbose` mode is enabled: * - Logs the weather update to the console. - * - Prints detailed weather information for the current period using `CSVWeather.printWeatherDF`. + * - Prints detailed weather information for the current period using + * `CSVWeather.printWeatherDF`. */ -void Cell2Fire::updateWeather(){ - if (this->args.WeatherOpt != "constant" && this->fire_period[this->year - 1] * this->args.FirePeriodLen / this->args.MinutesPerWP > this->weatherPeriod + 1) { - this->weatherPeriod++; - if (this->args.OutputGrids){ - this->outputGrid(); - } - if (this->args.verbose){ - std::cout << "\nWeather has been updated" << std::endl; - this->CSVWeather.printWeatherDF(wdf[this->weatherPeriod]); - } - } +void +Cell2Fire::updateWeather() +{ + if (this->args.WeatherOpt != "constant" + && this->fire_period[this->year - 1] * this->args.FirePeriodLen / this->args.MinutesPerWP + > this->weatherPeriod + 1) + { + this->weatherPeriod++; + if (this->args.OutputGrids) + { + this->outputGrid(); + } + if (this->args.verbose) + { + std::cout << "\nWeather has been updated" << std::endl; + this->CSVWeather.printWeatherDF(wdf[this->weatherPeriod]); + } + } } - /** * @brief Executes a single simulation step in the forest fire model. * - * This method simulates one fire period, handling all related processes such as ignition, message exchange, - * weather updates, and transitioning between simulation years or scenarios. It is the core operational logic - * for advancing the simulation in discrete steps. + * This method simulates one fire period, handling all related processes such + * as ignition, message exchange, weather updates, and transitioning between + * simulation years or scenarios. It is the core operational logic for + * advancing the simulation in discrete steps. * * ### Behavior: * - **Verbose Logging**: - * - If `verbose` is enabled, prints details about the current simulation state, including the year, fire period, - * weather period, and grid status. + * - If `verbose` is enabled, prints details about the current simulation + * state, including the year, fire period, weather period, and grid status. * * - **Simulation Logic**: * - **End of Simulation Checks**: - * - Ends the simulation if the current year exceeds the total years (`TotalYears`). - * - If the available cells or burning cells are empty, the simulation is marked as complete. + * - Ends the simulation if the current year exceeds the total years + * (`TotalYears`). + * - If the available cells or burning cells are empty, the simulation is + * marked as complete. * - **Ignition**: - * - Handles ignition logic during the first fire period. If no ignition occurs, checks for available burning cells. + * - Handles ignition logic during the first fire period. If no ignition + * occurs, checks for available burning cells. * - **Fire Spread**: * - Processes fire spread by sending and receiving messages between cells. * - **Weather Updates**: * - Resets the weather period at the start of each new year. * - **Fire Period Limits**: - * - If the current fire period exceeds the maximum allowed fire periods (`MaxFirePeriods`), advances to the next year. + * - If the current fire period exceeds the maximum allowed fire periods + * (`MaxFirePeriods`), advances to the next year. * - **Results Handling**: * - Outputs results and weather history if required. * * - **Transition to Next Simulation**: - * - Advances to the next simulation if the maximum year or conditions for termination are met. - * - Handles additional simulation-specific logic based on weather options and history requirements. + * - Advances to the next simulation if the maximum year or conditions for + * termination are met. + * - Handles additional simulation-specific logic based on weather options + * and history requirements. * */ -void Cell2Fire::Step(std::default_random_engine generator, int ep){ - // Iterator - // Declare an iterator to unordered_map - std::unordered_map::iterator it; - bool auxC = false; - this->noMessages = false; - // Conditions entering the step - if (this->args.verbose){ - std::cout << "********************************************" << std::endl; - std::cout << "Year: " << this->year << std::endl; - std::cout << "Fire Period: " << this->fire_period[this->year-1] << std::endl; - std::cout << "WeatherPeriod: " << this->weatherPeriod << std::endl; - std::cout << "MaxFirePeriods: " << this->args.MaxFirePeriods << std::endl; - printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); - std::cout << "********************************************" << std::endl; - } - // One step (one fire period, ignition - if needed -, sending messages and receiving them - if needed) - // For completeness: just in case user runs it longer than the horizon (should not happen) - if (this->year > this->args.TotalYears){ - if (this->args.verbose){ - printf("\nYear is greater than the Horizon, no more steps"); - } - this->done = true; - // Print-out results to folder - if (this->args.verbose) this->Results(); - - //Next Sim - this->sim += 1; - } - // Info - if (this->args.verbose){ - std::cout << "\nSimulating year" << this->year << "\nOut of totalYears:" << this->args.TotalYears; - } - // New operational step (ONE fire period) - if (this->fire_period[this->year - 1] > 0 && !this->done){ - // Fire Spread (one time step of RL - Operational) - // Send messages after ignition (does not advance time!) - std::unordered_map> SendMessageList = this->SendMessages(); - // Get Message - this->GetMessages(SendMessageList); - } - // Operational dynamic - // Ignition if we are in the first period (added workaround for no Messages) - if (!this->done && !this->noMessages){ - if (this->fire_period[this->year - 1] == 0) { - //std::cout << "Entra a Ignition step 0" << std::endl; - // Continue only if ignition - No ignition (True): done - if (this->RunIgnition(generator, ep)) { - // Next year - this->weatherPeriod = 0; - // If more than planning horizon, next sim - if (this->year > this->args.TotalYears) { - // Print-out results to folder - this->Results(); - // Next Sim if max year - this->done = true; - } - } - else { - // Start sending messages - std::unordered_map> SendMessageList = this->SendMessages(); - // Get Message - this->GetMessages(SendMessageList); - // Check if no burning cells to stop - if (this->burningCells.size() == 0) { - // Next Sim if max year - this->done = true; - } - } - } - } - // Ending conditions - if (this->fire_period[std::min(this->year , int(fire_period.size())) - 1] >= this->args.MaxFirePeriods){ - // Extra breaking condition: Max fire periods then go to next year - if (this->args.verbose){ - printf("\nNext year due to max periods...\n"); - } - // Next Year/Season update - this->weatherPeriod = 0; - auxC = true; - for(auto &bc : burningCells){ - auto lt = this->availCells.find(bc); - if (lt != this->availCells.end()) { - this->availCells.erase(bc); - } - this->burntCells.insert(bc); - } - this->burningCells.clear(); - } - // If more than planning horizon, next sim - if (this->year > this->args.TotalYears){ - //printf("\n\nEntra a year mayor al total...\n\n"); - // Print-out results to folder - this->Results(); - // Next Sim if max year - this->sim += 1; - this->done = true; - } - // Done flag (extra condition: no available cells or death of the team) - if ((this->availCells.size() == 0) || (this->burningCells.size() == 0 && !this->noMessages) && !this->done && !auxC){ - // Done - this->done = true; - // Print-out results to folder - this->Results(); - // Next Sim if max year - this->sim += 1; - } - - if ((this->sim > args.TotalSims) && (args.WeatherOpt != "rows")) { - this->counter_wt += 1; - if (this->counter_wt <= 1) { - // Weather History Folder - std::string filename = "WeatherHistory.csv"; - CSVWriter WtHistoryFolder("", ""); - this->historyFolder = this->args.OutFolder + "WeatherHistory"+separator() ; - WtHistoryFolder.MakeDir(this->historyFolder); - CSVWriter WtFile(this->historyFolder + filename); - WtFile.printWeather(WeatherHistory); - } - } - // Print current status - if (!this->done && this->args.verbose){ - printf("\nFire Period: %d", this->fire_period[this->year - 1]); - printf("\nYear: %d \n\n", this->year); - } -} - +void +Cell2Fire::Step(std::default_random_engine generator, int ep) +{ + // Iterator + // Declare an iterator to unordered_map + std::unordered_map::iterator it; + bool auxC = false; + this->noMessages = false; + // Conditions entering the step + if (this->args.verbose) + { + std::cout << "********************************************" << std::endl; + std::cout << "Year: " << this->year << std::endl; + std::cout << "Fire Period: " << this->fire_period[this->year - 1] << std::endl; + std::cout << "WeatherPeriod: " << this->weatherPeriod << std::endl; + std::cout << "MaxFirePeriods: " << this->args.MaxFirePeriods << std::endl; + printSets(this->availCells, this->nonBurnableCells, this->burningCells, this->burntCells, this->harvestCells); + std::cout << "********************************************" << std::endl; + } + // One step (one fire period, ignition - if needed -, sending messages and + // receiving them - if needed) For completeness: just in case user runs it + // longer than the horizon (should not happen) + if (this->year > this->args.TotalYears) + { + if (this->args.verbose) + { + printf("\nYear is greater than the Horizon, no more steps"); + } + this->done = true; + // Print-out results to folder + if (this->args.verbose) + this->Results(); + + // Next Sim + this->sim += 1; + } + // Info + if (this->args.verbose) + { + std::cout << "\nSimulating year" << this->year << "\nOut of totalYears:" << this->args.TotalYears; + } + // New operational step (ONE fire period) + if (this->fire_period[this->year - 1] > 0 && !this->done) + { + // Fire Spread (one time step of RL - Operational) + // Send messages after ignition (does not advance time!) + std::unordered_map> SendMessageList = this->SendMessages(); + // Get Message + this->GetMessages(SendMessageList); + } + // Operational dynamic + // Ignition if we are in the first period (added workaround for no Messages) + if (!this->done && !this->noMessages) + { + if (this->fire_period[this->year - 1] == 0) + { + // std::cout << "Entra a Ignition step 0" << std::endl; + // Continue only if ignition - No ignition (True): done + if (this->RunIgnition(generator, ep)) + { + // Next year + this->weatherPeriod = 0; + // If more than planning horizon, next sim + if (this->year > this->args.TotalYears) + { + // Print-out results to folder + this->Results(); + // Next Sim if max year + this->done = true; + } + } + else + { + // Start sending messages + std::unordered_map> SendMessageList = this->SendMessages(); + // Get Message + this->GetMessages(SendMessageList); + // Check if no burning cells to stop + if (this->burningCells.size() == 0) + { + // Next Sim if max year + this->done = true; + } + } + } + } + // Ending conditions + if (this->fire_period[std::min(this->year, int(fire_period.size())) - 1] >= this->args.MaxFirePeriods) + { + // Extra breaking condition: Max fire periods then go to next year + if (this->args.verbose) + { + printf("\nNext year due to max periods...\n"); + } + // Next Year/Season update + this->weatherPeriod = 0; + auxC = true; + for (auto& bc : burningCells) + { + auto lt = this->availCells.find(bc); + if (lt != this->availCells.end()) + { + this->availCells.erase(bc); + } + this->burntCells.insert(bc); + } + this->burningCells.clear(); + } + // If more than planning horizon, next sim + if (this->year > this->args.TotalYears) + { + // printf("\n\nEntra a year mayor al total...\n\n"); + // Print-out results to folder + this->Results(); + // Next Sim if max year + this->sim += 1; + this->done = true; + } + // Done flag (extra condition: no available cells or death of the team) + if ((this->availCells.size() == 0) || (this->burningCells.size() == 0 && !this->noMessages) && !this->done && !auxC) + { + // Done + this->done = true; + // Print-out results to folder + this->Results(); + // Next Sim if max year + this->sim += 1; + } -void Cell2Fire::InitHarvested(){ - std::cout << "OK"; + if ((this->sim > args.TotalSims) && (args.WeatherOpt != "rows")) + { + this->counter_wt += 1; + if (this->counter_wt <= 1) + { + // Weather History Folder + std::string filename = "WeatherHistory.csv"; + CSVWriter WtHistoryFolder("", ""); + this->historyFolder = this->args.OutFolder + "WeatherHistory" + separator(); + WtHistoryFolder.MakeDir(this->historyFolder); + CSVWriter WtFile(this->historyFolder + filename); + WtFile.printWeather(WeatherHistory); + } + } + // Print current status + if (!this->done && this->args.verbose) + { + printf("\nFire Period: %d", this->fire_period[this->year - 1]); + printf("\nYear: %d \n\n", this->year); + } } +void +Cell2Fire::InitHarvested() +{ + std::cout << "OK"; +} /** * @brief Retrieves the Rate of Spread (ROS) matrix for all cells. * * @return A vector of floats representing the ROS values for each cell. */ -std::vector Cell2Fire::getROSMatrix(){ - std::vector ROSMatrix (this->nCells, 0); - return ROSMatrix; +std::vector +Cell2Fire::getROSMatrix() +{ + std::vector ROSMatrix(this->nCells, 0); + return ROSMatrix; } - /** * @brief Retrieves the Fire Progress matrix for all cells. * - * @return A vector of floats representing the fire progress values for each cell. + * @return A vector of floats representing the fire progress values for each + * cell. */ -std::vector Cell2Fire::getFireProgressMatrix(){ - std::vector ProgressMatrix (this->nCells, 0); - return ProgressMatrix; +std::vector +Cell2Fire::getFireProgressMatrix() +{ + std::vector ProgressMatrix(this->nCells, 0); + return ProgressMatrix; } - /****************************************************************************** - Main Program + Main Program *******************************************************************************/ /** @@ -1944,86 +2378,98 @@ std::vector Cell2Fire::getFireProgressMatrix(){ * * This function initializes the simulation environment, reads input arguments, * and executes the main simulation loop, either in serial or parallel mode. - * The program simulates fire spread across a forest landscape using stochastic methods. + * The program simulates fire spread across a forest landscape using stochastic + * methods. * * @return Exit status of the program (0 for success). * * The main tasks performed include: * - Parsing command-line arguments. * - Initializing the forest simulation object and random number generators. - * - Executing simulation episodes in parallel, with each episode representing a replication. - * - Resetting the environment and running simulation steps until completion conditions are met. + * - Executing simulation episodes in parallel, with each episode representing + * a replication. + * - Resetting the environment and running simulation steps until completion + * conditions are met. * - Handling multi-threading for parallel simulations. * */ -int main(int argc, char* argv[]) { - // Read Arguments - std::cout << "------ Command line values ------\n"; - arguments args; - arguments* args_ptr = &args; - parseArgs(argc, argv, args_ptr); - GenDataFile(args.InFolder,args.Simulator); - int ep = 0; - int tstep = 0; - int stop = 0; - // Episodes loop (episode = replication) - // CP: Modified to account the case when no ignition occurs and no grids are generated (currently we are not generating grid when no ignition happened, TODO) - int num_threads = args.nthreads; - int TID = 0; - Cell2Fire Forest2(args); //generate Forest object - std::vector Forests(num_threads, Forest2); - - // Multigenerator - std::vector generators; - for (stop = 0; stop < args.TotalSims; ++stop) { - generators.emplace_back(default_random_engine(args.seed * stop)); - } - - // Parallel zone - #pragma omp parallel num_threads(num_threads) - { - // Number of threads - TID = omp_get_thread_num(); - if (TID == 0 && omp_get_num_threads() < 2) { - cout << "There are " << omp_get_num_threads() << " threads" << endl; - } - else { - cout << "Serial version execution" << endl; - } - Cell2Fire Forest = Forests[TID]; - // Random seed - std::default_random_engine& generator = generators[TID]; //generators[args.nthreads] - // Random generator and distributions - std::uniform_int_distribution udistribution(1, args.NWeatherFiles); // Get random weather - std::normal_distribution ndistribution(0.0, 1.0); // ROSRV - // Random numbers (weather file and ROS-CV) - int rnumber; - double rnumber2; - std::uniform_int_distribution udistributionIgnition(1, Forest.nCells); // Get random ignition point - // Steps and stop - int ep = 0; - int tstep = 0; - int stop = 0; - #pragma omp for - for (ep = 1; ep <= args.TotalSims; ep++) { - TID = omp_get_thread_num(); - // Reset environment (passing new random numbers) - generator = generators[TID]; //generators[args.nthreads] - rnumber = udistribution(generator); - rnumber2 = ndistribution(generator); - // Reset - Forest.reset(rnumber, rnumber2, ep); - // Time steps during horizon (or until we break it) - for (tstep = 0; tstep <= Forest.args.MaxFirePeriods * Forest.args.TotalYears; tstep++) { - Forest.Step(generator, ep); - - if (Forest.done) { - break; - } - } - } - } - delete [] df; - return 0; -} +int +main(int argc, char* argv[]) +{ + // Read Arguments + std::cout << "------ Command line values ------\n"; + arguments args; + arguments* args_ptr = &args; + parseArgs(argc, argv, args_ptr); + GenDataFile(args.InFolder, args.Simulator); + int ep = 0; + int tstep = 0; + int stop = 0; + // Episodes loop (episode = replication) + // CP: Modified to account the case when no ignition occurs and no grids are + // generated (currently we are not generating grid when no ignition happened, + // TODO) + int num_threads = args.nthreads; + int TID = 0; + Cell2Fire Forest2(args); // generate Forest object + std::vector Forests(num_threads, Forest2); + + // Multigenerator + std::vector generators; + for (stop = 0; stop < args.TotalSims; ++stop) + { + generators.emplace_back(default_random_engine(args.seed * stop)); + } +// Parallel zone +#pragma omp parallel num_threads(num_threads) + { + // Number of threads + TID = omp_get_thread_num(); + if (TID == 0 && omp_get_num_threads() < 2) + { + cout << "There are " << omp_get_num_threads() << " threads" << endl; + } + else + { + cout << "Serial version execution" << endl; + } + Cell2Fire Forest = Forests[TID]; + // Random seed + std::default_random_engine& generator = generators[TID]; // generators[args.nthreads] + // Random generator and distributions + std::uniform_int_distribution udistribution(1, args.NWeatherFiles); // Get random weather + std::normal_distribution ndistribution(0.0, 1.0); // ROSRV + // Random numbers (weather file and ROS-CV) + int rnumber; + double rnumber2; + std::uniform_int_distribution udistributionIgnition(1, Forest.nCells); // Get random ignition point + // Steps and stop + int ep = 0; + int tstep = 0; + int stop = 0; +#pragma omp for + for (ep = 1; ep <= args.TotalSims; ep++) + { + TID = omp_get_thread_num(); + // Reset environment (passing new random numbers) + generator = generators[TID]; // generators[args.nthreads] + rnumber = udistribution(generator); + rnumber2 = ndistribution(generator); + // Reset + Forest.reset(rnumber, rnumber2, ep); + // Time steps during horizon (or until we break it) + for (tstep = 0; tstep <= Forest.args.MaxFirePeriods * Forest.args.TotalYears; tstep++) + { + Forest.Step(generator, ep); + + if (Forest.done) + { + break; + } + } + } + } + delete[] df; + return 0; +} diff --git a/Cell2Fire/Cell2Fire.h b/Cell2Fire/Cell2Fire.h index 4ee04159..42846016 100644 --- a/Cell2Fire/Cell2Fire.h +++ b/Cell2Fire/Cell2Fire.h @@ -3,139 +3,139 @@ // Headers #include "Cells.h" -#include "Spotting.h" -#include "FuelModelSpain.h" +#include "DataGenerator.h" #include "FuelModelKitral.h" +#include "FuelModelSpain.h" +#include "Lightning.h" +#include "ReadArgs.h" #include "ReadCSV.h" +#include "Spotting.h" #include "WriteCSV.h" -#include "ReadArgs.h" -#include "Lightning.h" -#include "DataGenerator.h" // Include libraries +#include +#include +#include +#include +#include +#include #include #include +#include #include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include +#include using namespace std; -class Cell2Fire { - // DFs - private: - CSVReader CSVWeather; - CSVReader CSVForest; - - public: - // Main inputs - arguments args; - arguments* args_ptr; - fuel_coefs* coef_ptr; - fuel_coefs coefs[18]; - - // Integers - int sim; - int rows; - int cols; - int widthSims; - int weatherPeriod = 0; - int year = 1; - int gridNumber = 0; - int weatherperiod = 0; - int counter_wt = 0; - long int nCells; - int nIgnitions = 0; - double xllcorner; - double yllcorner; - // Booleans - bool noIgnition = true; // None = -1 - bool activeCrown=false; - bool messagesSent = false; - bool repeatFire = false; - bool done = false; - bool noMessages = false; - - // Doubles - double cellSide; - double areaCells; - double perimeterCells; - double ROSRV; - - // Strings - string gridFolder; - string messagesFolder; - string rosFolder; - string crownFolder; - string intensityFolder; - string sfbFolder; - string cfbFolder; - string flFolder; - string historyFolder; - string ignitionsFolder; - - // Vectors - std::vector fire_period; - std::vector> coordCells; - std::vector> adjCells; - std::vector> DF; - std::vector> WDist; - std::vector WeatherHistory; - std::vector ignProb; // (long int&, int); - std::vector statusCells; //(long int, int); - std::vector fTypeCells; // (long int&, int); - std::vector fTypeCells2; // (long int&, const char [9]); - std::vector> WeatherDF; - std::vector IgnitionPoints; - vector burnedOutList; - std::vector FSCell; - std::vector crownMetrics; - std::vectorcrownState; - std::vectorIntensities; - std::vectorcrownFraction; - std::vectorsurfFraction; - std::vectorRateOfSpreads; - std::vectorFlameLengths; - std::vector> IgnitionSets; - // std::vector IgnitionHistory; +class Cell2Fire +{ + // DFs + private: + CSVReader CSVWeather; + CSVReader CSVForest; + + public: + // Main inputs + arguments args; + arguments* args_ptr; + fuel_coefs* coef_ptr; + fuel_coefs coefs[18]; + + // Integers + int sim; + int rows; + int cols; + int widthSims; + int weatherPeriod = 0; + int year = 1; + int gridNumber = 0; + int weatherperiod = 0; + int counter_wt = 0; + long int nCells; + int nIgnitions = 0; + double xllcorner; + double yllcorner; + // Booleans + bool noIgnition = true; // None = -1 + bool activeCrown = false; + bool messagesSent = false; + bool repeatFire = false; + bool done = false; + bool noMessages = false; + + // Doubles + double cellSide; + double areaCells; + double perimeterCells; + double ROSRV; + + // Strings + string gridFolder; + string messagesFolder; + string rosFolder; + string crownFolder; + string intensityFolder; + string sfbFolder; + string cfbFolder; + string flFolder; + string historyFolder; + string ignitionsFolder; + + // Vectors + std::vector fire_period; + std::vector> coordCells; + std::vector> adjCells; + std::vector> DF; + std::vector> WDist; + std::vector WeatherHistory; + std::vector ignProb; // (long int&, int); + std::vector statusCells; //(long int, int); + std::vector fTypeCells; // (long int&, int); + std::vector fTypeCells2; // (long int&, const char [9]); + std::vector> WeatherDF; + std::vector IgnitionPoints; + vector burnedOutList; + std::vector FSCell; + std::vector crownMetrics; + std::vector crownState; + std::vector Intensities; + std::vector crownFraction; + std::vector surfFraction; + std::vector RateOfSpreads; + std::vector FlameLengths; + std::vector> IgnitionSets; + // std::vector IgnitionHistory; + + // Sets + std::unordered_set availCells; + std::unordered_set nonBurnableCells; + std::unordered_set burningCells; + std::unordered_set burntCells; + std::unordered_set harvestCells; + + // Cells Dictionary + std::unordered_map Cells_Obj; + + // Constructor + Cell2Fire(arguments args); + + // Methods + void InitCell(int id); + void reset(int rnumber, double rnumber2, int simExt); + bool RunIgnition(std::default_random_engine generator, int ep); + std::unordered_map> SendMessages(); + void GetMessages(std::unordered_map> sendMessageList); + void Results(); + void outputGrid(); + void updateWeather(); + void Step(std::default_random_engine generator, int ep); + void InitHarvested(); - // Sets - std::unordered_set availCells; - std::unordered_set nonBurnableCells; - std::unordered_set burningCells; - std::unordered_set burntCells; - std::unordered_set harvestCells; - - // Cells Dictionary - std::unordered_map Cells_Obj; - - // Constructor - Cell2Fire(arguments args); - - // Methods - void InitCell(int id); - void reset(int rnumber, double rnumber2, int simExt); - bool RunIgnition(std::default_random_engine generator, int ep); - std::unordered_map> SendMessages(); - void GetMessages(std::unordered_map> sendMessageList); - void Results(); - void outputGrid(); - void updateWeather(); - void Step(std::default_random_engine generator, int ep); - void InitHarvested(); - - // Utils - std::vector getROSMatrix(); - std::vector getFireProgressMatrix(); + // Utils + std::vector getROSMatrix(); + std::vector getFireProgressMatrix(); }; #endif diff --git a/Cell2Fire/Cells.cpp b/Cell2Fire/Cells.cpp index dcd83759..f0220546 100644 --- a/Cell2Fire/Cells.cpp +++ b/Cell2Fire/Cells.cpp @@ -1,25 +1,24 @@ // Include classes #include "Cells.h" -#include "Spotting.h" -#include "FuelModelSpain.h" -#include "FuelModelKitral.h" +#include "Ellipse.h" #include "FuelModelFBP.h" -#include "ReadCSV.h" +#include "FuelModelKitral.h" +#include "FuelModelSpain.h" #include "ReadArgs.h" -#include "Ellipse.h" +#include "ReadCSV.h" +#include "Spotting.h" // Include libraries +#include +#include +#include +#include #include #include +#include #include -#include -#include -#include -#include #include #include -#include -#include -#include +#include // #define RAND_MAX 0.5 using namespace std; @@ -27,313 +26,341 @@ using namespace std; /** * @brief Constructs a Cell object for the wildfire simulation. * - * Initializes the cell's properties, such as its unique identifier, geographical attributes, - * fuel type, fire status, and other internal parameters used in the simulation. - * Validates the cell's area and perimeter consistency during initialization. + * Initializes the cell's properties, such as its unique identifier, + * geographical attributes, fuel type, fire status, and other internal + * parameters used in the simulation. Validates the cell's area and perimeter + * consistency during initialization. * * @param _id The unique identifier for the cell (0 to size of landscape - 1). * @param _area The area of the cell. - * @param _coord The coordinates of the cell, represented as a vector of integers. - * @param _fType The primary fuel type of the cell (0: NonBurnable, 1: Normal, 2: Burnable). + * @param _coord The coordinates of the cell, represented as a vector of + * integers. + * @param _fType The primary fuel type of the cell (0: NonBurnable, 1: Normal, + * 2: Burnable). * @param _fType2 The secondary fuel type as a descriptive string. * @param _perimeter The perimeter of the cell. - * @param _status The fire status of the cell (0: Available, 1: Burning, 2: Burnt, 3: Harvested, 4: Non Fuel). - * @param _realId Alternative identifier of the cell (1 to size of the landscape). + * @param _status The fire status of the cell (0: Available, 1: Burning, 2: + * Burnt, 3: Harvested, 4: Non Fuel). + * @param _realId Alternative identifier of the cell (1 to size of the + * landscape). */ -Cells::Cells(int _id, double _area, std::vector _coord, - int _fType, std::string _fType2, double _perimeter, - int _status, int _realId) +Cells::Cells(int _id, + double _area, + std::vector _coord, + int _fType, + std::string _fType2, + double _perimeter, + int _status, + int _realId) { - // Global "dictionaries" (vectors) for status and types - // Status: 0: "Available", 1: "Burning", 2: "Burnt", 3: "Harvested", 4:"Non Fuel" - this->StatusD[0] = "Available"; - this->StatusD[1] = "Burning"; - this->StatusD[2] = "Burnt"; - this->StatusD[3] = "Harvested"; - this->StatusD[4] = "Non Fuel"; - - // FTypeD: 0: "NonBurnable", 1: "Normal", 2: "Burnable - this->FTypeD[0] = "NonBurnable"; - this->FTypeD[1] = "Normal"; - this->FTypeD[2] = "Burnable"; - - // Initialize fields of the Cell object - this->id = _id; // identifier for programming purposes: goes from 0 to size of landscape-1 - this->area = _area; - this->coord = _coord; - this->fType = _fType; - this->fType2 = _fType2; - this->perimeter = _perimeter; - this->status = _status; - this->realId = _realId; // real identifier of the landscape (goes from 1 to the size of the landscape) - this->_ctr2ctrdist = std::sqrt(this->area); - - if (std::abs(4 * this->_ctr2ctrdist - this->perimeter) > 0.01 * this->perimeter) - { - std::cerr << "Cell ID=" << this->id << "Area=" << this->area << "Perimeter=" << this->perimeter << std::endl; - // maybe raise runtime error - } - - // Inner fields - this->gMsgList = std::unordered_map>(); - this->hPeriod = 0; - - this->fireStarts = 0; - this->harvestStarts = 0; - this->fireStartsSeason = 0; - this->tYears = 4; - - this->gMsgListSeason = std::unordered_map>(); - this->fireProgress = std::unordered_map(); - this->angleDict = std::unordered_map(); - this->ROSAngleDir = std::unordered_map(); - this->distToCenter = std::unordered_map(); - this->angleToNb = std::unordered_map(); + // Global "dictionaries" (vectors) for status and types + // Status: 0: "Available", 1: "Burning", 2: "Burnt", 3: "Harvested", 4:"Non + // Fuel" + this->StatusD[0] = "Available"; + this->StatusD[1] = "Burning"; + this->StatusD[2] = "Burnt"; + this->StatusD[3] = "Harvested"; + this->StatusD[4] = "Non Fuel"; + + // FTypeD: 0: "NonBurnable", 1: "Normal", 2: "Burnable + this->FTypeD[0] = "NonBurnable"; + this->FTypeD[1] = "Normal"; + this->FTypeD[2] = "Burnable"; + + // Initialize fields of the Cell object + this->id = _id; // identifier for programming purposes: goes from 0 to size + // of landscape-1 + this->area = _area; + this->coord = _coord; + this->fType = _fType; + this->fType2 = _fType2; + this->perimeter = _perimeter; + this->status = _status; + this->realId = _realId; // real identifier of the landscape (goes from 1 to + // the size of the landscape) + this->_ctr2ctrdist = std::sqrt(this->area); + + if (std::abs(4 * this->_ctr2ctrdist - this->perimeter) > 0.01 * this->perimeter) + { + std::cerr << "Cell ID=" << this->id << "Area=" << this->area << "Perimeter=" << this->perimeter << std::endl; + // maybe raise runtime error + } + + // Inner fields + this->gMsgList = std::unordered_map>(); + this->hPeriod = 0; + + this->fireStarts = 0; + this->harvestStarts = 0; + this->fireStartsSeason = 0; + this->tYears = 4; + + this->gMsgListSeason = std::unordered_map>(); + this->fireProgress = std::unordered_map(); + this->angleDict = std::unordered_map(); + this->ROSAngleDir = std::unordered_map(); + this->distToCenter = std::unordered_map(); + this->angleToNb = std::unordered_map(); } /** * @brief Initializes fire-related fields for the cell during ignition. * - * Populates the angles and distances to adjacent cells, and initializes the Rate of Spread (ROS) per axis - * using cell area to compute distances in meters. Initializes the internal dictionaries used for managing - * fire spread to the cell's neighbors. + * Populates the angles and distances to adjacent cells, and initializes the + * Rate of Spread (ROS) per axis using cell area to compute distances in + * meters. Initializes the internal dictionaries used for managing fire spread + * to the cell's neighbors. * - * @param coordCells A 2D vector representing the coordinates of all cells in the landscape. - * @param availSet A set of available cells that can participate in fire spread. + * @param coordCells A 2D vector representing the coordinates of all cells in + * the landscape. + * @param availSet A set of available cells that can participate in fire + * spread. * @param cols The number of columns in the grid. * @param rows The number of rows in the grid. * * @return void */ -void Cells::initializeFireFields(std::vector> &coordCells, // TODO: should probably make a coordinate type - std::unordered_set &availSet, int cols, int rows) // WORKING CHECK OK +void +Cells::initializeFireFields(std::vector>& coordCells, // TODO: should probably make a coordinate type + std::unordered_set& availSet, + int cols, + int rows) // WORKING CHECK OK { - std::vector adj = adjacentCells(this->realId, rows, cols); - - for (auto &nb : adj) - { - // CP Default value is replaced: None = -1 - // std::cout << "DEBUG1: adjacent: " << nb.second << std::endl; - if (nb != -1) - { - int a = -1 * coordCells[nb - 1][0] + coordCells[this->id][0]; - int b = -1 * coordCells[nb - 1][1] + coordCells[this->id][1]; - - int angle = -1; - if (a == 0) - { - if (b >= 0) - angle = 270; - else - angle = 90; - } - else if (b == 0) - { - if (a >= 0) - angle = 180; - else - angle = 0; - } - else - { - // TODO: check this logi - double radToDeg = 180 / M_PI; - // TODO: i think all the negatives and abs cancel out - double temp = std::atan(b * 1.0 / a) * radToDeg; - if (a > 0) - temp += 180; - if (a < 0 && b > 0) - temp += 360; - angle = temp; - } - this->angleDict[nb] = angle; - if (availSet.find(nb) != availSet.end()) - { - // TODO: cannot be None, replaced None = -1 and ROSAngleDir has a double inside - this->ROSAngleDir[angle] = -1; - } - this->angleToNb[angle] = nb; - this->fireProgress[nb] = 0.0; - this->distToCenter[nb] = std::sqrt(a * a + b * b) * this->_ctr2ctrdist; - } - } + std::vector adj = adjacentCells(this->realId, rows, cols); + + for (auto& nb : adj) + { + // CP Default value is replaced: None = -1 + // std::cout << "DEBUG1: adjacent: " << nb.second << std::endl; + if (nb != -1) + { + int a = -1 * coordCells[nb - 1][0] + coordCells[this->id][0]; + int b = -1 * coordCells[nb - 1][1] + coordCells[this->id][1]; + + int angle = -1; + if (a == 0) + { + if (b >= 0) + angle = 270; + else + angle = 90; + } + else if (b == 0) + { + if (a >= 0) + angle = 180; + else + angle = 0; + } + else + { + // TODO: check this logi + double radToDeg = 180 / M_PI; + // TODO: i think all the negatives and abs cancel out + double temp = std::atan(b * 1.0 / a) * radToDeg; + if (a > 0) + temp += 180; + if (a < 0 && b > 0) + temp += 360; + angle = temp; + } + this->angleDict[nb] = angle; + if (availSet.find(nb) != availSet.end()) + { + // TODO: cannot be None, replaced None = -1 and ROSAngleDir has + // a double inside + this->ROSAngleDir[angle] = -1; + } + this->angleToNb[angle] = nb; + this->fireProgress[nb] = 0.0; + this->distToCenter[nb] = std::sqrt(a * a + b * b) * this->_ctr2ctrdist; + } + } } /** * @brief Calculates the neighboring cells in the grid. * - * Returns the indices of the eight neighboring cells (north, south, east, west, northeast, southeast, southwest, northwest) - * for the cell in a grid defined by the number of rows and columns. If a neighbor does not exist + * Returns the indices of the eight neighboring cells (north, south, east, + * west, northeast, southeast, southwest, northwest) for the cell in a grid + * defined by the number of rows and columns. If a neighbor does not exist * (e.g., out of bounds), it is marked as -1. * * @param cell The index of the current cell (1-based index). * @param nrows The number of rows in the grid. * @param ncols The number of columns in the grid. * - * @return A vector of integers representing the indices of the adjacent cells. Each index corresponds to a neighbor: - * {west, east, southwest, southeast, south, northwest, northeast, north}. Missing neighbors are represented by -1. + * @return A vector of integers representing the indices of the adjacent cells. + * Each index corresponds to a neighbor: {west, east, southwest, southeast, + * south, northwest, northeast, north}. Missing neighbors are represented by + * -1. */ -std::vector adjacentCells(int cell, int nrows, int ncols) +std::vector +adjacentCells(int cell, int nrows, int ncols) { - if (cell <= 0 || cell > nrows * ncols) - { - std::vector adjacents(8, -1); - return adjacents; - } - int total_cells = nrows * ncols; - int north = cell <= ncols ? -1 : cell - ncols; - int south = cell + ncols > total_cells ? -1 : cell + ncols; - int east = cell % ncols == 0 ? -1 : cell + 1; - int west = cell % ncols == 1 ? -1 : cell - 1; - int northeast = cell < ncols || cell % ncols == 0 ? -1 : cell - ncols + 1; - int southeast = cell + ncols > total_cells || cell % ncols == 0 ? -1 : cell + ncols + 1; - int southwest = cell % ncols == 1 || cell + ncols > total_cells ? -1 : cell + ncols - 1; - int northwest = cell % ncols == 1 || cell < ncols ? -1 : cell - ncols - 1; - std::vector adjacents = {west, east, southwest, southeast, south, northwest, northeast, north}; - return adjacents; + if (cell <= 0 || cell > nrows * ncols) + { + std::vector adjacents(8, -1); + return adjacents; + } + int total_cells = nrows * ncols; + int north = cell <= ncols ? -1 : cell - ncols; + int south = cell + ncols > total_cells ? -1 : cell + ncols; + int east = cell % ncols == 0 ? -1 : cell + 1; + int west = cell % ncols == 1 ? -1 : cell - 1; + int northeast = cell < ncols || cell % ncols == 0 ? -1 : cell - ncols + 1; + int southeast = cell + ncols > total_cells || cell % ncols == 0 ? -1 : cell + ncols + 1; + int southwest = cell % ncols == 1 || cell + ncols > total_cells ? -1 : cell + ncols - 1; + int northwest = cell % ncols == 1 || cell < ncols ? -1 : cell - ncols - 1; + std::vector adjacents = { west, east, southwest, southeast, south, northwest, northeast, north }; + return adjacents; } /* - New functions for calculating the ROS based on the fire angles - Distribute the rate of spread (ROS,ros) to the axes given in the AngleList. - All angles are w.t.r. E-W with East positive and in non-negative degrees. - Inputs: - thetafire: direction of "forward" - forward : forward ROS - flank: ROS normal to forward (on both sides) - back: ROS in the opposide direction of forward - AngleList: List of angles for the axes connecting centers - of interest (might have less than 8 angles) - Effect: - Populate the ROSAngleDir, whose indexes are the angles, - with ROS values. - - Returns void + New functions for calculating the ROS based on the fire angles + Distribute the rate of spread (ROS,ros) to the axes given in the + AngleList. All angles are w.t.r. E-W with East positive and in non-negative + degrees. Inputs: thetafire: direction of "forward" forward : forward ROS + flank: ROS normal to forward (on both sides) + back: ROS in the opposide direction of forward + AngleList: List of angles for the axes connecting + centers of interest (might have less than 8 angles) Effect: Populate the + ROSAngleDir, whose indexes are the angles, with ROS values. + + Returns void */ /** - * - * @param thetafire - * @param forward - * @param flank - * @param back + * + * @param thetafire + * @param forward + * @param flank + * @param back */ -void Cells::ros_distr_old(double thetafire, double forward, double flank, double back) -{ // WORKING CHECK OK - for (auto &angle : this->ROSAngleDir) - { - double offset = std::abs(angle.first - thetafire); - - double base = ((int)(offset)) / 90 * 90; - double result; - - // Distribute ROS - if (offset >= 0 && offset <= 90) - { - result = this->allocate(offset, 0, forward, flank); - } - else if (offset > 90 && offset < 180) - { - result = this->allocate(offset, 90, flank, back); - } - else if (offset >= 180 && offset <= 270) - { - result = this->allocate(offset, 180, back, flank); - } - else if (offset > 270 && offset < 360) - { - result = this->allocate(offset, 270, flank, forward); - } - this->ROSAngleDir[angle.first] = result; - } +void +Cells::ros_distr_old(double thetafire, double forward, double flank, double back) +{ // WORKING CHECK OK + for (auto& angle : this->ROSAngleDir) + { + double offset = std::abs(angle.first - thetafire); + + double base = ((int)(offset)) / 90 * 90; + double result; + + // Distribute ROS + if (offset >= 0 && offset <= 90) + { + result = this->allocate(offset, 0, forward, flank); + } + else if (offset > 90 && offset < 180) + { + result = this->allocate(offset, 90, flank, back); + } + else if (offset >= 180 && offset <= 270) + { + result = this->allocate(offset, 180, back, flank); + } + else if (offset > 270 && offset < 360) + { + result = this->allocate(offset, 270, flank, forward); + } + this->ROSAngleDir[angle.first] = result; + } } /** - * @brief Calculates the radial distance for a given angle in an ellipse defined by its semi-major and semi-minor axes. + * @brief Calculates the radial distance for a given angle in an ellipse + * defined by its semi-major and semi-minor axes. * - * Computes the distance from the center of an ellipse to its perimeter at a specified angle using the polar equation - * of an ellipse. The semi-major axis (`a`) and semi-minor axis (`b`) define the ellipse's geometry. + * Computes the distance from the center of an ellipse to its perimeter at a + * specified angle using the polar equation of an ellipse. The semi-major axis + * (`a`) and semi-minor axis (`b`) define the ellipse's geometry. * * @param theta The angle (in degrees) from the ellipse's major axis. * @param a The length of the semi-major axis of the ellipse. * @param b The length of the semi-minor axis of the ellipse. * - * @return The radial distance from the ellipse's center to its perimeter at the given angle. + * @return The radial distance from the ellipse's center to its perimeter at + * the given angle. */ -double Cells::rhoTheta(double theta, double a, double b) +double +Cells::rhoTheta(double theta, double a, double b) { - const double pi = 3.141592653589793; + const double pi = 3.141592653589793; - double c2, e, r1, r2, r; + double c2, e, r1, r2, r; - c2 = std::pow(a, 2) - std::pow(b, 2); - e = std::sqrt(c2) / a; + c2 = std::pow(a, 2) - std::pow(b, 2); + e = std::sqrt(c2) / a; - r1 = a * (1 - std::pow(e, 2)); - r2 = 1 - e * std::cos(theta * pi / 180.0); - r = r1 / r2; - return r; + r1 = a * (1 - std::pow(e, 2)); + r2 = 1 - e * std::cos(theta * pi / 180.0); + r = r1 / r2; + return r; } /** - * - * @param thetafire - * @param forward - * @param flank - * @param back - * @param EFactor + * + * @param thetafire + * @param forward + * @param flank + * @param back + * @param EFactor */ -void Cells::ros_distr(double thetafire, double forward, double flank, double back, double EFactor) -{ // WORKING CHECK OK - - // Ellipse points - // std::cout << "Dentro de ROS dist" << std::endl; - // std::cout << "thetafire:" << thetafire << std::endl; - // std::cout << "forward:" << forward << std::endl; - // std::cout << "flank:" << flank << std::endl; - // std::cout << "back:" << back << std::endl; - // std::cout << "EFactor:" << EFactor << std::endl; - - // std::cout << "Previo Data" << std::endl; - double a = (forward + back) / 2; - double b; - std::vector _x = {0.0, back, back, (forward + back) / 2., (forward + back) / 2., (forward + back)}; - std::vector _y = {0.0, std::pow(flank, 2) / a, -(std::pow(flank, 2) / a), flank, -flank, 0.0}; - // std::cout << "Post data" << std::endl; - - // Fit the Ellipse - // std::cout << "Previo Ellipse" << std::endl; - Ellipse SqlEllipse(_x, _y); // DEBUGGING - // std::cout << "Inicializo" << std::endl; - std::vector params = SqlEllipse.get_parameters(); - a = params[0]; - b = params[1]; - - // std::cout << "a:" << a << std::endl; - // std::cout << "b:" << b << std::endl; - - // Ros allocation for each angle inside the dictionary - for (auto &angle : this->ROSAngleDir) - { - double offset = angle.first - thetafire; - - if (offset < 0) - { - offset += 360; - } - if (offset > 360) - { - offset -= 360; - } - this->ROSAngleDir[angle.first] = rhoTheta(offset, a, b) * EFactor; - } +void +Cells::ros_distr(double thetafire, double forward, double flank, double back, double EFactor) +{ // WORKING CHECK OK + + // Ellipse points + // std::cout << "Dentro de ROS dist" << std::endl; + // std::cout << "thetafire:" << thetafire << std::endl; + // std::cout << "forward:" << forward << std::endl; + // std::cout << "flank:" << flank << std::endl; + // std::cout << "back:" << back << std::endl; + // std::cout << "EFactor:" << EFactor << std::endl; + + // std::cout << "Previo Data" << std::endl; + double a = (forward + back) / 2; + double b; + std::vector _x = { 0.0, back, back, (forward + back) / 2., (forward + back) / 2., (forward + back) }; + std::vector _y = { 0.0, std::pow(flank, 2) / a, -(std::pow(flank, 2) / a), flank, -flank, 0.0 }; + // std::cout << "Post data" << std::endl; + + // Fit the Ellipse + // std::cout << "Previo Ellipse" << std::endl; + Ellipse SqlEllipse(_x, _y); // DEBUGGING + // std::cout << "Inicializo" << std::endl; + std::vector params = SqlEllipse.get_parameters(); + a = params[0]; + b = params[1]; + + // std::cout << "a:" << a << std::endl; + // std::cout << "b:" << b << std::endl; + + // Ros allocation for each angle inside the dictionary + for (auto& angle : this->ROSAngleDir) + { + double offset = angle.first - thetafire; + + if (offset < 0) + { + offset += 360; + } + if (offset > 360) + { + offset -= 360; + } + this->ROSAngleDir[angle.first] = rhoTheta(offset, a, b) * EFactor; + } } /** - * @brief Distributes the Rate of Spread (ROS) across the cell's neighbors based on fire direction and ellipse geometry. + * @brief Distributes the Rate of Spread (ROS) across the cell's neighbors + * based on fire direction and ellipse geometry. * - * Updates the ROS for each neighbor in the `ROSAngleDir` dictionary using an elliptical model. The ROS is scaled by - * the elliptical geometry parameters and a factor (`EFactor`), with adjustments based on the - * fire's heading direction. + * Updates the ROS for each neighbor in the `ROSAngleDir` dictionary using an + * elliptical model. The ROS is scaled by the elliptical geometry parameters + * and a factor (`EFactor`), with adjustments based on the fire's heading + * direction. * * @param thetafire The direction of the fire's spread (in degrees). * @param a The semi-major axis of the ellipse representing fire spread. @@ -342,626 +369,727 @@ void Cells::ros_distr(double thetafire, double forward, double flank, double bac * * @return void */ -void Cells::ros_distr_V2(double thetafire, double a, double b, double c, double EFactor) +void +Cells::ros_distr_V2(double thetafire, double a, double b, double c, double EFactor) { - // Ros allocation for each angle inside the dictionary - for (auto &angle : this->ROSAngleDir) - { - double offset = angle.first - thetafire; - - if (offset < 0) - { - offset += 360; - } - if (offset > 360) - { - offset -= 360; - } - this->ROSAngleDir[angle.first] = rhoTheta(offset, a, b) * EFactor; - } + // Ros allocation for each angle inside the dictionary + for (auto& angle : this->ROSAngleDir) + { + double offset = angle.first - thetafire; + + if (offset < 0) + { + offset += 360; + } + if (offset > 360) + { + offset -= 360; + } + this->ROSAngleDir[angle.first] = rhoTheta(offset, a, b) * EFactor; + } } - -double Cells::allocate(double offset, double base, double ros1, double ros2) -{ // WORKING CHECK OK - double d = (offset - base) / 90; - return (1 - d) * ros1 + d * ros2; +double +Cells::allocate(double offset, double base, double ros1, double ros2) +{ // WORKING CHECK OK + double d = (offset - base) / 90; + return (1 - d) * ros1 + d * ros2; } /** -* @brief Calculates the cell's slope effect -* -* @param elev_i elevation of burning cell -* @param elev_j elevation of cell reached by fire -* @param cellsize side of a cell -*/ + * @brief Calculates the cell's slope effect + * + * @param elev_i elevation of burning cell + * @param elev_j elevation of cell reached by fire + * @param cellsize side of a cell + */ -float Cells::slope_effect(float elev_i, float elev_j, int cellsize) +float +Cells::slope_effect(float elev_i, float elev_j, int cellsize) { - float ps_ij = (elev_j - elev_i) / cellsize; - float se; - se = 1. + 0.023322 * ps_ij + 0.00013585 * std::pow(ps_ij, 2); + float ps_ij = (elev_j - elev_i) / cellsize; + float se; + se = 1. + 0.023322 * ps_ij + 0.00013585 * std::pow(ps_ij, 2); - return se; + return se; } /** * @brief Manage's the cell's response to being reached by fire. * - * Calculates fire dynamics such as rate of spread (ROS), intensity, flame length, and other metrics based - * on the simulation's parameters and environmental inputs. It determines if the cell begins to spread fire, - * if so, messages are sent to neighboring cells. It also logs fire metrics for further analysis. + * Calculates fire dynamics such as rate of spread (ROS), intensity, flame + * length, and other metrics based on the simulation's parameters and + * environmental inputs. It determines if the cell begins to spread fire, if + * so, messages are sent to neighboring cells. It also logs fire metrics for + * further analysis. * * @param period Current simulation period or timestep. - * @param AvailSet A set of available cells in the simulation (unused in this function, included for compatibility). + * @param AvailSet A set of available cells in the simulation (unused in this + * function, included for compatibility). * @param df_ptr Array containing cell-specific environmental and fuel data. - * @param coef Pointer to a structure containing fuel coefficients used in ROS calculations. + * @param coef Pointer to a structure containing fuel coefficients used in ROS + * calculations. * @param coordCells A vector of coordinate mappings for the cells. - * @param Cells_Obj A mapping of cell IDs to their corresponding `Cells` objects. - * @param args Pointer to a structure containing global simulation arguments and configurations. - * @param wdf_ptr Pointer to the weather data structure containing wind speed, direction, and other weather variables. - * @param FSCell A vector to store fire spread information, including source cell, target cell, period, and ROS values. - * @param crownMetrics A vector to store metrics related to crown fire behavior. - * @param activeCrown A boolean reference indicating whether crown fire activity is ongoing. - * @param randomROS A random value applied to ROS calculations when stochasticity is enabled. + * @param Cells_Obj A mapping of cell IDs to their corresponding `Cells` + * objects. + * @param args Pointer to a structure containing global simulation arguments + * and configurations. + * @param wdf_ptr Pointer to the weather data structure containing wind speed, + * direction, and other weather variables. + * @param FSCell A vector to store fire spread information, including source + * cell, target cell, period, and ROS values. + * @param crownMetrics A vector to store metrics related to crown fire + * behavior. + * @param activeCrown A boolean reference indicating whether crown fire + * activity is ongoing. + * @param randomROS A random value applied to ROS calculations when + * stochasticity is enabled. * @param perimeterCells Cell size, perimeter of a cell. * @param crownState A vector tracking the crown fire state of each cell. - * @param crownFraction A vector tracking the fraction of fire in the crown layer for each cell. - * @param surfFraction A vector tracking the fraction of fire in the surface layer for each cell. + * @param crownFraction A vector tracking the fraction of fire in the crown + * layer for each cell. + * @param surfFraction A vector tracking the fraction of fire in the surface + * layer for each cell. * @param Intensities A vector tracking the fire intensity for each cell. * @param RateOfSpreads A vector tracking the rate of spread for each cell. * @param FlameLengths A vector tracking the flame length for each cell. * - * @return A vector of integers representing the list of neighboring cells that should receive a message indicating fire has reached them. + * @return A vector of integers representing the list of neighboring cells that + * should receive a message indicating fire has reached them. */ -std::vector Cells::manageFire(int period, std::unordered_set &AvailSet, - inputs df_ptr[], fuel_coefs *coef, - std::vector> &coordCells, std::unordered_map &Cells_Obj, - arguments *args, weatherDF *wdf_ptr, std::vector *FSCell, std::vector *crownMetrics, - bool &activeCrown, double randomROS, int perimeterCells, std::vector &crownState, std::vector &crownFraction, std::vector &surfFraction, std::vector &Intensities, std::vector &RateOfSpreads, std::vector &FlameLengths) +std::vector +Cells::manageFire(int period, + std::unordered_set& AvailSet, + inputs df_ptr[], + fuel_coefs* coef, + std::vector>& coordCells, + std::unordered_map& Cells_Obj, + arguments* args, + weatherDF* wdf_ptr, + std::vector* FSCell, + std::vector* crownMetrics, + bool& activeCrown, + double randomROS, + int perimeterCells, + std::vector& crownState, + std::vector& crownFraction, + std::vector& surfFraction, + std::vector& Intensities, + std::vector& RateOfSpreads, + std::vector& FlameLengths) { - // Special flag for repetition (False = -99 for the record) - int repeat = -99; - - // msg lists contains integers (True = -100) - std::vector msg_list_aux; - msg_list_aux.push_back(0); - std::vector msg_list; - - // Populate Inputs - df_ptr[this->realId - 1].waz = wdf_ptr->waz; - df_ptr[this->realId - 1].ws = wdf_ptr->ws; - df_ptr[this->realId - 1].tmp = wdf_ptr->tmp; - df_ptr[this->realId - 1].rh = wdf_ptr->rh; - df_ptr[this->realId - 1].bui = wdf_ptr->bui; - df_ptr[this->realId - 1].ffmc = wdf_ptr->ffmc; - - int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation - if (head_cell <= 0) // solve boundaries case - { - head_cell = this->realId; // as it is used only for slope calculation, if it is a boundary cell, it uses the same cell, so it uses a no slope scenario - } - // Compute main angle and ROSs: forward, flanks and back - main_outs mainstruct, metrics; - snd_outs sndstruct; - fire_struc headstruct, backstruct, flankstruct, metrics2; - - // Calculate parameters - if (args->Simulator == "K") - { - calculate_k(&df_ptr[this->realId - 1], &df_ptr[head_cell - 1], perimeterCells, coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "S") - { - calculate_s(&df_ptr[this->realId - 1], coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "C") - { - calculate_fbp(&df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); - } - - /* ROSs DEBUG! */ - if (args->verbose) - { - std::cout << "*********** ROSs debug ************" << std::endl; - std::cout << "-------Input Structure--------" << std::endl; - std::cout << "fueltype: " << df_ptr[this->realId - 1].fueltype << std::endl; - std::cout << "nfueltype: " << df_ptr[this->realId - 1].nftype << std::endl; - std::cout << "ws: " << df_ptr[this->realId - 1].ws << std::endl; - std::cout << "waz: " << df_ptr[this->realId - 1].waz << std::endl; - std::cout << "ps: " << df_ptr[this->realId - 1].ps << std::endl; - std::cout << "saz: " << df_ptr[this->realId - 1].saz << std::endl; - std::cout << "cur: " << df_ptr[this->realId - 1].cur << std::endl; - std::cout << "elev: " << df_ptr[this->realId - 1].elev << std::endl; - std::cout << "cbd: " << df_ptr[this->realId - 1].cbd << std::endl; - std::cout << "cbh: " << df_ptr[this->realId - 1].cbh << std::endl; - std::cout << "ccf: " << df_ptr[this->realId - 1].ccf << std::endl; - std::cout << "\n-------Mainout Structure--------" << std::endl; - std::cout << "rss: " << mainstruct.rss << std::endl; - std::cout << "angle: " << mainstruct.angle << std::endl; - std::cout << "fl: " << mainstruct.fl << std::endl; - std::cout << "fh: " << mainstruct.fh << std::endl; - std::cout << "a:" << mainstruct.a << std::endl; - std::cout << "b:" << mainstruct.b << std::endl; - std::cout << "c:" << mainstruct.c << std::endl; - std::cout << "covertype: " << mainstruct.covertype << std::endl; - std::cout << "cros: " << mainstruct.crown << std::endl; - std::cout << "\n-------Headout Structure--------" << std::endl; - std::cout << "ros: " << headstruct.ros * args->HFactor << std::endl; - std::cout << "rss: " << headstruct.rss << std::endl; - std::cout << "\n------- Flank Structure--------" << std::endl; - std::cout << "ros: " << flankstruct.ros * args->FFactor << std::endl; - std::cout << "rss: " << flankstruct.rss << std::endl; - std::cout << "\n------- Back Structure--------" << std::endl; - std::cout << "ros: " << backstruct.ros * args->BFactor << std::endl; - std::cout << "rss: " << backstruct.rss << std::endl; - std::cout << "\n------- Extra --------" << std::endl; - std::cout << "lb: " << sndstruct.lb * args->BFactor << std::endl; - std::cout << "*********** ROSs debug ************" << std::endl; - } - /* */ - - double cartesianAngle = 270 - wdf_ptr->waz; // - 90; // CHECK!!!!! - if (cartesianAngle < 0) - { - cartesianAngle += 360; - } - - // Adjusting from Spanish forests angle - cartesianAngle = wdf_ptr->waz; - double offset = cartesianAngle + 270; - cartesianAngle = 360 - (offset >= 360) * (cartesianAngle - 90) - (offset < 360) * offset; - if (cartesianAngle == 360) - cartesianAngle = 0; - if (cartesianAngle < 0) - cartesianAngle += 360; - - double ROSRV = 0; - if (args->ROSCV > 0) - { - // std::srand(args->seed); - // std::default_random_engine generator(args->seed); - // std::normal_distribution distribution(0.0,1.0); - ROSRV = randomROS; - } - - // Display if verbose True (ROSs, Main angle, and ROS std (if included)) - if (args->verbose) - { - std::cout << "Main Angle (raz): " << wdf_ptr->waz << " Cartesian: " << cartesianAngle << std::endl; - std::cout << "Front ROS Value: " << headstruct.ros * args->HFactor << std::endl; - std::cout << "Flanks ROS Value: " << flankstruct.ros * args->FFactor << std::endl; - std::cout << "Rear ROS Value: " << backstruct.ros * args->BFactor << std::endl; - std::cout << "Std Normal RV for Stochastic ROS CV: " << ROSRV << std::endl; - } - - // If cell cannot send (thresholds), then it will be burned out in the main loop - double HROS = (1 + args->ROSCV * ROSRV) * headstruct.ros * args->HFactor; - - // Extra debug step for sanity checks - if (args->verbose) - { - std::cout << "\nSending message conditions" << std::endl; - std::cout << "HROS: " << HROS << " Threshold: " << args->ROSThreshold << std::endl; - } - - // Check thresholds for sending messages - if (HROS > args->ROSThreshold) - { - // True = -100 - repeat = -100; - - if (args->verbose) - { - std::cout << "\nRepeat condition: " << repeat << std::endl; - std::cout << "Cell can send messages" << std::endl; - } - - // ROS distribution method - // ros_distr(mainstruct.raz, headstruct.ros, flankstruct.ros, backstruct.ros); - // std::cout << "Entra a Ros Dist" << std::endl; - /*ros_distr(cartesianAngle, - headstruct.ros * args->HFactor, - flankstruct.ros * args->FFactor, - backstruct.ros * args->BFactor, - args->EFactor); - */ - ros_distr_V2(cartesianAngle, - mainstruct.a * args->HFactor, - mainstruct.b * args->FFactor, - mainstruct.c * args->BFactor, - args->EFactor); - // std::cout << "Sale de Ros Dist" << std::endl; - - // Fire progress using ROS from burning cell, not the neighbors // - // vector toPop = vector(); - - // this is a iterator through the keyset of a dictionary - for (auto &_angle : this->ROSAngleDir) - { - double angle = _angle.first; - int nb = angleToNb[angle]; - double ros = (1 + args->ROSCV * ROSRV) * _angle.second; - - if (std::isnan(ros)) - { - ros = 1e-4; - } - - if (args->verbose) - { - std::cout << " (angle, realized ros in m/min): (" << angle << ", " << ros << ")" << std::endl; - } - if (args->Simulator == "S") - { - // Slope effect - float se = slope_effect(df_ptr[this->realId - 1].elev, df_ptr[nb - 1].elev, this->perimeter / 4.); - if (args->verbose) - { - std::cout << "Slope effect: " << se << std::endl; - } - - // Workaround PeriodLen in 60 minutes - this->fireProgress[nb] += ros * args->FirePeriodLen * se; // Updates fire progress - } - else - this->fireProgress[nb] += ros * args->FirePeriodLen; - - // If the message arrives to the adjacent cell's center, send a message - if (this->fireProgress[nb] >= this->distToCenter[nb]) - { - msg_list.push_back(nb); - FSCell->push_back(double(this->realId)); - FSCell->push_back(double(nb)); - FSCell->push_back(double(period)); - FSCell->push_back(std::ceil(ros * 100.0) / 100.0); - df_ptr[nb - 1].waz = wdf_ptr->waz; - df_ptr[nb - 1].ws = wdf_ptr->ws; - df_ptr[nb - 1].tmp = wdf_ptr->tmp; - df_ptr[nb - 1].rh = wdf_ptr->rh; - df_ptr[nb - 1].bui = wdf_ptr->bui; - df_ptr[nb - 1].ffmc = wdf_ptr->ffmc; - if (args->Simulator == "K") - { - determine_destiny_metrics_k(&df_ptr[int(nb) - 1], coef, args, &metrics); - } - else if (args->Simulator == "S") - { - determine_destiny_metrics_s(&df_ptr[int(nb) - 1], coef, args, &metrics); - } - else if (args->Simulator == "C") - { - determine_destiny_metrics_fbp(&df_ptr[int(nb) - 1], coef, &metrics, &metrics2); - } - crownState[this->realId - 1] = mainstruct.crown; - crownState[nb - 1] = metrics.crown; - RateOfSpreads[this->realId - 1] = double(std::ceil(ros * 100.0) / 100.0); - RateOfSpreads[nb - 1] = double(std::ceil(ros * 100.0) / 100.0); - Intensities[this->realId - 1] = mainstruct.sfi; - Intensities[nb - 1] = metrics.sfi; - crownFraction[this->realId - 1] = mainstruct.cfb; - crownFraction[nb - 1] = metrics.cfb; - surfFraction[this->realId] = mainstruct.sfc; - surfFraction[nb] = metrics.sfc; - FlameLengths[this->realId - 1] = mainstruct.fl; - FlameLengths[nb - 1] = metrics.fl; - - // cannot mutate ROSangleDir during iteration.. we do it like 10 lines down - // toPop.push_back(angle); - /*if (verbose) { - //fill out this verbose section - std::cout << "MSG list" << msg_list << std::endl; - }*/ - } - - // Info for debugging status of the cell and fire evolution - if (this->fireProgress[nb] < this->distToCenter[nb] && repeat == -100 && -100 != msg_list_aux[0]) - { - if (args->verbose) - { - std::cout << "A Repeat = TRUE flag is sent in order to continue with the current fire....." << std::endl; - std::cout << "Main workaround of the new sim logic....." << std::endl; - } - msg_list_aux[0] = repeat; - } - } - - if (args->verbose) - { - printf("fireProgress Dict: "); - for (auto &nb : this->fireProgress) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - } - } - - // If original is empty (no messages but fire is alive if aux_list is not empty) - if (msg_list.size() == 0) - { - if (msg_list_aux[0] == -100) - { - msg_list = msg_list_aux; - } - - else - { - this->status = 2; // we are done sending messages, call us burned - } - } - - if (args->verbose) - { - std::cout << " ----------------- End of new manageFire function -----------------" << std::endl; - } - return msg_list; + // Special flag for repetition (False = -99 for the record) + int repeat = -99; + + // msg lists contains integers (True = -100) + std::vector msg_list_aux; + msg_list_aux.push_back(0); + std::vector msg_list; + + // Populate Inputs + df_ptr[this->realId - 1].waz = wdf_ptr->waz; + df_ptr[this->realId - 1].ws = wdf_ptr->ws; + df_ptr[this->realId - 1].tmp = wdf_ptr->tmp; + df_ptr[this->realId - 1].rh = wdf_ptr->rh; + df_ptr[this->realId - 1].bui = wdf_ptr->bui; + df_ptr[this->realId - 1].ffmc = wdf_ptr->ffmc; + + int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation + if (head_cell <= 0) // solve boundaries case + { + head_cell = this->realId; // as it is used only for slope calculation, if + // it is a boundary cell, it uses the same + // cell, so it uses a no slope scenario + } + // Compute main angle and ROSs: forward, flanks and back + main_outs mainstruct, metrics; + snd_outs sndstruct; + fire_struc headstruct, backstruct, flankstruct, metrics2; + + // Calculate parameters + if (args->Simulator == "K") + { + calculate_k(&df_ptr[this->realId - 1], + &df_ptr[head_cell - 1], + perimeterCells, + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "S") + { + calculate_s(&df_ptr[this->realId - 1], + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "C") + { + calculate_fbp(&df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); + } + + /* ROSs DEBUG! */ + if (args->verbose) + { + std::cout << "*********** ROSs debug ************" << std::endl; + std::cout << "-------Input Structure--------" << std::endl; + std::cout << "fueltype: " << df_ptr[this->realId - 1].fueltype << std::endl; + std::cout << "nfueltype: " << df_ptr[this->realId - 1].nftype << std::endl; + std::cout << "ws: " << df_ptr[this->realId - 1].ws << std::endl; + std::cout << "waz: " << df_ptr[this->realId - 1].waz << std::endl; + std::cout << "ps: " << df_ptr[this->realId - 1].ps << std::endl; + std::cout << "saz: " << df_ptr[this->realId - 1].saz << std::endl; + std::cout << "cur: " << df_ptr[this->realId - 1].cur << std::endl; + std::cout << "elev: " << df_ptr[this->realId - 1].elev << std::endl; + std::cout << "cbd: " << df_ptr[this->realId - 1].cbd << std::endl; + std::cout << "cbh: " << df_ptr[this->realId - 1].cbh << std::endl; + std::cout << "ccf: " << df_ptr[this->realId - 1].ccf << std::endl; + std::cout << "\n-------Mainout Structure--------" << std::endl; + std::cout << "rss: " << mainstruct.rss << std::endl; + std::cout << "angle: " << mainstruct.angle << std::endl; + std::cout << "fl: " << mainstruct.fl << std::endl; + std::cout << "fh: " << mainstruct.fh << std::endl; + std::cout << "a:" << mainstruct.a << std::endl; + std::cout << "b:" << mainstruct.b << std::endl; + std::cout << "c:" << mainstruct.c << std::endl; + std::cout << "covertype: " << mainstruct.covertype << std::endl; + std::cout << "cros: " << mainstruct.crown << std::endl; + std::cout << "\n-------Headout Structure--------" << std::endl; + std::cout << "ros: " << headstruct.ros * args->HFactor << std::endl; + std::cout << "rss: " << headstruct.rss << std::endl; + std::cout << "\n------- Flank Structure--------" << std::endl; + std::cout << "ros: " << flankstruct.ros * args->FFactor << std::endl; + std::cout << "rss: " << flankstruct.rss << std::endl; + std::cout << "\n------- Back Structure--------" << std::endl; + std::cout << "ros: " << backstruct.ros * args->BFactor << std::endl; + std::cout << "rss: " << backstruct.rss << std::endl; + std::cout << "\n------- Extra --------" << std::endl; + std::cout << "lb: " << sndstruct.lb * args->BFactor << std::endl; + std::cout << "*********** ROSs debug ************" << std::endl; + } + /* */ + + double cartesianAngle = 270 - wdf_ptr->waz; // - 90; // CHECK!!!!! + if (cartesianAngle < 0) + { + cartesianAngle += 360; + } + + // Adjusting from Spanish forests angle + cartesianAngle = wdf_ptr->waz; + double offset = cartesianAngle + 270; + cartesianAngle = 360 - (offset >= 360) * (cartesianAngle - 90) - (offset < 360) * offset; + if (cartesianAngle == 360) + cartesianAngle = 0; + if (cartesianAngle < 0) + cartesianAngle += 360; + + double ROSRV = 0; + if (args->ROSCV > 0) + { + // std::srand(args->seed); + // std::default_random_engine generator(args->seed); + // std::normal_distribution distribution(0.0,1.0); + ROSRV = randomROS; + } + + // Display if verbose True (ROSs, Main angle, and ROS std (if included)) + if (args->verbose) + { + std::cout << "Main Angle (raz): " << wdf_ptr->waz << " Cartesian: " << cartesianAngle << std::endl; + std::cout << "Front ROS Value: " << headstruct.ros * args->HFactor << std::endl; + std::cout << "Flanks ROS Value: " << flankstruct.ros * args->FFactor << std::endl; + std::cout << "Rear ROS Value: " << backstruct.ros * args->BFactor << std::endl; + std::cout << "Std Normal RV for Stochastic ROS CV: " << ROSRV << std::endl; + } + + // If cell cannot send (thresholds), then it will be burned out in the main + // loop + double HROS = (1 + args->ROSCV * ROSRV) * headstruct.ros * args->HFactor; + + // Extra debug step for sanity checks + if (args->verbose) + { + std::cout << "\nSending message conditions" << std::endl; + std::cout << "HROS: " << HROS << " Threshold: " << args->ROSThreshold << std::endl; + } + + // Check thresholds for sending messages + if (HROS > args->ROSThreshold) + { + // True = -100 + repeat = -100; + + if (args->verbose) + { + std::cout << "\nRepeat condition: " << repeat << std::endl; + std::cout << "Cell can send messages" << std::endl; + } + + // ROS distribution method + // ros_distr(mainstruct.raz, headstruct.ros, flankstruct.ros, + // backstruct.ros); std::cout << "Entra a Ros Dist" << std::endl; + /*ros_distr(cartesianAngle, + headstruct.ros * args->HFactor, + flankstruct.ros * args->FFactor, + backstruct.ros * args->BFactor, + args->EFactor); + */ + ros_distr_V2(cartesianAngle, + mainstruct.a * args->HFactor, + mainstruct.b * args->FFactor, + mainstruct.c * args->BFactor, + args->EFactor); + // std::cout << "Sale de Ros Dist" << std::endl; + + // Fire progress using ROS from burning cell, not the neighbors // + // vector toPop = vector(); + + // this is a iterator through the keyset of a dictionary + for (auto& _angle : this->ROSAngleDir) + { + double angle = _angle.first; + int nb = angleToNb[angle]; + double ros = (1 + args->ROSCV * ROSRV) * _angle.second; + + if (std::isnan(ros)) + { + ros = 1e-4; + } + + if (args->verbose) + { + std::cout << " (angle, realized ros in m/min): (" << angle << ", " << ros << ")" << std::endl; + } + if (args->Simulator == "S") + { + // Slope effect + float se = slope_effect(df_ptr[this->realId - 1].elev, df_ptr[nb - 1].elev, this->perimeter / 4.); + if (args->verbose) + { + std::cout << "Slope effect: " << se << std::endl; + } + + // Workaround PeriodLen in 60 minutes + this->fireProgress[nb] += ros * args->FirePeriodLen * se; // Updates fire progress + } + else + this->fireProgress[nb] += ros * args->FirePeriodLen; + + // If the message arrives to the adjacent cell's center, send a + // message + if (this->fireProgress[nb] >= this->distToCenter[nb]) + { + msg_list.push_back(nb); + FSCell->push_back(double(this->realId)); + FSCell->push_back(double(nb)); + FSCell->push_back(double(period)); + FSCell->push_back(std::ceil(ros * 100.0) / 100.0); + df_ptr[nb - 1].waz = wdf_ptr->waz; + df_ptr[nb - 1].ws = wdf_ptr->ws; + df_ptr[nb - 1].tmp = wdf_ptr->tmp; + df_ptr[nb - 1].rh = wdf_ptr->rh; + df_ptr[nb - 1].bui = wdf_ptr->bui; + df_ptr[nb - 1].ffmc = wdf_ptr->ffmc; + if (args->Simulator == "K") + { + determine_destiny_metrics_k(&df_ptr[int(nb) - 1], coef, args, &metrics); + } + else if (args->Simulator == "S") + { + determine_destiny_metrics_s(&df_ptr[int(nb) - 1], coef, args, &metrics); + } + else if (args->Simulator == "C") + { + determine_destiny_metrics_fbp(&df_ptr[int(nb) - 1], coef, &metrics, &metrics2); + } + crownState[this->realId - 1] = mainstruct.crown; + crownState[nb - 1] = metrics.crown; + RateOfSpreads[this->realId - 1] = double(std::ceil(ros * 100.0) / 100.0); + RateOfSpreads[nb - 1] = double(std::ceil(ros * 100.0) / 100.0); + Intensities[this->realId - 1] = mainstruct.sfi; + Intensities[nb - 1] = metrics.sfi; + crownFraction[this->realId - 1] = mainstruct.cfb; + crownFraction[nb - 1] = metrics.cfb; + surfFraction[this->realId] = mainstruct.sfc; + surfFraction[nb] = metrics.sfc; + FlameLengths[this->realId - 1] = mainstruct.fl; + FlameLengths[nb - 1] = metrics.fl; + + // cannot mutate ROSangleDir during iteration.. we do it like 10 + // lines down toPop.push_back(angle); + /*if (verbose) { + //fill out this verbose section + std::cout << "MSG list" << msg_list << std::endl; + }*/ + } + + // Info for debugging status of the cell and fire evolution + if (this->fireProgress[nb] < this->distToCenter[nb] && repeat == -100 && -100 != msg_list_aux[0]) + { + if (args->verbose) + { + std::cout << "A Repeat = TRUE flag is sent in order to " + "continue with the current fire....." + << std::endl; + std::cout << "Main workaround of the new sim logic....." << std::endl; + } + msg_list_aux[0] = repeat; + } + } + + if (args->verbose) + { + printf("fireProgress Dict: "); + for (auto& nb : this->fireProgress) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + } + } + + // If original is empty (no messages but fire is alive if aux_list is not + // empty) + if (msg_list.size() == 0) + { + if (msg_list_aux[0] == -100) + { + msg_list = msg_list_aux; + } + + else + { + this->status = 2; // we are done sending messages, call us burned + } + } + + if (args->verbose) + { + std::cout << " ----------------- End of new manageFire function " + "-----------------" + << std::endl; + } + return msg_list; } /** - Manage fire for BBO tuning version + Manage fire for BBO tuning version */ -std::vector Cells::manageFireBBO(int period, std::unordered_set &AvailSet, - inputs *df_ptr, fuel_coefs *coef, - std::vector> &coordCells, std::unordered_map &Cells_Obj, - arguments *args, weatherDF *wdf_ptr, std::vector *FSCell, std::vector *crownMetrics, - bool &activeCrown, double randomROS, int perimeterCells, std::vector &EllipseFactors, std::vector &crownState, std::vector &crownFraction, std::vector &surfFraction, std::vector &Intensities, std::vector &RateOfSpreads, std::vector &FlameLengths) +std::vector +Cells::manageFireBBO(int period, + std::unordered_set& AvailSet, + inputs* df_ptr, + fuel_coefs* coef, + std::vector>& coordCells, + std::unordered_map& Cells_Obj, + arguments* args, + weatherDF* wdf_ptr, + std::vector* FSCell, + std::vector* crownMetrics, + bool& activeCrown, + double randomROS, + int perimeterCells, + std::vector& EllipseFactors, + std::vector& crownState, + std::vector& crownFraction, + std::vector& surfFraction, + std::vector& Intensities, + std::vector& RateOfSpreads, + std::vector& FlameLengths) { - // Special flag for repetition (False = -99 for the record) - int repeat = -99; - - // msg lists contains integers (True = -100) - std::vector msg_list_aux; - msg_list_aux.push_back(0); - std::vector msg_list; - - // Compute main angle and ROSs: forward, flanks and back - main_outs mainstruct, metrics; - snd_outs sndstruct; - fire_struc headstruct, backstruct, flankstruct, metrics2; - - // Populate inputs - df_ptr->waz = wdf_ptr->waz; - df_ptr->ws = wdf_ptr->ws; - df_ptr->bui = wdf_ptr->bui; - df_ptr->ffmc = wdf_ptr->ffmc; - df_ptr->tmp = wdf_ptr->tmp; - df_ptr->rh = wdf_ptr->rh; - int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation - if (head_cell <= 0) // solve boundaries case - { - head_cell = this->realId; // as it is used only for slope calculation, if it is a boundary cell, it uses the same cell, so it uses a no slope scenario - } - // Calculate parameters - - if (args->Simulator == "K") - { - calculate_k(&df_ptr[this->realId - 1], &df_ptr[head_cell - 1], perimeterCells, coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "S") - { - calculate_s(&df_ptr[this->realId - 1], coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - - else if (args->Simulator == "C") - { - calculate_fbp(&df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); - } - - /* ROSs DEBUG! */ - if (args->verbose) - { - std::cout << "*********** ROSs debug ************" << std::endl; - std::cout << "-------Input Structure--------" << std::endl; - std::cout << "fueltype: " << df_ptr->fueltype << std::endl; - std::cout << "ws: " << df_ptr->ws << std::endl; - std::cout << "waz: " << df_ptr->waz << std::endl; - std::cout << "ps: " << df_ptr->ps << std::endl; - std::cout << "saz: " << df_ptr->saz << std::endl; - std::cout << "cur: " << df_ptr->cur << std::endl; - std::cout << "elev: " << df_ptr->elev << std::endl; - std::cout << "\n-------Mainout Structure--------" << std::endl; - std::cout << "rss: " << mainstruct.rss << std::endl; - std::cout << "angle: " << mainstruct.angle << std::endl; - std::cout << "fl: " << mainstruct.fl << std::endl; - std::cout << "fh: " << mainstruct.fh << std::endl; - std::cout << "a:" << mainstruct.a << std::endl; - std::cout << "b:" << mainstruct.b << std::endl; - std::cout << "c:" << mainstruct.c << std::endl; - std::cout << "covertype: " << mainstruct.covertype << std::endl; - std::cout << "cros: " << mainstruct.crown << std::endl; - std::cout << "\n-------Headout Structure--------" << std::endl; - std::cout << "ros: " << headstruct.ros * args->HFactor << std::endl; - std::cout << "rss: " << headstruct.rss << std::endl; - std::cout << "\n------- Flank Structure--------" << std::endl; - std::cout << "ros: " << flankstruct.ros * args->FFactor << std::endl; - std::cout << "rss: " << flankstruct.rss << std::endl; - std::cout << "\n------- Back Structure--------" << std::endl; - std::cout << "ros: " << backstruct.ros * args->BFactor << std::endl; - std::cout << "rss: " << backstruct.rss << std::endl; - std::cout << "\n------- Extra --------" << std::endl; - std::cout << "lb: " << sndstruct.lb * args->BFactor << std::endl; - std::cout << "*********** ROSs debug ************" << std::endl; - } - /* */ - - double cartesianAngle = 270 - wdf_ptr->waz; // - 90; // CHECK!!!!! - if (cartesianAngle < 0) - { - cartesianAngle += 360; - } - - // Adjusting from Spanish forests angle - cartesianAngle = wdf_ptr->waz; - double offset = cartesianAngle + 270; - cartesianAngle = 360 - (offset >= 360) * (cartesianAngle - 90) - (offset < 360) * offset; - if (cartesianAngle == 360) - cartesianAngle = 0; - if (cartesianAngle < 0) - cartesianAngle += 360; - - double ROSRV = 0; - if (args->ROSCV > 0) - { - // std::srand(args->seed); - // std::default_random_engine generator(args->seed); - // std::normal_distribution distribution(0.0,1.0); - ROSRV = randomROS; - } - - // Display if verbose True (ROSs, Main angle, and ROS std (if included)) - if (args->verbose) - { - std::cout << "Main Angle (raz): " << wdf_ptr->waz << " Cartesian: " << cartesianAngle << std::endl; - std::cout << "Front ROS Value: " << headstruct.ros * EllipseFactors[0] << std::endl; - std::cout << "Flanks ROS Value: " << flankstruct.ros * EllipseFactors[1] << std::endl; - std::cout << "Rear ROS Value: " << backstruct.ros * EllipseFactors[2] << std::endl; - std::cout << "Std Normal RV for Stochastic ROS CV: " << ROSRV << std::endl; - } - - // If cell cannot send (thresholds), then it will be burned out in the main loop - double HROS = (1 + args->ROSCV * ROSRV) * headstruct.ros * EllipseFactors[0]; - - // Extra debug step for sanity checks - if (args->verbose) - { - std::cout << "\nSending message conditions" << std::endl; - std::cout << "HROS: " << HROS << " Threshold: " << args->ROSThreshold << std::endl; - } - - // Check thresholds for sending messages - if (HROS > args->ROSThreshold) - { - // True = -100 - repeat = -100; - - if (args->verbose) - { - std::cout << "\nRepeat condition: " << repeat << std::endl; - std::cout << "Cell can send messages" << std::endl; - } - - // ROS distribution method - // ros_distr(mainstruct.raz, headstruct.ros, flankstruct.ros, backstruct.ros); - // std::cout << "Entra a Ros Dist" << std::endl; - /*ros_distr(cartesianAngle, - headstruct.ros * EllipseFactors[0], - flankstruct.ros * EllipseFactors[1], - backstruct.ros * EllipseFactors[2], - EllipseFactors[3]); - */ - ros_distr_V2(cartesianAngle, - mainstruct.a * EllipseFactors[0], - mainstruct.b * EllipseFactors[1], - mainstruct.c * EllipseFactors[2], - EllipseFactors[3]); - // std::cout << "Sale de Ros Dist" << std::endl; - - // Fire progress using ROS from burning cell, not the neighbors // - // vector toPop = vector(); - - // this is a iterator through the keyset of a dictionary - for (auto &_angle : this->ROSAngleDir) - { - double angle = _angle.first; - int nb = angleToNb[angle]; - double ros = (1 + args->ROSCV * ROSRV) * _angle.second; - - if (args->verbose) - { - std::cout << " (angle, realized ros in m/min): (" << angle << ", " << ros << ")" << std::endl; - } - - // Workaround PeriodLen in 60 minutes - this->fireProgress[nb] += ros * args->FirePeriodLen; // Updates fire progress - - // If the message arrives to the adjacent cell's center, send a message - if (this->fireProgress[nb] >= this->distToCenter[nb]) - { - msg_list.push_back(nb); - FSCell->push_back(double(this->realId)); - FSCell->push_back(double(nb)); - FSCell->push_back(double(period)); - FSCell->push_back(ros); - if (args->Simulator == "K") - { - determine_destiny_metrics_k(&df_ptr[int(nb) - 1], coef, args, &metrics); - } - else if (args->Simulator == "S") - { - determine_destiny_metrics_s(&df_ptr[int(nb) - 1], coef, args, &metrics); - } - else if (args->Simulator == "C") - { - determine_destiny_metrics_fbp(&df_ptr[int(nb) - 1], coef, &metrics, &metrics2); - } - crownState[this->realId - 1] = mainstruct.crown; - crownState[nb - 1] = metrics.crown; - RateOfSpreads[this->realId - 1] = double(std::ceil(ros * 100.0) / 100.0); - RateOfSpreads[nb - 1] = double(std::ceil(ros * 100.0) / 100.0); - Intensities[this->realId - 1] = mainstruct.sfi; - Intensities[nb - 1] = metrics.sfi; - crownFraction[this->realId - 1] = mainstruct.cfb; - crownFraction[nb - 1] = metrics.cfb; - surfFraction[this->realId] = mainstruct.sfc; - surfFraction[nb] = metrics.sfc; - FlameLengths[this->realId - 1] = mainstruct.fl; - FlameLengths[nb - 1] = metrics.fl; - // cannot mutate ROSangleDir during iteration.. we do it like 10 lines down - // toPop.push_back(angle); - /*if (verbose) { - //fill out this verbose section - std::cout << "MSG list" << msg_list << std::endl; - }*/ - } - - // Info for debugging status of the cell and fire evolution - if (this->fireProgress[nb] < this->distToCenter[nb] && repeat == -100 && -100 != msg_list_aux[0]) - { - if (args->verbose) - { - std::cout << "A Repeat = TRUE flag is sent in order to continue with the current fire....." << std::endl; - std::cout << "Main workaround of the new sim logic....." << std::endl; - } - msg_list_aux[0] = repeat; - } - } - - if (args->verbose) - { - printf("fireProgress Dict: "); - for (auto &nb : this->fireProgress) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - } - } - - // If original is empty (no messages but fire is alive if aux_list is not empty) - if (msg_list.size() == 0) - { - if (msg_list_aux[0] == -100) - { - msg_list = msg_list_aux; - } - - else - { - this->status = 2; // we are done sending messages, call us burned - } - } - - if (args->verbose) - { - std::cout << " ----------------- End of new manageFire function -----------------" << std::endl; - } - return msg_list; + // Special flag for repetition (False = -99 for the record) + int repeat = -99; + + // msg lists contains integers (True = -100) + std::vector msg_list_aux; + msg_list_aux.push_back(0); + std::vector msg_list; + + // Compute main angle and ROSs: forward, flanks and back + main_outs mainstruct, metrics; + snd_outs sndstruct; + fire_struc headstruct, backstruct, flankstruct, metrics2; + + // Populate inputs + df_ptr->waz = wdf_ptr->waz; + df_ptr->ws = wdf_ptr->ws; + df_ptr->bui = wdf_ptr->bui; + df_ptr->ffmc = wdf_ptr->ffmc; + df_ptr->tmp = wdf_ptr->tmp; + df_ptr->rh = wdf_ptr->rh; + int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation + if (head_cell <= 0) // solve boundaries case + { + head_cell = this->realId; // as it is used only for slope calculation, if + // it is a boundary cell, it uses the same + // cell, so it uses a no slope scenario + } + // Calculate parameters + + if (args->Simulator == "K") + { + calculate_k(&df_ptr[this->realId - 1], + &df_ptr[head_cell - 1], + perimeterCells, + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "S") + { + calculate_s(&df_ptr[this->realId - 1], + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + + else if (args->Simulator == "C") + { + calculate_fbp(&df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); + } + + /* ROSs DEBUG! */ + if (args->verbose) + { + std::cout << "*********** ROSs debug ************" << std::endl; + std::cout << "-------Input Structure--------" << std::endl; + std::cout << "fueltype: " << df_ptr->fueltype << std::endl; + std::cout << "ws: " << df_ptr->ws << std::endl; + std::cout << "waz: " << df_ptr->waz << std::endl; + std::cout << "ps: " << df_ptr->ps << std::endl; + std::cout << "saz: " << df_ptr->saz << std::endl; + std::cout << "cur: " << df_ptr->cur << std::endl; + std::cout << "elev: " << df_ptr->elev << std::endl; + std::cout << "\n-------Mainout Structure--------" << std::endl; + std::cout << "rss: " << mainstruct.rss << std::endl; + std::cout << "angle: " << mainstruct.angle << std::endl; + std::cout << "fl: " << mainstruct.fl << std::endl; + std::cout << "fh: " << mainstruct.fh << std::endl; + std::cout << "a:" << mainstruct.a << std::endl; + std::cout << "b:" << mainstruct.b << std::endl; + std::cout << "c:" << mainstruct.c << std::endl; + std::cout << "covertype: " << mainstruct.covertype << std::endl; + std::cout << "cros: " << mainstruct.crown << std::endl; + std::cout << "\n-------Headout Structure--------" << std::endl; + std::cout << "ros: " << headstruct.ros * args->HFactor << std::endl; + std::cout << "rss: " << headstruct.rss << std::endl; + std::cout << "\n------- Flank Structure--------" << std::endl; + std::cout << "ros: " << flankstruct.ros * args->FFactor << std::endl; + std::cout << "rss: " << flankstruct.rss << std::endl; + std::cout << "\n------- Back Structure--------" << std::endl; + std::cout << "ros: " << backstruct.ros * args->BFactor << std::endl; + std::cout << "rss: " << backstruct.rss << std::endl; + std::cout << "\n------- Extra --------" << std::endl; + std::cout << "lb: " << sndstruct.lb * args->BFactor << std::endl; + std::cout << "*********** ROSs debug ************" << std::endl; + } + /* */ + + double cartesianAngle = 270 - wdf_ptr->waz; // - 90; // CHECK!!!!! + if (cartesianAngle < 0) + { + cartesianAngle += 360; + } + + // Adjusting from Spanish forests angle + cartesianAngle = wdf_ptr->waz; + double offset = cartesianAngle + 270; + cartesianAngle = 360 - (offset >= 360) * (cartesianAngle - 90) - (offset < 360) * offset; + if (cartesianAngle == 360) + cartesianAngle = 0; + if (cartesianAngle < 0) + cartesianAngle += 360; + + double ROSRV = 0; + if (args->ROSCV > 0) + { + // std::srand(args->seed); + // std::default_random_engine generator(args->seed); + // std::normal_distribution distribution(0.0,1.0); + ROSRV = randomROS; + } + + // Display if verbose True (ROSs, Main angle, and ROS std (if included)) + if (args->verbose) + { + std::cout << "Main Angle (raz): " << wdf_ptr->waz << " Cartesian: " << cartesianAngle << std::endl; + std::cout << "Front ROS Value: " << headstruct.ros * EllipseFactors[0] << std::endl; + std::cout << "Flanks ROS Value: " << flankstruct.ros * EllipseFactors[1] << std::endl; + std::cout << "Rear ROS Value: " << backstruct.ros * EllipseFactors[2] << std::endl; + std::cout << "Std Normal RV for Stochastic ROS CV: " << ROSRV << std::endl; + } + + // If cell cannot send (thresholds), then it will be burned out in the main + // loop + double HROS = (1 + args->ROSCV * ROSRV) * headstruct.ros * EllipseFactors[0]; + + // Extra debug step for sanity checks + if (args->verbose) + { + std::cout << "\nSending message conditions" << std::endl; + std::cout << "HROS: " << HROS << " Threshold: " << args->ROSThreshold << std::endl; + } + + // Check thresholds for sending messages + if (HROS > args->ROSThreshold) + { + // True = -100 + repeat = -100; + + if (args->verbose) + { + std::cout << "\nRepeat condition: " << repeat << std::endl; + std::cout << "Cell can send messages" << std::endl; + } + + // ROS distribution method + // ros_distr(mainstruct.raz, headstruct.ros, flankstruct.ros, + // backstruct.ros); std::cout << "Entra a Ros Dist" << std::endl; + /*ros_distr(cartesianAngle, + headstruct.ros * EllipseFactors[0], + flankstruct.ros * EllipseFactors[1], + backstruct.ros * EllipseFactors[2], + EllipseFactors[3]); + */ + ros_distr_V2(cartesianAngle, + mainstruct.a * EllipseFactors[0], + mainstruct.b * EllipseFactors[1], + mainstruct.c * EllipseFactors[2], + EllipseFactors[3]); + // std::cout << "Sale de Ros Dist" << std::endl; + + // Fire progress using ROS from burning cell, not the neighbors // + // vector toPop = vector(); + + // this is a iterator through the keyset of a dictionary + for (auto& _angle : this->ROSAngleDir) + { + double angle = _angle.first; + int nb = angleToNb[angle]; + double ros = (1 + args->ROSCV * ROSRV) * _angle.second; + + if (args->verbose) + { + std::cout << " (angle, realized ros in m/min): (" << angle << ", " << ros << ")" << std::endl; + } + + // Workaround PeriodLen in 60 minutes + this->fireProgress[nb] += ros * args->FirePeriodLen; // Updates fire progress + + // If the message arrives to the adjacent cell's center, send a + // message + if (this->fireProgress[nb] >= this->distToCenter[nb]) + { + msg_list.push_back(nb); + FSCell->push_back(double(this->realId)); + FSCell->push_back(double(nb)); + FSCell->push_back(double(period)); + FSCell->push_back(ros); + if (args->Simulator == "K") + { + determine_destiny_metrics_k(&df_ptr[int(nb) - 1], coef, args, &metrics); + } + else if (args->Simulator == "S") + { + determine_destiny_metrics_s(&df_ptr[int(nb) - 1], coef, args, &metrics); + } + else if (args->Simulator == "C") + { + determine_destiny_metrics_fbp(&df_ptr[int(nb) - 1], coef, &metrics, &metrics2); + } + crownState[this->realId - 1] = mainstruct.crown; + crownState[nb - 1] = metrics.crown; + RateOfSpreads[this->realId - 1] = double(std::ceil(ros * 100.0) / 100.0); + RateOfSpreads[nb - 1] = double(std::ceil(ros * 100.0) / 100.0); + Intensities[this->realId - 1] = mainstruct.sfi; + Intensities[nb - 1] = metrics.sfi; + crownFraction[this->realId - 1] = mainstruct.cfb; + crownFraction[nb - 1] = metrics.cfb; + surfFraction[this->realId] = mainstruct.sfc; + surfFraction[nb] = metrics.sfc; + FlameLengths[this->realId - 1] = mainstruct.fl; + FlameLengths[nb - 1] = metrics.fl; + // cannot mutate ROSangleDir during iteration.. we do it like 10 + // lines down toPop.push_back(angle); + /*if (verbose) { + //fill out this verbose section + std::cout << "MSG list" << msg_list << std::endl; + }*/ + } + + // Info for debugging status of the cell and fire evolution + if (this->fireProgress[nb] < this->distToCenter[nb] && repeat == -100 && -100 != msg_list_aux[0]) + { + if (args->verbose) + { + std::cout << "A Repeat = TRUE flag is sent in order to " + "continue with the current fire....." + << std::endl; + std::cout << "Main workaround of the new sim logic....." << std::endl; + } + msg_list_aux[0] = repeat; + } + } + + if (args->verbose) + { + printf("fireProgress Dict: "); + for (auto& nb : this->fireProgress) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + } + } + + // If original is empty (no messages but fire is alive if aux_list is not + // empty) + if (msg_list.size() == 0) + { + if (msg_list_aux[0] == -100) + { + msg_list = msg_list_aux; + } + + else + { + this->status = 2; // we are done sending messages, call us burned + } + } + + if (args->verbose) + { + std::cout << " ----------------- End of new manageFire function " + "-----------------" + << std::endl; + } + return msg_list; } /** @@ -975,91 +1103,120 @@ std::vector Cells::manageFireBBO(int period, std::unordered_set &Avail * @param NMsg Current simulation year. * @param season int * @param df Array containing cell-specific environmental and fuel data. - * @param coef Pointer to a structure containing fuel coefficients used in ROS calculations. - * @param args Pointer to a structure containing global simulation arguments and configurations. - * The ROS threshold should be stored here with the key "ROSThreshold". - * @param wdf_ptr Pointer to the weather data structure containing wind speed, direction, and other weather variables. - * @param activeCrown A boolean reference indicating whether crown fire activity is ongoing. + * @param coef Pointer to a structure containing fuel coefficients used in ROS + * calculations. + * @param args Pointer to a structure containing global simulation arguments + * and configurations. The ROS threshold should be stored here with the key + * "ROSThreshold". + * @param wdf_ptr Pointer to the weather data structure containing wind speed, + * direction, and other weather variables. + * @param activeCrown A boolean reference indicating whether crown fire + * activity is ongoing. * @param perimeterCells Cell size, perimeter of a cell. -*/ + */ -bool Cells::get_burned(int period, int season, int NMsg, inputs df[], fuel_coefs *coef, arguments *args, weatherDF *wdf_ptr, bool &activeCrown, int perimeterCells) +bool +Cells::get_burned(int period, + int season, + int NMsg, + inputs df[], + fuel_coefs* coef, + arguments* args, + weatherDF* wdf_ptr, + bool& activeCrown, + int perimeterCells) { - if (args->verbose) - { - std::cout << "ROS Threshold get_burned method" << std::endl; - std::cout << "ROSThreshold: " << args->ROSThreshold << std::endl; - } - - // Structures - main_outs mainstruct, metrics; - snd_outs sndstruct; - fire_struc headstruct, backstruct, flankstruct; - - // Compute main angle and ROSs: forward, flanks and back - df[this->id].waz = wdf_ptr->waz; - df[this->id].ws = wdf_ptr->ws; - df[this->id].tmp = wdf_ptr->tmp; - df[this->id].rh = wdf_ptr->rh; - int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation - if (head_cell <= 0) // solve boundaries case - { - head_cell = this->realId; // as it is used only for slope calculation, if it is a boundary cell, it uses the same cell, so it uses a no slope scenario - } - // Calculate parameters - if (args->Simulator == "K") - { - calculate_k(&(df[this->id]), &(df[head_cell - 1]), perimeterCells, coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "S") - { - calculate_s(&(df[this->id]), coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - - else if (args->Simulator == "C") - { - calculate_fbp(&df[this->id], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); - } - - if (args->verbose) - { - std::cout << "\nMain Angle :" << wdf_ptr->waz << std::endl; - std::cout << "Front ROS Value :" << headstruct.ros * args->HFactor << std::endl; - std::cout << "Flanks ROS Value :" << flankstruct.ros * args->FFactor << std::endl; - std::cout << "Rear ROS Value :" << backstruct.ros * args->BFactor << std::endl; - } - - // Check a threshold for the ROS - if (headstruct.ros * args->HFactor > args->ROSThreshold) - { - this->status = 1; - this->fireStarts = period; - this->fireStartsSeason = season; - this->burntP = period; - return true; - } - // Not burned - return false; + if (args->verbose) + { + std::cout << "ROS Threshold get_burned method" << std::endl; + std::cout << "ROSThreshold: " << args->ROSThreshold << std::endl; + } + + // Structures + main_outs mainstruct, metrics; + snd_outs sndstruct; + fire_struc headstruct, backstruct, flankstruct; + + // Compute main angle and ROSs: forward, flanks and back + df[this->id].waz = wdf_ptr->waz; + df[this->id].ws = wdf_ptr->ws; + df[this->id].tmp = wdf_ptr->tmp; + df[this->id].rh = wdf_ptr->rh; + int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation + if (head_cell <= 0) // solve boundaries case + { + head_cell = this->realId; // as it is used only for slope calculation, if + // it is a boundary cell, it uses the same + // cell, so it uses a no slope scenario + } + // Calculate parameters + if (args->Simulator == "K") + { + calculate_k(&(df[this->id]), + &(df[head_cell - 1]), + perimeterCells, + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "S") + { + calculate_s( + &(df[this->id]), coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); + } + + else if (args->Simulator == "C") + { + calculate_fbp(&df[this->id], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); + } + + if (args->verbose) + { + std::cout << "\nMain Angle :" << wdf_ptr->waz << std::endl; + std::cout << "Front ROS Value :" << headstruct.ros * args->HFactor << std::endl; + std::cout << "Flanks ROS Value :" << flankstruct.ros * args->FFactor << std::endl; + std::cout << "Rear ROS Value :" << backstruct.ros * args->BFactor << std::endl; + } + + // Check a threshold for the ROS + if (headstruct.ros * args->HFactor > args->ROSThreshold) + { + this->status = 1; + this->fireStarts = period; + this->fireStartsSeason = season; + this->burntP = period; + return true; + } + // Not burned + return false; } /* Old functions - Returns void + Returns void - Inputs: - AdjacentCells dictionary{string:[array integers]} + Inputs: + AdjacentCells dictionary{string:[array integers]} */ -// void Cells::set_Adj(std::unordered_map & adjacentCells) { // WORKING CHECK OK +// void Cells::set_Adj(std::unordered_map & adjacentCells) { +// // WORKING CHECK OK // // TODO: in python, these are pointers, maybe make these pointers too :P // this->adjacents = adjacentCells; // } /** - * @brief Sets a cell's fire status (0: Available, 1: Burning, 2: Burnt, 3: Harvested, 4: Non Fuel). + * @brief Sets a cell's fire status (0: Available, 1: Burning, 2: Burnt, 3: + * Harvested, 4: Non Fuel). * @param status_int Code for new status. */ -void Cells::setStatus(int status_int) +void +Cells::setStatus(int status_int) { - this->status = status_int; + this->status = status_int; } /** @@ -1067,173 +1224,212 @@ void Cells::setStatus(int status_int) * * @return The cell's fire status as a descriptive string. */ -std::string Cells::getStatus() +std::string +Cells::getStatus() { - // Return cell's status - return this->StatusD[this->status]; + // Return cell's status + return this->StatusD[this->status]; } /** * @brief Ignites a cell. * - * Sets the following cell's attributes to represent ignition: status, fireStarts, fireStartsSeason, burnt. + * Sets the following cell's attributes to represent ignition: status, + * fireStarts, fireStartsSeason, burnt. * * @param period Current simulation period or timestep. * @param df_ptr Array containing cell-specific environmental and fuel data. - * @param coef Pointer to a structure containing fuel coefficients used in ROS calculations. + * @param coef Pointer to a structure containing fuel coefficients used in ROS + * calculations. * @param year Current simulation year * @param ignitionPoints Vector with ignition point. - * @param args Pointer to a structure containing global simulation arguments and configurations. - * The ROS threshold should be stored here with the key "ROSThreshold". - * @param wdf_ptr Pointer to the weather data structure containing wind speed, direction, and other weather variables. - * @param activeCrown A boolean reference indicating whether crown fire activity is ongoing. + * @param args Pointer to a structure containing global simulation arguments + * and configurations. The ROS threshold should be stored here with the key + * "ROSThreshold". + * @param wdf_ptr Pointer to the weather data structure containing wind speed, + * direction, and other weather variables. + * @param activeCrown A boolean reference indicating whether crown fire + * activity is ongoing. * @param perimeterCells size of a cell. * * * @return True if ignition happens, False if not. */ -bool Cells::ignition(int period, int year, std::vector &ignitionPoints, inputs *df_ptr, // WORKING CHECK OK - fuel_coefs *coef, arguments *args, weatherDF *wdf_ptr, bool &activeCrown, int perimeterCells) +bool +Cells::ignition(int period, + int year, + std::vector& ignitionPoints, + inputs* df_ptr, // WORKING CHECK OK + fuel_coefs* coef, + arguments* args, + weatherDF* wdf_ptr, + bool& activeCrown, + int perimeterCells) { - // If we have ignition points, update - if (ignitionPoints.size() > 0) - { - this->status = 1; - this->fireStarts = period; - this->fireStartsSeason = year; - this->burntP = period; - - // An ignition has happened - return true; - } - else - { - // Ignites if implied head ros andfire intensity are high enough - main_outs mainstruct; - snd_outs sndstruct; - fire_struc headstruct, backstruct, flankstruct; - - // printf("\nWeather inside ignition:\n"); - // std::cout << "waz: " << wdf_ptr->waz << " ffmc: " << wdf_ptr->ffmc << " bui: " << wdf_ptr->bui << std::endl; - - // Populate inputs - df_ptr->waz = wdf_ptr->waz; - df_ptr->ws = wdf_ptr->ws; - df_ptr->bui = wdf_ptr->bui; - df_ptr->ffmc = wdf_ptr->ffmc; - int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation - if (head_cell <= 0) // solve boundaries case - { - head_cell = this->realId; // as it is used only for slope calculation, if it is a boundary cell, it uses the same cell, so it uses a no slope scenario - } - // Calculate parameters - if (args->Simulator == "K") - { - calculate_k(&df_ptr[this->realId - 1], &df_ptr[head_cell - 1], perimeterCells, coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "S") - { - calculate_s(&df_ptr[this->realId - 1], coef, args, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct, activeCrown); - } - else if (args->Simulator == "C") - { - calculate_fbp(&df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); - } - - if (args->verbose) - { - std::cout << "\nIn ignition function" << std::endl; - std::cout << "Main Angle: " << wdf_ptr->waz << std::endl; - std::cout << "Front ROS Value: " << headstruct.ros * args->HFactor << std::endl; - std::cout << "Flanks ROS Value: " << flankstruct.ros * args->FFactor << std::endl; - std::cout << "Rear ROS Value: " << backstruct.ros * args->BFactor << std::endl; - } - - // Check a threshold for the ROS - if (headstruct.ros * args->HFactor > args->ROSThreshold) - { - if (args->verbose) - { - std::cout << "Head (ROS, FI) values of: (" << headstruct.ros * args->HFactor << ", " << headstruct.fi << ") are enough for ignition" << std::endl; - } - - this->status = 1; - this->fireStarts = period; - this->fireStartsSeason = year; - this->burntP = period; - - return true; - } - return false; - } + // If we have ignition points, update + if (ignitionPoints.size() > 0) + { + this->status = 1; + this->fireStarts = period; + this->fireStartsSeason = year; + this->burntP = period; + + // An ignition has happened + return true; + } + else + { + // Ignites if implied head ros andfire intensity are high enough + main_outs mainstruct; + snd_outs sndstruct; + fire_struc headstruct, backstruct, flankstruct; + + // printf("\nWeather inside ignition:\n"); + // std::cout << "waz: " << wdf_ptr->waz << " ffmc: " << wdf_ptr->ffmc + // << " bui: " << wdf_ptr->bui << std::endl; + + // Populate inputs + df_ptr->waz = wdf_ptr->waz; + df_ptr->ws = wdf_ptr->ws; + df_ptr->bui = wdf_ptr->bui; + df_ptr->ffmc = wdf_ptr->ffmc; + int head_cell = angleToNb[wdf_ptr->waz]; // head cell for slope calculation + if (head_cell <= 0) // solve boundaries case + { + head_cell = this->realId; // as it is used only for slope calculation, if + // it is a boundary cell, it uses the same cell, + // so it uses a no slope scenario + } + // Calculate parameters + if (args->Simulator == "K") + { + calculate_k(&df_ptr[this->realId - 1], + &df_ptr[head_cell - 1], + perimeterCells, + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "S") + { + calculate_s(&df_ptr[this->realId - 1], + coef, + args, + &mainstruct, + &sndstruct, + &headstruct, + &flankstruct, + &backstruct, + activeCrown); + } + else if (args->Simulator == "C") + { + calculate_fbp( + &df_ptr[this->realId - 1], coef, &mainstruct, &sndstruct, &headstruct, &flankstruct, &backstruct); + } + + if (args->verbose) + { + std::cout << "\nIn ignition function" << std::endl; + std::cout << "Main Angle: " << wdf_ptr->waz << std::endl; + std::cout << "Front ROS Value: " << headstruct.ros * args->HFactor << std::endl; + std::cout << "Flanks ROS Value: " << flankstruct.ros * args->FFactor << std::endl; + std::cout << "Rear ROS Value: " << backstruct.ros * args->BFactor << std::endl; + } + + // Check a threshold for the ROS + if (headstruct.ros * args->HFactor > args->ROSThreshold) + { + if (args->verbose) + { + std::cout << "Head (ROS, FI) values of: (" << headstruct.ros * args->HFactor << ", " << headstruct.fi + << ") are enough for ignition" << std::endl; + } + + this->status = 1; + this->fireStarts = period; + this->fireStartsSeason = year; + this->burntP = period; + + return true; + } + return false; + } } /* - Returns void - Inputs - ID int - period int + Returns void + Inputs + ID int + period int */ -void Cells::harvested(int id, int period) -{ // WORKING CHECK OK - // TODO: unused param - this->status = 3; - this->harvestStarts = period; +void +Cells::harvested(int id, int period) +{ // WORKING CHECK OK + // TODO: unused param + this->status = 3; + this->harvestStarts = period; } /* - Returns void + Returns void */ -void Cells::print_info() -{ // WORKING CHECK OK - std::cout << "Cell Information" << std::endl; - std::cout << "ID = " << this->id << std::endl; - std::cout << "In Forest ID = " << this->realId << std::endl; - std::cout << "Status = " << this->StatusD[this->status] << std::endl; - std::cout << "Coordinates: "; - std::cout << this->coord[0] << " " << this->coord[1] << std::endl; - - std::cout << "Area = " << this->area << std::endl; - std::cout << "FTypes = " << this->FTypeD[this->fType] << std::endl; - std::cout << "AdjacentCells:"; - // for (auto & nb : this->adjacents){ - // std::cout << " " << nb.first << ":" << nb.second; - // } - std::cout << std::endl; - - printf("Angle Dict: "); - for (auto &nb : this->angleDict) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - - printf("Ros Angle Dict: "); - for (auto &nb : this->ROSAngleDir) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - - printf("angleToNb Dict: "); - for (auto &nb : this->angleToNb) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - - printf("fireProgress Dict: "); - for (auto &nb : this->fireProgress) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; - - printf("distToCenter Dict: "); - for (auto &nb : this->distToCenter) - { - std::cout << " " << nb.first << " : " << nb.second; - } - std::cout << std::endl; +void +Cells::print_info() +{ // WORKING CHECK OK + std::cout << "Cell Information" << std::endl; + std::cout << "ID = " << this->id << std::endl; + std::cout << "In Forest ID = " << this->realId << std::endl; + std::cout << "Status = " << this->StatusD[this->status] << std::endl; + std::cout << "Coordinates: "; + std::cout << this->coord[0] << " " << this->coord[1] << std::endl; + + std::cout << "Area = " << this->area << std::endl; + std::cout << "FTypes = " << this->FTypeD[this->fType] << std::endl; + std::cout << "AdjacentCells:"; + // for (auto & nb : this->adjacents){ + // std::cout << " " << nb.first << ":" << nb.second; + // } + std::cout << std::endl; + + printf("Angle Dict: "); + for (auto& nb : this->angleDict) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + + printf("Ros Angle Dict: "); + for (auto& nb : this->ROSAngleDir) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + + printf("angleToNb Dict: "); + for (auto& nb : this->angleToNb) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + + printf("fireProgress Dict: "); + for (auto& nb : this->fireProgress) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; + + printf("distToCenter Dict: "); + for (auto& nb : this->distToCenter) + { + std::cout << " " << nb.first << " : " << nb.second; + } + std::cout << std::endl; } diff --git a/Cell2Fire/Cells.h b/Cell2Fire/Cells.h index 36c77f42..52441ad0 100644 --- a/Cell2Fire/Cells.h +++ b/Cell2Fire/Cells.h @@ -2,143 +2,201 @@ #define CELLS // include stuff -#include "ReadArgs.h" #include "Ellipse.h" +#include "ReadArgs.h" -#include #include +#include +#include #include #include -#include #include using namespace std; std::vector adjacentCells(int cell, int nrows, int ncols); /* -* Weather structure -*/ + * Weather structure + */ typedef struct - { float ws, waz,rh,tmp,apcp,ffmc,dmc,dc,isi,bui,fwi; //David: some variables only used on C2FK and not on C2FSB and viceversa - } weatherDF; //David: Moved here to simplify inclusion - +{ + float ws, waz, rh, tmp, apcp, ffmc, dmc, dc, isi, bui, + fwi; // David: some variables only used on C2FK and not on C2FSB and + // viceversa +} weatherDF; // David: Moved here to simplify inclusion typedef struct - { char fueltype[4]; - float ws, saz, cur, ps, cbh, ccf, cbd, elev, tmp, rh,lat,lon,ffmc,bui,gfl; //David: some variables only used on C2FK and not on C2FSB and viceversa - int waz, nftype,FMC,time,pattern,mon, jd,jd_min,pc,pdf; - } inputs; //David: Moved here to simplify inclusion - +{ + char fueltype[4]; + float ws, saz, cur, ps, cbh, ccf, cbd, elev, tmp, rh, lat, lon, ffmc, bui, + gfl; // David: some variables only used on C2FK and not on C2FSB and + // viceversa + int waz, nftype, FMC, time, pattern, mon, jd, jd_min, pc, pdf; +} inputs; // David: Moved here to simplify inclusion typedef struct - { char fueltype[4] ; - float p1, p2, p3 ; // hros coef - float q1, q2, q3 ; // flame length coef - float q, bui0,cfl ; // fbp params - float cbh,fmc,fl,h; +{ + char fueltype[4]; + float p1, p2, p3; // hros coef + float q1, q2, q3; // flame length coef + float q, bui0, cfl; // fbp params + float cbh, fmc, fl, h; int nftype; - } fuel_coefs; +} fuel_coefs; - typedef struct - { float hffmc,sfc,csi,fl, fh, a, b, c, rss, angle, - ros_active,cfb,se,rso,fmc,sfi,isi,be,sf,raz,wsv,ff; - char covertype; - int crown,jd_min,jd; - } main_outs; +typedef struct +{ + float hffmc, sfc, csi, fl, fh, a, b, c, rss, angle, ros_active, cfb, se, rso, fmc, sfi, isi, be, sf, raz, wsv, ff; + char covertype; + int crown, jd_min, jd; +} main_outs; typedef struct - { float ros,dist,rost,cfb,fc,cfc,time,rss,isi; +{ + float ros, dist, rost, cfb, fc, cfc, time, rss, isi; char fd; double fi; - } fire_struc; - - - typedef struct - { float lb, area, perm, pgr, lbt; - } snd_outs; +} fire_struc; +typedef struct +{ + float lb, area, perm, pgr, lbt; +} snd_outs; -class Cells { +class Cells +{ // TODO: find where to put the enums - public: - // immutable - int id; - int fType; - int realId; - double _ctr2ctrdist; - double area; - double perimeter; - - std::string fType2; - std::vector coord; //maybe change this into a tuple or class CP: 2-tuple (int) - //std::unordered_map adjacents; // CP: dictionary {string: [int array]} - - string FTypeD[3]; - string StatusD[5]; - - // mutable - int status; - int hPeriod; - int fireStarts; - int harvestStarts; - int fireStartsSeason; - int burntP; - int tYears; - - std::unordered_map> gMsgList; // {40 -> [1, 2, 3] } - std::unordered_map> gMsgListSeason; - std::unordered_map fireProgress; // CP: dictionary {int: double} - std::unordered_map angleDict; // CP: dictionary {int: double} - std::unordered_map ROSAngleDir; // CP: dictionary {int: double|None} Instead of None we can use a determined number like -9999 = None TODO: maybe int : double - std::unordered_map distToCenter; // CP: dictionary {int: double} - std::unordered_map angleToNb; // CP: dictionary {double: int} - - // TODO: reference to shared object - - // constructor and methods here - Cells(int _id, double _area, std::vector _coord, - int _fType, std::string _fType2, double _perimeter, - int _status, int _realId); - - void initializeFireFields(std::vector> & coordCells, std::unordered_set & availSet,int cols,int rows); // TODO: need TYPE - void ros_distr_old(double thetafire, double forward, double flank, double back); - double rhoTheta(double theta, double a, double b); - void ros_distr(double thetafire, double forward, double flank, double back, double EFactor); - void ros_distr_V2(double thetafire, double a, double b, double c, double EFactor); - - std::vector manageFire(int period, std::unordered_set & AvailSet, - inputs df[], fuel_coefs * coef, - std::vector> & coordCells, std::unordered_map & Cells_Obj, - arguments * args, weatherDF * wdf_ptr, std::vector * FSCell, std::vector * crownMetrics, - bool & activeCrown,double randomROS,int perimeterCells,std::vector & crownState, std::vector & crownFraction,std::vector & surfFraction, std::vector & Intensities, std::vector & RateOfSpreads, std::vector & FlameLengths); - - std::vector manageFireBBO(int period, std::unordered_set & AvailSet, - inputs * df_ptr, fuel_coefs * coef, - std::vector> & coordCells, std::unordered_map & Cells_Obj, - arguments * args, weatherDF * wdf_ptr, std::vector * FSCell, std::vector * crownMetrics, - bool & activeCrown,double randomROS,int perimeterCells, std::vector & EllipseFactors,std::vector & crownState, std::vector & crownFraction,std::vector & surfFraction, std::vector & Intensities, std::vector & RateOfSpreads, std::vector & FlameLengths); - - bool get_burned(int period, int season, int NMsg, inputs df[], fuel_coefs * coef, arguments * args, weatherDF * wdf_ptr,bool & activeCrown,int perimeterCells) ; - - //void set_Adj(std::unordered_map & adjacentCells); - - void setStatus(int status_int); - - std::string getStatus(); - - bool ignition(int period, int year, std::vector & ignitionPoints, inputs * df_ptr, // WORKING CHECK OK - fuel_coefs * coef, arguments *args, weatherDF * wdf_ptr,bool & activeCrown,int perimeterCells); - - void harvested(int id, int period); - - void print_info(); - - - - - private: - double allocate(double offset, double base, double ros1, double ros2); - float slope_effect(float elev_i, float elev_j, int cellsize); + public: + // immutable + int id; + int fType; + int realId; + double _ctr2ctrdist; + double area; + double perimeter; + + std::string fType2; + std::vector coord; // maybe change this into a tuple or class CP: 2-tuple (int) + // std::unordered_map adjacents; // CP: dictionary {string: + // [int array]} + + string FTypeD[3]; + string StatusD[5]; + + // mutable + int status; + int hPeriod; + int fireStarts; + int harvestStarts; + int fireStartsSeason; + int burntP; + int tYears; + + std::unordered_map> gMsgList; // {40 -> [1, 2, 3] } + std::unordered_map> gMsgListSeason; + std::unordered_map fireProgress; // CP: dictionary {int: double} + std::unordered_map angleDict; // CP: dictionary {int: double} + std::unordered_map ROSAngleDir; // CP: dictionary {int: double|None} Instead of None we + // can use a determined number like -9999 = None TODO: + // maybe int : double + std::unordered_map distToCenter; // CP: dictionary {int: double} + std::unordered_map angleToNb; // CP: dictionary {double: int} + + // TODO: reference to shared object + + // constructor and methods here + Cells(int _id, + double _area, + std::vector _coord, + int _fType, + std::string _fType2, + double _perimeter, + int _status, + int _realId); + + void initializeFireFields(std::vector>& coordCells, + std::unordered_set& availSet, + int cols, + int rows); // TODO: need TYPE + void ros_distr_old(double thetafire, double forward, double flank, double back); + double rhoTheta(double theta, double a, double b); + void ros_distr(double thetafire, double forward, double flank, double back, double EFactor); + void ros_distr_V2(double thetafire, double a, double b, double c, double EFactor); + + std::vector manageFire(int period, + std::unordered_set& AvailSet, + inputs df[], + fuel_coefs* coef, + std::vector>& coordCells, + std::unordered_map& Cells_Obj, + arguments* args, + weatherDF* wdf_ptr, + std::vector* FSCell, + std::vector* crownMetrics, + bool& activeCrown, + double randomROS, + int perimeterCells, + std::vector& crownState, + std::vector& crownFraction, + std::vector& surfFraction, + std::vector& Intensities, + std::vector& RateOfSpreads, + std::vector& FlameLengths); + + std::vector manageFireBBO(int period, + std::unordered_set& AvailSet, + inputs* df_ptr, + fuel_coefs* coef, + std::vector>& coordCells, + std::unordered_map& Cells_Obj, + arguments* args, + weatherDF* wdf_ptr, + std::vector* FSCell, + std::vector* crownMetrics, + bool& activeCrown, + double randomROS, + int perimeterCells, + std::vector& EllipseFactors, + std::vector& crownState, + std::vector& crownFraction, + std::vector& surfFraction, + std::vector& Intensities, + std::vector& RateOfSpreads, + std::vector& FlameLengths); + + bool get_burned(int period, + int season, + int NMsg, + inputs df[], + fuel_coefs* coef, + arguments* args, + weatherDF* wdf_ptr, + bool& activeCrown, + int perimeterCells); + + // void set_Adj(std::unordered_map & adjacentCells); + + void setStatus(int status_int); + + std::string getStatus(); + + bool ignition(int period, + int year, + std::vector& ignitionPoints, + inputs* df_ptr, // WORKING CHECK OK + fuel_coefs* coef, + arguments* args, + weatherDF* wdf_ptr, + bool& activeCrown, + int perimeterCells); + + void harvested(int id, int period); + + void print_info(); + + private: + double allocate(double offset, double base, double ros1, double ros2); + float slope_effect(float elev_i, float elev_j, int cellsize); }; #endif diff --git a/Cell2Fire/DataGenerator.cpp b/Cell2Fire/DataGenerator.cpp index be5a2a28..e97734f2 100644 --- a/Cell2Fire/DataGenerator.cpp +++ b/Cell2Fire/DataGenerator.cpp @@ -2,32 +2,37 @@ #include "DataGenerator.h" -#include +#include "tiffio.h" +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include -#include -#include #include -#include -#include -#include -#include "tiffio.h" -#include -#include -#include +#include -inline char separator() +inline char +separator() { #if defined _WIN32 || defined __CYGWIN__ - return '\\'; + return '\\'; #else - return '/'; + return '/'; #endif } -// Reads fbp_lookup_table.csv and creates dictionaries for the fuel types and cells' ColorsDict -std::tuple, std::unordered_map>> Dictionary(const std::string& filename) { +// Reads fbp_lookup_table.csv and creates dictionaries for the fuel types and +// cells' ColorsDict +std::tuple, + std::unordered_map>> +Dictionary(const std::string& filename) +{ std::unordered_map FBPDict; std::unordered_map> ColorsDict; @@ -37,27 +42,32 @@ std::tuple, std::unordered_map 1) { + while (std::getline(file, line)) + { + if (aux > 1) + { aux += 1; // Replace hyphen size_t hyphenPos = line.find('-'); - while (hyphenPos != std::string::npos) { + while (hyphenPos != std::string::npos) + { line.replace(hyphenPos, 1, ""); hyphenPos = line.find('-'); } // Replace newline size_t newlinePos = line.find('\n'); - while (newlinePos != std::string::npos) { + while (newlinePos != std::string::npos) + { line.replace(newlinePos, 1, ""); newlinePos = line.find('\n'); } // Replace "No" with "NF" size_t noPos = line.find("No"); - while (noPos != std::string::npos) { + while (noPos != std::string::npos) + { line.replace(noPos, 2, "NF"); noPos = line.find("No"); } @@ -66,30 +76,32 @@ std::tuple, std::unordered_map tokens; std::string token; - while (std::getline(ss, token, ',')) { + while (std::getline(ss, token, ',')) + { tokens.push_back(token); } - if (tokens[3].substr(0, 3) == "FM1") { + if (tokens[3].substr(0, 3) == "FM1") + { FBPDict[tokens[0]] = tokens[3].substr(0, 4); - } else if (tokens[3].substr(0, 3) == "Non" || tokens[3].substr(0, 3) == "NFn") { + } + else if (tokens[3].substr(0, 3) == "Non" || tokens[3].substr(0, 3) == "NFn") + { FBPDict[tokens[0]] = "NF"; - } else { + } + else + { FBPDict[tokens[0]] = tokens[3].substr(0, 3); } ColorsDict[tokens[0]] = std::make_tuple( - std::stof(tokens[4]) / 255.0f, - std::stof(tokens[5]) / 255.0f, - std::stof(tokens[6]) / 255.0f, - 1.0f - ); + std::stof(tokens[4]) / 255.0f, std::stof(tokens[5]) / 255.0f, std::stof(tokens[6]) / 255.0f, 1.0f); } - if (aux == 1) { + if (aux == 1) + { aux += 1; } - } return std::make_tuple(FBPDict, ColorsDict); @@ -97,9 +109,11 @@ std::tuple, std::unordered_map, std::vector, int, int, float> -ForestGrid(const std::string& filename, const std::unordered_map& Dictionary) { +ForestGrid(const std::string& filename, const std::unordered_map& Dictionary) +{ std::ifstream file(filename); - if (!file.is_open()) { + if (!file.is_open()) + { throw std::runtime_error("Error: Could not open file '" + filename + "'"); } @@ -107,7 +121,8 @@ ForestGrid(const std::string& filename, const std::unordered_map> key >> value) || key != "cellsize") { + if (!(iss >> key >> value) || key != "cellsize") + { std::cerr << "line=" << line << std::endl; throw std::runtime_error("Expected 'cellsize' on line 5 of " + filename); } @@ -135,38 +151,44 @@ ForestGrid(const std::string& filename, const std::unordered_map> grid2; // Read the ASCII file with the grid structure - for (size_t i = 6; i < filelines.size(); ++i) { - line = filelines[i]; + for (size_t i = 6; i < filelines.size(); ++i) + { + line = filelines[i]; - // Remove newline characters - line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); + // Remove newline characters + line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); - // Remove leading and trailing whitespaces - line.erase(line.begin(), std::find_if(line.begin(), line.end(), [](char c) { return !std::isspace(c); })); - line.erase(std::find_if(line.rbegin(), line.rend(), [](char c) { return !std::isspace(c); }).base(), line.end()); + // Remove leading and trailing whitespaces + line.erase(line.begin(), std::find_if(line.begin(), line.end(), [](char c) { return !std::isspace(c); })); + line.erase(std::find_if(line.rbegin(), line.rend(), [](char c) { return !std::isspace(c); }).base(), + line.end()); - std::istringstream iss(line); - std::string token; - while (iss >> token) { - if (Dictionary.find(token) == Dictionary.end()) { - gridcell1.push_back("NF"); - gridcell2.push_back("NF"); - gridcell3.push_back(0); - gridcell4.push_back("NF"); - } else { - gridcell1.push_back(token); - gridcell2.push_back(Dictionary.at(token)); - gridcell3.push_back(std::stoi(token)); - gridcell4.push_back(Dictionary.at(token)); - } - tcols = std::max(tcols, static_cast(gridcell1.size())); - } - - grid.push_back(gridcell1); - grid2.push_back(gridcell2); - gridcell1.clear(); - gridcell2.clear(); -} + std::istringstream iss(line); + std::string token; + while (iss >> token) + { + if (Dictionary.find(token) == Dictionary.end()) + { + gridcell1.push_back("NF"); + gridcell2.push_back("NF"); + gridcell3.push_back(0); + gridcell4.push_back("NF"); + } + else + { + gridcell1.push_back(token); + gridcell2.push_back(Dictionary.at(token)); + gridcell3.push_back(std::stoi(token)); + gridcell4.push_back(Dictionary.at(token)); + } + tcols = std::max(tcols, static_cast(gridcell1.size())); + } + + grid.push_back(gridcell1); + grid2.push_back(gridcell2); + gridcell1.clear(); + gridcell2.clear(); + } // Adjacent list of dictionaries and Cells coordinates std::vector> CoordCells; CoordCells.reserve(grid.size() * tcols); @@ -177,15 +199,20 @@ ForestGrid(const std::string& filename, const std::unordered_map& data, int nCells) { +void +DataGrids(const std::string& filename, std::vector& data, int nCells) +{ std::ifstream file(filename); - if (!file.is_open()) { + if (!file.is_open()) + { std::cerr << "Error: Could not open file '" << filename << "'" << std::endl; return; } @@ -194,7 +221,8 @@ void DataGrids(const std::string& filename, std::vector& data, int nCells // Read all lines from the file std::string line; - while (std::getline(file, line)) { + while (std::getline(file, line)) + { filelines.push_back(line); } @@ -204,7 +232,8 @@ void DataGrids(const std::string& filename, std::vector& data, int nCells std::istringstream iss(line); std::string key, value; - if (!(iss >> key >> value) || key != "cellsize") { + if (!(iss >> key >> value) || key != "cellsize") + { std::cerr << "Error: Expected 'cellsize' on line 5 of " << filename << std::endl; return; } @@ -214,39 +243,44 @@ void DataGrids(const std::string& filename, std::vector& data, int nCells int aux = 0; // Read the ASCII file with the grid structure - for (size_t i = 6; i < filelines.size(); ++i) { + for (size_t i = 6; i < filelines.size(); ++i) + { line = filelines[i]; line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); line = ' ' + line; std::istringstream iss(line); std::string token; - while (iss >> token) { + while (iss >> token) + { data[aux++] = std::stof(token); - if (aux == nCells) { + if (aux == nCells) + { return; // Stop reading if we've filled the data vector } } } - - } std::tuple, std::vector, int, int, float> -ForestGridTif(const std::string& filename, const std::unordered_map& Dictionary) { +ForestGridTif(const std::string& filename, const std::unordered_map& Dictionary) +{ /* Reads fuel data from a .tif Args: filename (std::string): Name of .tif file. - Dictionary (std::unordered_map&): Reference to fuels dictionary + Dictionary (std::unordered_map&): Reference to + fuels dictionary Returns: - Fuel vectors, number of cells y cell size (tuple[std::vector, std::vector) + Fuel vectors, number of cells y cell size (tuple[std::vector, + std::vector) */ // Tries to open file std::cout << filename << '\n'; TIFF* fuelsDataset = TIFFOpen(filename.c_str(), "r"); - if (!fuelsDataset) { + if (!fuelsDataset) + { throw std::runtime_error("Error: Could not open file '" + filename + "'"); } @@ -275,80 +309,92 @@ ForestGridTif(const std::string& filename, const std::unordered_map::epsilon(); - if (fabs(cellSizeX - cellSizeY) > epsilon) { + if (fabs(cellSizeX - cellSizeY) > epsilon) + { throw std::runtime_error("Error: Cells are not square in: '" + filename + "'"); } // Read raster data // Allocate memory for one row of pixel data - void *buf; - if (n_bits == 64){ + void* buf; + if (n_bits == 64) + { buf = (double*)_TIFFmalloc(nXSize * sizeof(double)); } - else if (n_bits == 32) { + else if (n_bits == 32) + { buf = (int32_t*)_TIFFmalloc(nXSize * sizeof(int32_t)); - } - else { + } + else + { throw std::runtime_error("Error: file type is not supported: '" + filename + "'"); } - - if (!buf) { + + if (!buf) + { TIFFClose(fuelsDataset); throw std::runtime_error("Could not allocate memory"); } // For each row - for (int i = 0; i < nYSize; i++) { + for (int i = 0; i < nYSize; i++) + { // Read pixel values for the current row - if (TIFFReadScanline(fuelsDataset, buf, i) != 1) { + if (TIFFReadScanline(fuelsDataset, buf, i) != 1) + { _TIFFfree(buf); TIFFClose(fuelsDataset); throw std::runtime_error("Read error on row " + std::to_string(i)); } // For each column float pixelValue; - std::string token; - for (int j = 0; j < nXSize; j++) { - if (n_bits == 64){ - double *values = (double *) buf; - pixelValue = ((double *) buf)[j]; - token = std::to_string(static_cast( ((double *) buf)[j])); - } - else { - float *values = (float *) buf; - pixelValue = ((int32_t *) buf)[j]; - token = std::to_string(static_cast( ((int32_t *) buf)[j])); + std::string token; + for (int j = 0; j < nXSize; j++) + { + if (n_bits == 64) + { + double* values = (double*)buf; + pixelValue = ((double*)buf)[j]; + token = std::to_string(static_cast(((double*)buf)[j])); + } + else + { + float* values = (float*)buf; + pixelValue = ((int32_t*)buf)[j]; + token = std::to_string(static_cast(((int32_t*)buf)[j])); } // Access the pixel value at position (i, j) - //std::cout << token << '\n'; - //std::cout << pixelValue << '\n'; - if (pixelValue != pixelValue || Dictionary.find(token) == Dictionary.end()) { - // If fuel not in Dictionary: - gridcell1.push_back("NF"); - - gridcell2.push_back("NF"); - - gridcell3.push_back(0); - gridcell4.push_back("NF"); - } else { - - gridcell1.push_back(token); - gridcell2.push_back(Dictionary.at(token)); - gridcell3.push_back(std::stoi(token)); - gridcell4.push_back(Dictionary.at(token)); + // std::cout << token << '\n'; + // std::cout << pixelValue << '\n'; + if (pixelValue != pixelValue || Dictionary.find(token) == Dictionary.end()) + { + // If fuel not in Dictionary: + gridcell1.push_back("NF"); + + gridcell2.push_back("NF"); + + gridcell3.push_back(0); + gridcell4.push_back("NF"); + } + else + { + + gridcell1.push_back(token); + gridcell2.push_back(Dictionary.at(token)); + gridcell3.push_back(std::stoi(token)); + gridcell4.push_back(Dictionary.at(token)); } tcols = std::max(tcols, static_cast(gridcell1.size())); - - } + } grid.push_back(gridcell1); grid2.push_back(gridcell2); gridcell1.clear(); - gridcell2.clear(); + gridcell2.clear(); } std::vector> CoordCells; CoordCells.reserve(grid.size() * tcols); @@ -359,34 +405,40 @@ ForestGridTif(const std::string& filename, const std::unordered_map& data, int nCells) { - /* - Reads fuel data from a .tif - Args: - filename (std::string): Name of .tif file. - Dictionary (std::unordered_map&): Reference to fuels dictionary +void +DataGridsTif(const std::string& filename, std::vector& data, int nCells) +{ + /* + Reads fuel data from a .tif + Args: + filename (std::string): Name of .tif file. + Dictionary (std::unordered_map&): Reference to + fuels dictionary - Returns: - Fuel vectors, number of cells y cell size (tuple[std::vector, std::vector) - */ + Returns: + Fuel vectors, number of cells y cell size (tuple[std::vector, + std::vector) + */ // Tries to open file std::cout << filename << '\n'; TIFF* fuelsDataset = TIFFOpen(filename.c_str(), "r"); - if (!fuelsDataset) { + if (!fuelsDataset) + { throw std::runtime_error("Error: Could not open file '" + filename + "'"); } std::vector filelines; // Get cell side double* modelPixelScale; - uint32_t count; - //TIFFGetField(tiff, 33424, &count, &data); + uint32_t count; + // TIFFGetField(tiff, 33424, &count, &data); TIFFGetField(fuelsDataset, 33550, &count, &modelPixelScale); // Gets cell size - double cellSizeX {modelPixelScale[0]}; - double cellSizeY {modelPixelScale[1]}; + double cellSizeX{ modelPixelScale[0] }; + double cellSizeY{ modelPixelScale[1] }; const double epsilon = std::numeric_limits::epsilon(); - if (fabs(cellSizeX - cellSizeY) > epsilon) { + if (fabs(cellSizeX - cellSizeY) > epsilon) + { throw std::runtime_error("Error: Cells are not square in: '" + filename + "'"); } double cellsize; @@ -400,101 +452,166 @@ void DataGridsTif(const std::string& filename, std::vector& data, int nCe int aux = 0; // Read raster data // Allocate memory for one row of pixel data - void *buf; - if (n_bits == 64){ + void* buf; + if (n_bits == 64) + { buf = (double*)_TIFFmalloc(nXSize * sizeof(double)); } - else if (n_bits == 32) { + else if (n_bits == 32) + { buf = (float*)_TIFFmalloc(nXSize * sizeof(float)); - } - else { + } + else + { throw std::runtime_error("Error: file type is not supported: '" + filename + "'"); } - if (!buf) { + if (!buf) + { TIFFClose(fuelsDataset); throw std::runtime_error("Could not allocate memory"); } // For each row // For each column float pixelValue; - for (int i = 0; i < nYSize; i++) { + for (int i = 0; i < nYSize; i++) + { // Read pixel values for the current row - if (TIFFReadScanline(fuelsDataset, buf, i) != 1) { + if (TIFFReadScanline(fuelsDataset, buf, i) != 1) + { _TIFFfree(buf); TIFFClose(fuelsDataset); throw std::runtime_error("Read error on row " + std::to_string(i)); } // For each column - for (int j = 0; j < nXSize; j++) { + for (int j = 0; j < nXSize; j++) + { // Access the pixel value at position (i, j) - if (n_bits == 64){ - double *values = (double *) buf; - pixelValue = ((double *) buf)[j]; - } - else { - float *values = (float *) buf; - pixelValue = ((int32_t *) buf)[j]; + if (n_bits == 64) + { + double* values = (double*)buf; + pixelValue = ((double*)buf)[j]; } - if (pixelValue == pixelValue){ - //std::cout << token << '\n'; + else + { + float* values = (float*)buf; + pixelValue = ((int32_t*)buf)[j]; + } + if (pixelValue == pixelValue) + { + // std::cout << token << '\n'; data[aux] = pixelValue; - } else { + } + else + { data[aux] = pixelValue; } aux++; - if (aux == nCells) { + if (aux == nCells) + { return; // Stop reading if we've filled the data vector } - } + } } } -std::vector>> GenerateDat(const std::vector& GFuelType, const std::vector& GFuelTypeN, - const std::vector& Elevation, const std::vector& PS, - const std::vector& SAZ, const std::vector& Curing, - const std::vector& CBD, const std::vector& CBH, - const std::vector& CCF, const std::vector& PY, - const std::vector& FMC, const std::string& InFolder) { +std::vector>> +GenerateDat(const std::vector& GFuelType, + const std::vector& GFuelTypeN, + const std::vector& Elevation, + const std::vector& PS, + const std::vector& SAZ, + const std::vector& Curing, + const std::vector& CBD, + const std::vector& CBH, + const std::vector& CCF, + const std::vector& PY, + const std::vector& FMC, + const std::string& InFolder) +{ // DF columns - std::vector Columns = {"fueltype", "lat", "lon", "elev", "ws", "waz", "ps", "saz", "cur", "cbd", "cbh", "ccf", "ftypeN", "fmc", "py", - "jd", "jd_min", "pc", "pdf", "time", "ffmc", "bui", "gfl", "pattern"}; + std::vector Columns + = { "fueltype", "lat", "lon", "elev", "ws", "waz", "ps", "saz", "cur", "cbd", "cbh", "ccf", + "ftypeN", "fmc", "py", "jd", "jd_min", "pc", "pdf", "time", "ffmc", "bui", "gfl", "pattern" }; // GFL dictionary (FBP) - std::unordered_map GFLD = { - {"C1", 0.75f}, {"C2", 0.8f}, {"C3", 1.15f}, {"C4", 1.2f}, {"C5", 1.2f}, {"C6", 1.2f}, {"C7", 1.2f}, - {"D1", static_cast(std::nanf(""))}, {"D2", static_cast(std::nanf(""))}, - {"S1", static_cast(std::nanf(""))}, {"S2", static_cast(std::nanf(""))}, {"S3", static_cast(std::nanf(""))}, - {"O1a", 0.35f}, {"O1b", 0.35f}, - {"M1", static_cast(std::nanf(""))}, {"M2", static_cast(std::nanf(""))}, {"M3", static_cast(std::nanf(""))}, {"M4", static_cast(std::nanf(""))}, {"NF", static_cast(std::nanf(""))}, - {"M1_5", 0.1f}, {"M1_10", 0.2f}, {"M1_15", 0.3f}, {"M1_20", 0.4f}, {"M1_25", 0.5f}, {"M1_30", 0.6f}, - {"M1_35", 0.7f}, {"M1_40", 0.8f}, {"M1_45", 0.8f}, {"M1_50", 0.8f}, {"M1_55", 0.8f}, {"M1_60", 0.8f}, - {"M1_65", 1.0f}, {"M1_70", 1.0f}, {"M1_75", 1.0f}, {"M1_80", 1.0f}, {"M1_85", 1.0f}, {"M1_90", 1.0f}, {"M1_95", 1.0f}}; + std::unordered_map GFLD = { { "C1", 0.75f }, + { "C2", 0.8f }, + { "C3", 1.15f }, + { "C4", 1.2f }, + { "C5", 1.2f }, + { "C6", 1.2f }, + { "C7", 1.2f }, + { "D1", static_cast(std::nanf("")) }, + { "D2", static_cast(std::nanf("")) }, + { "S1", static_cast(std::nanf("")) }, + { "S2", static_cast(std::nanf("")) }, + { "S3", static_cast(std::nanf("")) }, + { "O1a", 0.35f }, + { "O1b", 0.35f }, + { "M1", static_cast(std::nanf("")) }, + { "M2", static_cast(std::nanf("")) }, + { "M3", static_cast(std::nanf("")) }, + { "M4", static_cast(std::nanf("")) }, + { "NF", static_cast(std::nanf("")) }, + { "M1_5", 0.1f }, + { "M1_10", 0.2f }, + { "M1_15", 0.3f }, + { "M1_20", 0.4f }, + { "M1_25", 0.5f }, + { "M1_30", 0.6f }, + { "M1_35", 0.7f }, + { "M1_40", 0.8f }, + { "M1_45", 0.8f }, + { "M1_50", 0.8f }, + { "M1_55", 0.8f }, + { "M1_60", 0.8f }, + { "M1_65", 1.0f }, + { "M1_70", 1.0f }, + { "M1_75", 1.0f }, + { "M1_80", 1.0f }, + { "M1_85", 1.0f }, + { "M1_90", 1.0f }, + { "M1_95", 1.0f } }; // PDF dictionary (CANADA) - std::unordered_map PDFD = { - {"M3_5", 5}, {"M3_10", 10}, {"M3_15", 15}, {"M3_20", 20}, {"M3_25", 25}, {"M3_30", 30}, {"M3_35", 35}, {"M3_40", 40}, {"M3_45", 45}, {"M3_50", 50}, - {"M3_55", 55}, {"M3_60", 60}, {"M3_65", 65}, {"M3_70", 70}, {"M3_75", 75}, {"M3_80", 80}, {"M3_85", 85}, {"M3_90", 90}, {"M3_95", 95}, {"M4_5", 5}, - {"M4_10", 10}, {"M4_15", 15}, {"M4_20", 20}, {"M4_25", 25}, {"M4_30", 30}, {"M4_35", 35}, {"M4_40", 40}, {"M4_45", 45}, {"M4_50", 50}, {"M4_55", 55}, - {"M4_60", 60}, {"M4_65", 65}, {"M4_70", 70}, {"M4_75", 75}, {"M4_80", 80}, {"M4_85", 85}, {"M4_90", 90}, {"M4_95", 95}, {"M3M4_5", 5}, {"M3M4_10", 10}, - {"M3M4_15", 15}, {"M3M4_20", 20}, {"M3M4_25", 25}, {"M3M4_30", 30}, {"M3M4_35", 35}, {"M3M4_40", 40}, {"M3M4_45", 45}, {"M3M4_50", 50}, {"M3M4_55", 55}, - {"M3M4_60", 60}, {"M3M4_65", 65}, {"M3M4_70", 70}, {"M3M4_75", 75}, {"M3M4_80", 80}, {"M3M4_85", 85}, {"M3M4_90", 90}, {"M3M4_95", 95}}; + std::unordered_map PDFD + = { { "M3_5", 5 }, { "M3_10", 10 }, { "M3_15", 15 }, { "M3_20", 20 }, { "M3_25", 25 }, + { "M3_30", 30 }, { "M3_35", 35 }, { "M3_40", 40 }, { "M3_45", 45 }, { "M3_50", 50 }, + { "M3_55", 55 }, { "M3_60", 60 }, { "M3_65", 65 }, { "M3_70", 70 }, { "M3_75", 75 }, + { "M3_80", 80 }, { "M3_85", 85 }, { "M3_90", 90 }, { "M3_95", 95 }, { "M4_5", 5 }, + { "M4_10", 10 }, { "M4_15", 15 }, { "M4_20", 20 }, { "M4_25", 25 }, { "M4_30", 30 }, + { "M4_35", 35 }, { "M4_40", 40 }, { "M4_45", 45 }, { "M4_50", 50 }, { "M4_55", 55 }, + { "M4_60", 60 }, { "M4_65", 65 }, { "M4_70", 70 }, { "M4_75", 75 }, { "M4_80", 80 }, + { "M4_85", 85 }, { "M4_90", 90 }, { "M4_95", 95 }, { "M3M4_5", 5 }, { "M3M4_10", 10 }, + { "M3M4_15", 15 }, { "M3M4_20", 20 }, { "M3M4_25", 25 }, { "M3M4_30", 30 }, { "M3M4_35", 35 }, + { "M3M4_40", 40 }, { "M3M4_45", 45 }, { "M3M4_50", 50 }, { "M3M4_55", 55 }, { "M3M4_60", 60 }, + { "M3M4_65", 65 }, { "M3M4_70", 70 }, { "M3M4_75", 75 }, { "M3M4_80", 80 }, { "M3M4_85", 85 }, + { "M3M4_90", 90 }, { "M3M4_95", 95 } }; // PCD dictionary (CANADA) - std::unordered_map PCD = { - {"M3_5", 5}, {"M3_10", 10}, {"M3_15", 15}, {"M3_20", 20}, {"M3_25", 25}, {"M3_30", 30}, {"M3_35", 35}, {"M3_40", 40}, {"M3_45", 45}, {"M3_50", 50}, - {"M3_55", 55}, {"M3_60", 60}, {"M3_65", 65}, {"M3_70", 70}, {"M3_75", 75}, {"M3_80", 80}, {"M3_85", 85}, {"M3_90", 90}, {"M3_95", 95}, {"M4_5", 5}, - {"M4_10", 10}, {"M4_15", 15}, {"M4_20", 20}, {"M4_25", 25}, {"M4_30", 30}, {"M4_35", 35}, {"M4_40", 40}, {"M4_45", 45}, {"M4_50", 50}, {"M4_55", 55}, - {"M4_60", 60}, {"M4_65", 65}, {"M4_70", 70}, {"M4_75", 75}, {"M4_80", 80}, {"M4_85", 85}, {"M4_90", 90}, {"M4_95", 95}, {"M3M4_5", 5}, {"M3M4_10", 10}, - {"M3M4_15", 15}, {"M3M4_20", 20}, {"M3M4_25", 25}, {"M3M4_30", 30}, {"M3M4_35", 35}, {"M3M4_40", 40}, {"M3M4_45", 45}, {"M3M4_50", 50}, {"M3M4_55", 55}, - {"M3M4_60", 60}, {"M3M4_65", 65}, {"M3M4_70", 70}, {"M3M4_75", 75}, {"M3M4_80", 80}, {"M3M4_85", 85}, {"M3M4_90", 90}, {"M3M4_95", 95}}; + std::unordered_map PCD + = { { "M3_5", 5 }, { "M3_10", 10 }, { "M3_15", 15 }, { "M3_20", 20 }, { "M3_25", 25 }, + { "M3_30", 30 }, { "M3_35", 35 }, { "M3_40", 40 }, { "M3_45", 45 }, { "M3_50", 50 }, + { "M3_55", 55 }, { "M3_60", 60 }, { "M3_65", 65 }, { "M3_70", 70 }, { "M3_75", 75 }, + { "M3_80", 80 }, { "M3_85", 85 }, { "M3_90", 90 }, { "M3_95", 95 }, { "M4_5", 5 }, + { "M4_10", 10 }, { "M4_15", 15 }, { "M4_20", 20 }, { "M4_25", 25 }, { "M4_30", 30 }, + { "M4_35", 35 }, { "M4_40", 40 }, { "M4_45", 45 }, { "M4_50", 50 }, { "M4_55", 55 }, + { "M4_60", 60 }, { "M4_65", 65 }, { "M4_70", 70 }, { "M4_75", 75 }, { "M4_80", 80 }, + { "M4_85", 85 }, { "M4_90", 90 }, { "M4_95", 95 }, { "M3M4_5", 5 }, { "M3M4_10", 10 }, + { "M3M4_15", 15 }, { "M3M4_20", 20 }, { "M3M4_25", 25 }, { "M3M4_30", 30 }, { "M3M4_35", 35 }, + { "M3M4_40", 40 }, { "M3M4_45", 45 }, { "M3M4_50", 50 }, { "M3M4_55", 55 }, { "M3M4_60", 60 }, + { "M3M4_65", 65 }, { "M3M4_70", 70 }, { "M3M4_75", 75 }, { "M3M4_80", 80 }, { "M3M4_85", 85 }, + { "M3M4_90", 90 }, { "M3M4_95", 95 } }; // Create a vector to store unique_ptr of ~BaseData std::vector>> dataGrids; // Dataframe - // std::vector> DF(GFuelType.size(), std::vector(Columns.size())); + // std::vector> DF(GFuelType.size(), + // std::vector(Columns.size())); // Populate DF - for (size_t i = 0; i < GFuelType.size(); ++i) { + for (size_t i = 0; i < GFuelType.size(); ++i) + { std::vector> rowData; @@ -504,21 +621,20 @@ std::vector>> GenerateDat(const std::ve // lat 1 rowData.emplace_back(std::make_unique("51.621244")); - // lon 2 rowData.emplace_back(std::make_unique("-115.608378")); // Elevation 3 - + if (std::isnan(Elevation[i])) - + { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(Elevation[i]))); } - // Blank space (task: check why) 4,5 rowData.emplace_back(std::make_unique("")); @@ -527,25 +643,26 @@ std::vector>> GenerateDat(const std::ve // PS 6 if (std::isnan(PS[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(PS[i]))); } - // SAZ 7 if (std::isnan(SAZ[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(SAZ[i]))); } - - // Handle special cases 8 - if (std::isnan(Curing[i]) && (GFuelType[i] == "O1a" || GFuelType[i] == "O1b")) { + // Handle special cases 8 + if (std::isnan(Curing[i]) && (GFuelType[i] == "O1a" || GFuelType[i] == "O1b")) + { rowData.emplace_back(std::make_unique("60")); // "cur" } else @@ -556,55 +673,61 @@ std::vector>> GenerateDat(const std::ve // CBD 9 if (std::isnan(CBD[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(CBD[i]))); } // CBH 10 if (std::isnan(CBH[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(CBH[i]))); } // CCF 11 if (std::isnan(CCF[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(CCF[i]))); } // Fuel Type N 12 - //if (std::isnan(GFuelTypeN[i])) + // if (std::isnan(GFuelTypeN[i])) if (std::isnan(static_cast(GFuelTypeN[i]))) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(GFuelTypeN[i]))); } // FMC 13 if (std::isnan(FMC[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(FMC[i]))); } // PY 14 if (std::isnan(PY[i])) { - rowData.emplace_back(std::make_unique("")); + rowData.emplace_back(std::make_unique("")); } - else { + else + { rowData.emplace_back(std::make_unique(std::to_string(PY[i]))); } @@ -613,7 +736,8 @@ std::vector>> GenerateDat(const std::ve rowData.emplace_back(std::make_unique("")); // Populate PC 17 - if (PCD.find(GFuelType[i]) != PCD.end()) { + if (PCD.find(GFuelType[i]) != PCD.end()) + { rowData.emplace_back(std::make_unique(std::to_string(PCD[GFuelType[i]]))); // "pc" } else @@ -623,7 +747,8 @@ std::vector>> GenerateDat(const std::ve } // Populate PDF 18 - if (PDFD.find(GFuelType[i]) != PDFD.end()) { + if (PDFD.find(GFuelType[i]) != PDFD.end()) + { rowData.emplace_back(std::make_unique(std::to_string(PDFD[GFuelType[i]]))); // "pdf" } else @@ -639,90 +764,109 @@ std::vector>> GenerateDat(const std::ve rowData.emplace_back(std::make_unique("")); // GFL 22 - if (GFLD.find(GFuelType[i]) != GFLD.end()) { + if (GFLD.find(GFuelType[i]) != GFLD.end()) + { rowData.emplace_back(std::make_unique(std::to_string(GFLD[GFuelType[i]]))); // "gfl" } else { rowData.emplace_back(std::make_unique("")); } - - + rowData.emplace_back(std::make_unique("")); // Add the rowData to dataGrids dataGrids.push_back(std::move(rowData)); rowData.clear(); - - } - + return dataGrids; } // Function to write data to a CSV file -void writeDataToFile(const std::vector>>& dataGrids, const std::string& InFolder) +void +writeDataToFile(const std::vector>>& dataGrids, const std::string& InFolder) { std::ofstream dataFile(InFolder + separator() + "Data.csv"); - std::vector Columns = {"fueltype", "lat", "lon", "elev", "ws", "waz", "ps", "saz", "cur", "cbd", "cbh", "ccf", "ftypeN", "fmc", "py", - "jd", "jd_min", "pc", "pdf", "time", "ffmc", "bui", "gfl", "pattern"}; - if (dataFile.is_open()) { + std::vector Columns + = { "fueltype", "lat", "lon", "elev", "ws", "waz", "ps", "saz", "cur", "cbd", "cbh", "ccf", + "ftypeN", "fmc", "py", "jd", "jd_min", "pc", "pdf", "time", "ffmc", "bui", "gfl", "pattern" }; + if (dataFile.is_open()) + { // Write header - for (const auto& col : Columns) { + for (const auto& col : Columns) + { dataFile << col << ","; } dataFile << "\n"; // Write data - for (const auto& rowData : dataGrids) { - for (const auto& item : rowData) { + for (const auto& rowData : dataGrids) + { + for (const auto& item : rowData) + { dataFile << *item << ","; // Dereference the unique_ptr before writing - } - dataFile << "\n"; -} + } + dataFile << "\n"; + } std::cout << "Data file generated successfully" << std::endl; dataFile.close(); - } else { + } + else + { std::cerr << "Error: Unable to open data file for writing" << std::endl; } } // Main function -void GenDataFile(const std::string& InFolder, const std::string& Simulator) { +void +GenDataFile(const std::string& InFolder, const std::string& Simulator) +{ std::unordered_map FBPDict; std::unordered_map> ColorsDict; // Determine the lookup table based on the Simulator std::string lookupTable; - if (Simulator == "K") { + if (Simulator == "K") + { lookupTable = InFolder + separator() + "kitral_lookup_table.csv"; - } else if (Simulator == "S") { + } + else if (Simulator == "S") + { lookupTable = InFolder + separator() + "spain_lookup_table.csv"; - } else if (Simulator == "C") { + } + else if (Simulator == "C") + { lookupTable = InFolder + separator() + "fbp_lookup_table.csv"; - } else { - std::cerr << "Error: Simulator not recognized:" << Simulator << std::endl; - exit(1); + } + else + { + std::cerr << "Error: Simulator not recognized:" << Simulator << std::endl; + exit(1); } // Check if the lookup table exists - if (!fileExists(lookupTable)) { - std::cerr << "Error: Lookup table '" << lookupTable << "' not found" << std::endl; - return; + if (!fileExists(lookupTable)) + { + std::cerr << "Error: Lookup table '" << lookupTable << "' not found" << std::endl; + return; } // Call Dictionary function to read lookup table std::tie(FBPDict, ColorsDict) = Dictionary(lookupTable); // Call ForestGrid function - //If fuels.tif exists, then .tif's are used, otherwise .asc + // If fuels.tif exists, then .tif's are used, otherwise .asc std::string extension; - if(fileExists(InFolder + separator() + "fuels.tif")){ + if (fileExists(InFolder + separator() + "fuels.tif")) + { extension = ".tif"; - } else { + } + else + { extension = ".asc"; } std::cout << "Using " << extension << '\n'; @@ -732,15 +876,18 @@ void GenDataFile(const std::string& InFolder, const std::string& Simulator) { std::vector GFuelType; int FBPDicts, Cols; float CellSide; - if(extension == ".tif"){ + if (extension == ".tif") + { std::tie(GFuelTypeN, GFuelType, FBPDicts, Cols, CellSide) = ForestGridTif(FGrid, FBPDict); - } else{ + } + else + { std::tie(GFuelTypeN, GFuelType, FBPDicts, Cols, CellSide) = ForestGrid(FGrid, FBPDict); } // FOR DEBUGING ---------------------------------------------------------- /* - + // Print FBPDict std::cout << "FBPDict:\n"; for (const auto& entry : FBPDict) { @@ -750,8 +897,10 @@ void GenDataFile(const std::string& InFolder, const std::string& Simulator) { // Print ColorsDict std::cout << "ColorsDict:\n"; for (const auto& entry : ColorsDict) { - std::cout << " " << entry.first << ": " << std::get<0>(entry.second) << ", " - << std::get<1>(entry.second) << ", " << std::get<2>(entry.second) << ", " + std::cout << " " << entry.first << ": " << std::get<0>(entry.second) << + ", " + << std::get<1>(entry.second) << ", " << + std::get<2>(entry.second) << ", " << std::get<3>(entry.second) << std::endl; } @@ -769,9 +918,10 @@ void GenDataFile(const std::string& InFolder, const std::string& Simulator) { std::cout << "\n" << "FBPDicts:" << FBPDicts << "\n"; std::cout << "\n" << "Cols:" << Cols << "\n"; std::cout << "\n" << "CellSide:" << CellSide << "\n"; - + */ - // FOR DEBUGING ENDS HERE----------------------------------------------------- + // FOR DEBUGING ENDS + // HERE----------------------------------------------------- int NCells = GFuelType.size(); @@ -786,45 +936,68 @@ void GenDataFile(const std::string& InFolder, const std::string& Simulator) { std::vector PY(NCells, static_cast(std::nanf(""))); std::vector FMC(NCells, static_cast(std::nanf(""))); - std::vector filenames = { - "elevation" + extension, "saz" + extension, "slope" + extension, "cur" + extension, - "cbd" + extension, "cbh" + extension, "ccf" + extension, "py" + extension, "fmc" + extension - }; + std::vector filenames + = { "elevation" + extension, "saz" + extension, "slope" + extension, "cur" + extension, "cbd" + extension, + "cbh" + extension, "ccf" + extension, "py" + extension, "fmc" + extension }; - for (const auto& name : filenames) { + for (const auto& name : filenames) + { std::string filePath = InFolder + separator() + name; - if (fileExists(filePath)) { - if (name == "elevation.asc") { + if (fileExists(filePath)) + { + if (name == "elevation.asc") + { DataGrids(filePath, Elevation, NCells); - } else if (name == "saz.asc") { + } + else if (name == "saz.asc") + { DataGrids(filePath, SAZ, NCells); - } else if (name == "slope.asc") { + } + else if (name == "slope.asc") + { DataGrids(filePath, PS, NCells); - } else if (name == "cur.asc") { + } + else if (name == "cur.asc") + { DataGrids(filePath, Curing, NCells); - } else if (name == "cbd.asc") { + } + else if (name == "cbd.asc") + { DataGrids(filePath, CBD, NCells); - } else if (name == "cbh.asc") { + } + else if (name == "cbh.asc") + { DataGrids(filePath, CBH, NCells); - } else if (name == "ccf.asc") { + } + else if (name == "ccf.asc") + { DataGrids(filePath, CCF, NCells); - } else if (name == "py.asc") { + } + else if (name == "py.asc") + { DataGrids(filePath, PY, NCells); - } else if (name == "fmc.asc") { + } + else if (name == "fmc.asc") + { DataGrids(filePath, FMC, NCells); - } else { - // Handle the case where the file name doesn't match any condition - // std::cout << "Unhandled file: " << name << std::endl; } - } - else { + else + { + // Handle the case where the file name doesn't match any + // condition std::cout << "Unhandled file: " << name << + // std::endl; + } + } + else + { std::cout << "No " << name << " file, filling with NaN" << std::endl; } } // Call GenerateDat function - std::vector>> result = GenerateDat(GFuelType, GFuelTypeN, Elevation, PS, SAZ, Curing, CBD, CBH, CCF, PY, FMC, InFolder); - writeDataToFile(result,InFolder); + std::vector>> result + = GenerateDat(GFuelType, GFuelTypeN, Elevation, PS, SAZ, Curing, CBD, CBH, CCF, PY, FMC, InFolder); + writeDataToFile(result, InFolder); std::cout << "File Generated"; } diff --git a/Cell2Fire/DataGenerator.h b/Cell2Fire/DataGenerator.h index 1ebd5ae5..a64c4321 100644 --- a/Cell2Fire/DataGenerator.h +++ b/Cell2Fire/DataGenerator.h @@ -1,39 +1,48 @@ #ifndef DATAGENERATOR_H #define DATAGENERATOR_H -#include +#include "tiffio.h" +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include -#include -#include #include -#include -#include -#include -#include "tiffio.h" -#include -#include -#include +#include -std::tuple, std::unordered_map>> Dictionary(const std::string& filename); +std::tuple, + std::unordered_map>> +Dictionary(const std::string& filename); -std::tuple, std::vector, int, int, float> ForestGrid(const std::string& filename, const std::unordered_map& Dictionary); +std::tuple, std::vector, int, int, float> +ForestGrid(const std::string& filename, const std::unordered_map& Dictionary); bool fileExists(const std::string& filename); void DataGrids(const std::string& filename, std::vector& data, int nCells); -std::vector>> GenerateDat(const std::vector& GFuelType, const std::vector& GFuelTypeN, - const std::vector& Elevation, const std::vector& PS, - const std::vector& SAZ, const std::vector& Curing, - const std::vector& CBD, const std::vector& CBH, - const std::vector& CCF, const std::vector& PY, - const std::vector& FMC, const std::string& InFolder); - -void writeDataToFile(const std::vector>>& dataGrids, const std::string& InFolder); +std::vector>> GenerateDat(const std::vector& GFuelType, + const std::vector& GFuelTypeN, + const std::vector& Elevation, + const std::vector& PS, + const std::vector& SAZ, + const std::vector& Curing, + const std::vector& CBD, + const std::vector& CBH, + const std::vector& CCF, + const std::vector& PY, + const std::vector& FMC, + const std::string& InFolder); + +void writeDataToFile(const std::vector>>& dataGrids, + const std::string& InFolder); void GenDataFile(const std::string& InFolder, const std::string& Simulator); -#endif //DataGenerator.h - +#endif // DataGenerator.h diff --git a/Cell2Fire/Ellipse.cpp b/Cell2Fire/Ellipse.cpp index dd5dd64f..685730aa 100644 --- a/Cell2Fire/Ellipse.cpp +++ b/Cell2Fire/Ellipse.cpp @@ -2,164 +2,174 @@ #include "Ellipse.h" // Include libraries +#include +#include +#include +#include +#include #include #include +#include #include -#include -#include -#include -#include #include #include -#include -#include -#include -#include +#include #define no_argument 0 -#define required_argument 1 +#define required_argument 1 #define optional_argument 2 using namespace Eigen; using namespace std; - /* - Constructor + Constructor */ Ellipse::Ellipse(std::vector _x, std::vector _y) { - // Aux integers - int i,j; - int N = _x.size(); - - // Initialize Arrays and Matrices - ArrayXXd X(1,N); - ArrayXXd Y(1,N); - ArrayXXd D1(N,3); - ArrayXXd D2(N,3); - ArrayXXd S1(3,3); - ArrayXXd S2(3,3); - ArrayXXd S3(3,3); - ArrayXXd C1 = ArrayXXd::Zero(3,3); - ArrayXXd M(3,3); - VectorXd Eval(3,1); - MatrixXd Evec(3,3); - ArrayXXd cond(3,1); - ArrayXXd Coef(1,N); - - // Print input vectors (debug) - for (i = 0; i < N; i++){ - X(i) = _x[i]; - Y(i) = _y[i]; - } - //std::cout << "X:" << X << //std::endl; - //std::cout << "Y:" << Y << //std::endl; - - //Quadratic part of design matrix [eqn. 15] from (*) + // Aux integers + int i, j; + int N = _x.size(); + + // Initialize Arrays and Matrices + ArrayXXd X(1, N); + ArrayXXd Y(1, N); + ArrayXXd D1(N, 3); + ArrayXXd D2(N, 3); + ArrayXXd S1(3, 3); + ArrayXXd S2(3, 3); + ArrayXXd S3(3, 3); + ArrayXXd C1 = ArrayXXd::Zero(3, 3); + ArrayXXd M(3, 3); + VectorXd Eval(3, 1); + MatrixXd Evec(3, 3); + ArrayXXd cond(3, 1); + ArrayXXd Coef(1, N); + + // Print input vectors (debug) + for (i = 0; i < N; i++) + { + X(i) = _x[i]; + Y(i) = _y[i]; + } + // std::cout << "X:" << X << //std::endl; + // std::cout << "Y:" << Y << //std::endl; + + // Quadratic part of design matrix [eqn. 15] from (*) D1.col(0) = X.pow(2).transpose(); - D1.col(1) = (X * Y).transpose(); - D1.col(2) = Y.pow(2).transpose(); - //std::cout << "D1:" << D1 << //std::endl; - - // Linear part of design matrix [eqn. 16] from (*) - D2.col(0) = X.transpose(); - D2.col(1) = Y.transpose(); - D2.col(2) = ArrayXXd::Constant(N,1,1); - //std::cout << "D2:" << D2 << //std::endl; - + D1.col(1) = (X * Y).transpose(); + D1.col(2) = Y.pow(2).transpose(); + // std::cout << "D1:" << D1 << //std::endl; + + // Linear part of design matrix [eqn. 16] from (*) + D2.col(0) = X.transpose(); + D2.col(1) = Y.transpose(); + D2.col(2) = ArrayXXd::Constant(N, 1, 1); + // std::cout << "D2:" << D2 << //std::endl; + // Forming scatter matrix [eqn. 17] from (*) - S1 = D1.matrix().transpose() * D1.matrix(); - S2 = D1.matrix().transpose() * D2.matrix(); - S3 = D2.matrix().transpose() * D2.matrix(); - - //std::cout << "S1:" << S1 << //std::endl; - //std::cout << "S2:" << S2 << //std::endl; - //std::cout << "S3:" << S3 << //std::endl; + S1 = D1.matrix().transpose() * D1.matrix(); + S2 = D1.matrix().transpose() * D2.matrix(); + S3 = D2.matrix().transpose() * D2.matrix(); + + // std::cout << "S1:" << S1 << //std::endl; + // std::cout << "S2:" << S2 << //std::endl; + // std::cout << "S3:" << S3 << //std::endl; // Constraint matrix [eqn. 18] - C1(0,2) = 2; - C1(1,1) = -1; - C1(2,0) = 2; - //std::cout << "C1:" << C1 << //std::endl; - - //Reduced scatter matrix [eqn. 29] - M = C1.matrix().inverse()*(S1.matrix() - S2.matrix() * S3.matrix().inverse() * S2.matrix().transpose()); - EigenSolver M2(M.matrix()); - - //M*|a b c >=l|a b c >. Find eigenvalues and eigenvectors from this equation [eqn. 28] + C1(0, 2) = 2; + C1(1, 1) = -1; + C1(2, 0) = 2; + // std::cout << "C1:" << C1 << //std::endl; + + // Reduced scatter matrix [eqn. 29] + M = C1.matrix().inverse() * (S1.matrix() - S2.matrix() * S3.matrix().inverse() * S2.matrix().transpose()); + EigenSolver M2(M.matrix()); + + // M*|a b c >=l|a b c >. Find eigenvalues and eigenvectors from this equation + // [eqn. 28] Eval = M2.eigenvalues().real(); - Evec = M2.eigenvectors().real(); - - //std::cout << "Eval:" << Eval << //std::endl; - //std::cout << "Evec:" << Evec << //std::endl; - + Evec = M2.eigenvectors().real(); + + // std::cout << "Eval:" << Eval << //std::endl; + // std::cout << "Evec:" << Evec << //std::endl; + // Eigenvector must meet constraint 4ac - b^2 to be valid. - cond = 4 * Evec.row(0).array() * Evec.row(2).array() - Evec.row(1).array().pow(2); - //std::cout << "cond:" << cond << //std::endl; - //std::cout << "Check condition:" << (cond > 0) << //std::endl; - - int TotalCols = 0; - int auxCol = 0; - for (i=0; i < cond.size(); i++){ - if (cond(i) > 0){ - TotalCols++; - } - } - //std::cout << "Total Cols:" << TotalCols << //std::endl; - - ArrayXXd a1(3, TotalCols); - for (i=0; i < cond.size(); i++){ - if (cond(i) > 0){ - a1.col(auxCol) = Evec.col(i); - auxCol++; - //std::cout << "Adde column:" << i+1 << //std::endl; - } - } - - //std::cout << "a1:" << a1 << //std::endl; - - //|d f g> = -S3^(-1)*S2^(T)*|a b c> [eqn. 24] - MatrixXd a2 = -S3.matrix().inverse() *S2.matrix().transpose() * a1.matrix(); - //std::cout << "a2:" << a2 << //std::endl; - - // eigenvectors |a b c d f g> - for (i=0; i<6; i++){ - if (i<3) Coef(i) = a1(i); - else Coef(i) = a2(i-3); - } - - //std::cout << "Coef:" << Coef << //std::endl; - this->_Coef = Coef; - std::cout << "la elipse" << endl; + cond = 4 * Evec.row(0).array() * Evec.row(2).array() - Evec.row(1).array().pow(2); + // std::cout << "cond:" << cond << //std::endl; + // std::cout << "Check condition:" << (cond > 0) << //std::endl; + + int TotalCols = 0; + int auxCol = 0; + for (i = 0; i < cond.size(); i++) + { + if (cond(i) > 0) + { + TotalCols++; + } + } + // std::cout << "Total Cols:" << TotalCols << //std::endl; + + ArrayXXd a1(3, TotalCols); + for (i = 0; i < cond.size(); i++) + { + if (cond(i) > 0) + { + a1.col(auxCol) = Evec.col(i); + auxCol++; + // std::cout << "Adde column:" << i+1 << //std::endl; + } + } + + // std::cout << "a1:" << a1 << //std::endl; + + //|d f g> = -S3^(-1)*S2^(T)*|a b c> [eqn. 24] + MatrixXd a2 = -S3.matrix().inverse() * S2.matrix().transpose() * a1.matrix(); + // std::cout << "a2:" << a2 << //std::endl; + + // eigenvectors |a b c d f g> + for (i = 0; i < 6; i++) + { + if (i < 3) + Coef(i) = a1(i); + else + Coef(i) = a2(i - 3); + } + + // std::cout << "Coef:" << Coef << //std::endl; + this->_Coef = Coef; + std::cout << "la elipse" << endl; } -std::vector Ellipse::get_parameters(){ - std::vector params; - double a,b,c,d,f,g; - - a = this->_Coef(0); - b = this->_Coef(1) / 2; - c = this->_Coef(2); - d = this->_Coef(3) / 2; - f = this->_Coef(4) / 2; - g = this->_Coef(5); - +std::vector +Ellipse::get_parameters() +{ + std::vector params; + double a, b, c, d, f, g; + + a = this->_Coef(0); + b = this->_Coef(1) / 2; + c = this->_Coef(2); + d = this->_Coef(3) / 2; + f = this->_Coef(4) / 2; + g = this->_Coef(5); + // finding center of ellipse [eqn.19 and 20] from (**) - double x0 = (c*d - b*f) / (std::pow(b,2) - a*c); - double y0 = (a*f - b*d) / (std::pow(b,2) - a*c); - - //Find the semi-axes lengths [eqn. 21 and 22] from (**) - double numerator = 2*(a*f*f+c*d*d+g*b*b-2*b*d*f-a*c*g); - double denominator1 = (b*b-a*c)*( (c-a)*std::sqrt(1+4*b*b/((a-c)*(a-c)))-(c+a)); - double denominator2 = (b*b-a*c)*( (a-c)*std::sqrt(1+4*b*b/((a-c)*(a-c)))-(c+a)); - double width = std::sqrt(numerator / denominator1); - double height = std::sqrt(numerator / denominator2); - - // angle of counterclockwise rotation of major-axis of ellipse to x-axis [eqn. 23] from (**) or [eqn. 26] from (***). + double x0 = (c * d - b * f) / (std::pow(b, 2) - a * c); + double y0 = (a * f - b * d) / (std::pow(b, 2) - a * c); + + // Find the semi-axes lengths [eqn. 21 and 22] from (**) + double numerator = 2 * (a * f * f + c * d * d + g * b * b - 2 * b * d * f - a * c * g); + double denominator1 = (b * b - a * c) * ((c - a) * std::sqrt(1 + 4 * b * b / ((a - c) * (a - c))) - (c + a)); + double denominator2 = (b * b - a * c) * ((a - c) * std::sqrt(1 + 4 * b * b / ((a - c) * (a - c))) - (c + a)); + double width = std::sqrt(numerator / denominator1); + double height = std::sqrt(numerator / denominator2); + + // angle of counterclockwise rotation of major-axis of ellipse to x-axis + // [eqn. 23] from (**) or [eqn. 26] from (***). this->_a = width; - this->_b = height; - params.push_back(width); - params.push_back(height); - return params; -} \ No newline at end of file + this->_b = height; + params.push_back(width); + params.push_back(height); + return params; +} diff --git a/Cell2Fire/Ellipse.h b/Cell2Fire/Ellipse.h index 674814c1..9ad200e9 100644 --- a/Cell2Fire/Ellipse.h +++ b/Cell2Fire/Ellipse.h @@ -2,27 +2,28 @@ #define ELLIPSE // include stuff -#include +#include #include +#include +#include #include #include -#include #include -#include using namespace Eigen; using namespace std; -class Ellipse { - public: - // mutable - double _a; - double _b; - ArrayXXd _Coef; - - // constructor and methods here - Ellipse(std::vector _x, std::vector _y); - std::vector get_parameters(); +class Ellipse +{ + public: + // mutable + double _a; + double _b; + ArrayXXd _Coef; + + // constructor and methods here + Ellipse(std::vector _x, std::vector _y); + std::vector get_parameters(); }; #endif diff --git a/Cell2Fire/Forest.cpp b/Cell2Fire/Forest.cpp index 7f11b877..c55597e0 100644 --- a/Cell2Fire/Forest.cpp +++ b/Cell2Fire/Forest.cpp @@ -2,26 +2,33 @@ #include "Forest.h" // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include using namespace std; -/* - Constructor +/* + Constructor */ -Forest::Forest(int _id, std::string _location, std::vector _coord, int _nCells, double _area, double _vol, - double _age, double _perimeter, std::unordered_map & _fTypes) { - - // Populate fields - this->id = _id; +Forest::Forest(int _id, + std::string _location, + std::vector _coord, + int _nCells, + double _area, + double _vol, + double _age, + double _perimeter, + std::unordered_map& _fTypes) +{ + + // Populate fields + this->id = _id; this->location = _location; this->coord = _coord; this->nCells = _nCells; @@ -30,25 +37,26 @@ Forest::Forest(int _id, std::string _location, std::vector _coord, int _nCe this->age = _age; this->fTypes = _fTypes; this->availCells = std::vector(); - for (int i = 0; i <= this->nCells; i++) { + for (int i = 0; i <= this->nCells; i++) + { this->availCells.push_back(i); } this->burntCells = std::vector(); - } /* - Prints-out information from the forest + Prints-out information from the forest */ -void Forest::print_info() { - std::cout << "Forest Information" << std::endl; - std::cout << "ID = " << this->id << std::endl; - std::cout << "Location = " << this->location << std::endl; - //std::cout << "Coordinates = " << this->coord << std::endl; - std::cout << "NCells = " << this->nCells << std::endl; - std::cout << "Area = " << this->area << std::endl; - std::cout << "Vol = " << this->vol << std::endl; - std::cout << "Age = " << this->age << std::endl; - //std::cout << "FTypes = " << this->fTypes << std::endl; +void +Forest::print_info() +{ + std::cout << "Forest Information" << std::endl; + std::cout << "ID = " << this->id << std::endl; + std::cout << "Location = " << this->location << std::endl; + // std::cout << "Coordinates = " << this->coord << std::endl; + std::cout << "NCells = " << this->nCells << std::endl; + std::cout << "Area = " << this->area << std::endl; + std::cout << "Vol = " << this->vol << std::endl; + std::cout << "Age = " << this->age << std::endl; + // std::cout << "FTypes = " << this->fTypes << std::endl; } - diff --git a/Cell2Fire/Forest.h b/Cell2Fire/Forest.h index 0ae3124f..1ddb9674 100644 --- a/Cell2Fire/Forest.h +++ b/Cell2Fire/Forest.h @@ -2,38 +2,45 @@ #define FOREST // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include using namespace std; // Class definition -class Forest { - public: - int id; - int nCells; - double area; - double vol; - double age; - double perimeter; - std::string location; - std::vector coord; - std::unordered_map fTypes; - std::vector availCells; - std::vector burntCells; - - // Constructor & methods - Forest(int _id, std::string _location, std::vector _coord, int _nCells, double _area, - double _vol, double _age, double _perimeter, std::unordered_map & _fTypes); - - void print_info(); +class Forest +{ + public: + int id; + int nCells; + double area; + double vol; + double age; + double perimeter; + std::string location; + std::vector coord; + std::unordered_map fTypes; + std::vector availCells; + std::vector burntCells; + + // Constructor & methods + Forest(int _id, + std::string _location, + std::vector _coord, + int _nCells, + double _area, + double _vol, + double _age, + double _perimeter, + std::unordered_map& _fTypes); + + void print_info(); }; #endif diff --git a/Cell2Fire/FuelModelFBP.cpp b/Cell2Fire/FuelModelFBP.cpp index 9520dc1b..0edd81de 100644 --- a/Cell2Fire/FuelModelFBP.cpp +++ b/Cell2Fire/FuelModelFBP.cpp @@ -1,858 +1,1084 @@ -/* Subroutine of FBP.C version 4.4 Aug,2007 - Canadian Forest Fire Behaviour Prediction System -This code is copyright of the Canadian Forest Service, Natural Resources Canada (1992-2005) -It is provide free of charge to anyone who wishes to incorporate it within their -forest fire management applications, however users should note in their application that -the FBP calucaltions come from the Canadianf Forest Services Fire Behaviour Prediction -System. The Canadian Forest Service has gone through considerable testing to ensure that -these computer functions duplicate the system as laid out in ST-X-3 (The Development -and Structure of the Canadian Forest Fire Behaviour Prediction System (1992)) and the subsequent corrections and additions to the system (the draft "FBP Note"), however no -guarentte is given as to the absolute accuracy of the code. - This file contains a series of functions that go thru all the - FBP System calculations. -Originally Written at P.N.F.I. December 91, by Mike Wotton - Corrections to version 1.0 - 1.01 - b value in O1b was wrong. KA at nofc (mar5,92) ...bmw - 1.01a - no error just added upper and lowercase fueltype entry ...bmw - 1.02 - l_to_b problem with inequalitiy...minor prob fixed - 1.5 - modifications to stop small(improbable) numbers from blowing - up the slope calculation stuff - this caused a slope problem which BA @ PFC pointed out - may 93.......bmw - 3.0 jan /96 bmw - - c6 - constant sfc - 3.01 apr/97 - - add line to recognize uppercase in grass fuels - 3.02 apr/97 - - change accn funtion to recognize lower case fuels for open - 3.1 jul/97 - - change slope function to stop overflow when cur<=50 in O1 - 3.2 sept/97 - - change the c6 calc of flank ros to avoid variation in l/b with - RSC calculation in flank. - 3.3 jan/98 - - error was SFC >0 if CUR<50 (and hence ROS=0) - changed this within the surf_fuel_consump() fn - 3.4 apr/98 (ya i know the dates aren't in sequence) - - change O1a A value from 1.41 to 1.4 from KA apr/98 - - 4.0 jan/98 - - changes listed within the FBP note and TEST dataset - 4.1 - August 2004 - - final changes in the FBP note (new M-3/M-4 model) and a new grass CF model - -removed some verstigaes of older functions for input /output - 4.2 - Oct 2004 - - changes as a result of discussion with Prometheus team - - SFC in grass ...4.1 did not include changes to grass consumption though - spread at values of CUR<50% are now possible (see point 3.3 above) - - at very short time periods using acceleration a CFB(t) should be caluclated - and used for final ROS in the C-6 model. - 4.3 - August 2005 - - changes as a result of further discussions with Prometheus team. These were: - - changes to include the alternate ISI calculation formula (53a footnote 2) in - the calculation of WSE (...added as a section to The FBP Note) - - addition of D-2 for the promtheus team to evaluate their model - ( D-2 is leafed out pure aspen - ROS(D-2)= 0.2 * ROS(D-1) if BUI>80 otherwise ROS(D-2)=0) - - NOTE that this (D-2) is not an official part of the FBP System however. - 4.4 August 2007 - - crown consump in m3/m4. It was calcuating based full conifer content. - but should be modifed by PDF - - change to match changes in FBP Note section 3.3 (eqn 66c) - 4.5 Nov 2007 - - perimeter calc wasn't based on LB(t). - - Flankfire final ROS (FROS) could be set to FRSS if flank fire did not - involve crowning - - change to function headers in perimeter() and flank_spread_distance() - to accomodate LB(t) assignment - - LB(t) is now added to the secondary inputs structure and kept - it is asdsigned in flank_spread_distance(). - 4.6 jan 2009 - - uping the slope limit to 70%...and so the default after that is 10.0 - 5.0 Oct 2014 - - PGR is corrected to be a function of ROS(t) not equilibrium ROS - 5.0001 June 2015 - - forgot to change the encoded version number to 5.0. now 5.0001 - - updated header to FBP5.h -*/ -#include "Cells.h" -#include "FuelModelFBP.h" -#include -#include -#include - - char version[50]="Last modified June 2015, by BMW ", - ver[17] = "Version 5.0001 "; - - float slopelimit_isi=0.01; - int numfuels=18; - - void calculate_fbp(inputs *data,fuel_coefs *pt,main_outs *at, - snd_outs *sec,fire_struc *hptr,fire_struc *fptr,fire_struc *bptr) - { - int firetype=0; - float accn; - fuel_coefs **ptr=&pt; - setup_const(*ptr); - zero_main(at); - zero_sec(sec); - zero_fire(hptr); - zero_fire(fptr); - zero_fire(bptr); - at->covertype=get_fueltype_number(ptr,data->fueltype); - at->ff=ffmc_effect(data->ffmc); - at->rss=rate_of_spread(data,(*ptr),at); - hptr->rss=at->rss; - at->sfc=surf_fuel_consump(data); - at->sfi=fire_intensity(at->sfc,at->rss); - - if(at->covertype=='c') - { - at->fmc=foliar_moisture(data,at); - at->csi=crit_surf_intensity((*ptr),at->fmc); - at->rso=critical_ros(data->fueltype,at->sfc,at->csi); - firetype=fire_type(at->csi,at->sfi); - at->crown=firetype; - if(firetype==1) - { - hptr->cfb=crown_frac_burn(at->rss,at->rso); - hptr->fd=fire_description(hptr->cfb); - hptr->ros=final_ros(data,at->fmc,at->isi,hptr->cfb,at->rss); - hptr->cfc=crown_consump(data,(*ptr),hptr->cfb); - hptr->fc=hptr->cfc+at->sfc; - hptr->fi=fire_intensity(hptr->fc,hptr->ros); - } - } - if(at->covertype=='n' || firetype==0) - { - hptr->fd='S'; - hptr->ros=at->rss; - hptr->fc=at->sfc; - hptr->fi=at->sfi; - hptr->cfb=0.0; - } - sec->lb=l_to_b(data->fueltype,at->wsv); - bptr->isi=backfire_isi(at); - bptr->rss=backfire_ros(data,(*ptr),at,bptr->isi); - fptr->rss=flankfire_ros(hptr->rss,bptr->rss,sec->lb); - bptr->fi=fire_behaviour(data,(*ptr),at,bptr); - fptr->ros=flankfire_ros(hptr->ros,bptr->ros,sec->lb ); - fptr->fi=flank_fire_behaviour(data,(*ptr),at,fptr); - at->a=hptr->ros; - at->b=fptr->ros; - - if(data->pattern==1 && data->time>0) - { - accn=acceleration(data,hptr->cfb); - hptr->dist=spread_distance(data,hptr,accn); - bptr->dist=spread_distance(data,bptr,accn); - fptr->dist=flank_spread_distance(data,fptr,sec,hptr->rost,bptr->rost, - hptr->dist,bptr->dist,sec->lb,accn); - at->fl=hptr->dist; - hptr->time=time_to_crown(hptr->ros,at->rso,accn); - fptr->time=time_to_crown(fptr->ros,at->rso,accn); - bptr->time=time_to_crown(bptr->ros,at->rso,accn); - } - else - { - set_all(hptr,data->time); - set_all(fptr,data->time); - set_all(bptr,data->time); - } - sec->area=area((hptr->dist+bptr->dist),fptr->dist); - if(data->pattern==1 && data->time>0) sec->perm=perimeter(hptr,bptr,sec,sec->lbt); - else sec->perm=perimeter(hptr,bptr,sec,sec->lb); - at->c=bptr->ros; - - } - - -void determine_destiny_metrics_fbp(inputs* data, fuel_coefs* pt, main_outs* metrics,fire_struc* metrics2) { - int firetype=0; - fuel_coefs **ptr=&pt; - setup_const(*ptr); - zero_main(metrics); - metrics->covertype=get_fueltype_number(ptr,data->fueltype); - if (metrics->covertype=='f'){ - metrics->rss=0; - metrics->sfi=0; - metrics->crown=0; - } - else{ - metrics->ff=ffmc_effect(data->ffmc); - metrics->rss=rate_of_spread(data,(*ptr),metrics); - metrics->sfc=surf_fuel_consump(data); - metrics->sfi=fire_intensity(metrics->sfc,metrics->rss); - - if(metrics->covertype=='c') - { - metrics->fmc=foliar_moisture(data,metrics); - metrics->csi=crit_surf_intensity((*ptr),metrics->fmc); - metrics->rso=critical_ros(data->fueltype,metrics->sfc,metrics->csi); - firetype=fire_type(metrics->csi,metrics->sfi); - metrics->crown=firetype; - if(firetype==1){ - metrics2->cfb=crown_frac_burn(metrics->rss,metrics->rso); - } - } - } -} - -void setup_const(fuel_coefs *ptr) - { - //printf("dlw debug, enter fuel_coefs\n"); -/* fuel type 0 */ - strncpy(ptr->fueltype,"M1 ",3); - ptr->p1=110.0; ptr->p2=0.0282; ptr->p3=1.5; - ptr->q=0.80; ptr->bui0=50; ptr->cbh=6; ptr->cfl=0.80; -/* fuel type 1 */ - ptr++; - strncpy(ptr->fueltype,"M2 ",3); - ptr->p1=110.0; ptr->p2=0.0282; ptr->p3=1.5; - ptr->q=0.80; ptr->bui0=50; ptr->cbh=6; ptr->cfl=0.80; -/* fuel type 2 */ - ptr++; - strncpy(ptr->fueltype,"M3 ",3); - ptr->p1=120.0; ptr->p2=0.0572; ptr->p3=1.4; - ptr->q=0.80; ptr->bui0=50; ptr->cbh=6; ptr->cfl=0.80; -/* fuel type 3 */ - ptr++; - strncpy(ptr->fueltype,"M4 ",3); - ptr->p1=100.0; ptr->p2=0.0404; ptr->p3=1.48; - ptr->q=0.80; ptr->bui0=50; ptr->cbh=6; ptr->cfl=0.80; -/* fuel type 4 */ - ptr++; - strncpy(ptr->fueltype,"C1 ",3); - ptr->p1=90.0; ptr->p2=0.0649; ptr->p3=4.5; - ptr->q=0.90; ptr->bui0=72; ptr->cbh=2; ptr->cfl=0.75; - /* fuel type 5 */ - ptr++; - strncpy(ptr->fueltype,"C2 ",3); - ptr->p1=110.0; ptr->p2=0.0282; ptr->p3=1.5; - ptr->q=0.70; ptr->bui0=64; ptr->cbh=3; ptr->cfl=0.80; -/* fuel type 6 */ - ptr++; - strncpy(ptr->fueltype,"C3 ",3); - ptr->p1=110.0; ptr->p2=0.0444; ptr->p3=3.0; - ptr->q=0.75; ptr->bui0=62; ptr->cbh=8; ptr->cfl=1.15; -/* fuel type 7 */ - ptr++; - strncpy(ptr->fueltype,"C4 ",3); - ptr->p1=110.0; ptr->p2=0.0293; ptr->p3=1.5; - ptr->q=0.80; ptr->bui0=66; ptr->cbh=4; ptr->cfl=1.20; - /* fuel type 8 */ - ptr++; - strncpy(ptr->fueltype,"C5 ",3); - ptr->p1=30.0; ptr->p2=0.0697; ptr->p3=4.0; - ptr->q=0.80; ptr->bui0=56; ptr->cbh=18; ptr->cfl=1.20; - /* fuel type 9 */ - ptr++; - strncpy(ptr->fueltype,"C6 ",3); - ptr->p1=30.0; ptr->p2=0.0800; ptr->p3=3.0; - ptr->q=0.80; ptr->bui0=62; ptr->cbh=7; ptr->cfl=1.80; - /* fuel type 10 */ - ptr++; - strncpy(ptr->fueltype,"C7 ",3); - ptr->p1=45.0; ptr->p2=0.0305; ptr->p3=2.0; - ptr->q=0.85; ptr->bui0=106; ptr->cbh=10; ptr->cfl=0.50; - /* fuel type 11 */ - ptr++; - strncpy(ptr->fueltype,"D1 ",3); - ptr->p1=30.0; ptr->p2=0.0232; ptr->p3=1.6; - ptr->q=0.90; ptr->bui0=32; ptr->cbh=0; ptr->cfl=0.0; - /* fuel type 12 */ - ptr++; - strncpy(ptr->fueltype,"S1 ",3); - ptr->p1=75.0; ptr->p2=0.0297; ptr->p3=1.3; - ptr->q=0.75; ptr->bui0=38; ptr->cbh=0; ptr->cfl=0.0; - /* fuel type 13 */ - ptr++; - strncpy(ptr->fueltype,"S2 ",3); - ptr->p1=40.0; ptr->p2=0.0438; ptr->p3=1.7; - ptr->q=0.75; ptr->bui0=63; ptr->cbh=0; ptr->cfl=0.0; - /* fuel type 14 */ - ptr++; - strncpy(ptr->fueltype,"S3 ",3); - ptr->p1=55.0; ptr->p2=0.0829; ptr->p3=3.2; - ptr->q=0.75; ptr->bui0=31; ptr->cbh=0; ptr->cfl=0.0; - /* fuel type 15 */ - ptr++; - strncpy(ptr->fueltype,"O1a",3); - ptr->p1=190.0; ptr->p2=0.0310; ptr->p3=1.40; - ptr->q=1.000; ptr->bui0=01; ptr->cbh=0; ptr->cfl=0.0; - /* fuel type 16 */ - ptr++; - strncpy(ptr->fueltype,"O1b",3); - ptr->p1=250.0; ptr->p2=0.0350; ptr->p3=1.7; - ptr->q=1.000; ptr->bui0=1; ptr->cbh=0; ptr->cfl=0.0; -/* fuel type 17 */ - ptr++; - strncpy(ptr->fueltype,"D2 ",3); - ptr->p1=6.0; ptr->p2=0.0232; ptr->p3=1.6; - ptr->q=0.90; ptr->bui0=32; ptr->cbh=0; ptr->cfl=0.0; - - } - - char get_fueltype_number(fuel_coefs **ptr,char fuel[4]) - { - int i; - char cover; - if(fuel[0]>='a' && fuel[0]<='z') fuel[0]+='A'-'a'; - if(fuel[2]>='A' && fuel[2]<='Z') fuel[2]+='a'-'A'; - for(i=0; ifueltype,fuel,3)!=0); i++)(*ptr)++; - if(i>=numfuels) - { - printf(" %s not a recognizable fuel type\n ",fuel); - //exit(9); - cover='f'; - return (cover); - } - if(fuel[0]=='C' || fuel[0]=='M')cover='c'; - else cover='n'; - - return (cover); - } - - float ffmc_effect(float ffmc) - { - float mc,ff; - mc=147.2*(101.0-ffmc)/(59.5+ffmc); - ff=91.9*exp(-0.1386*mc)*(1+pow(mc,5.31)/49300000.0); - return (ff); - } - - float rate_of_spread(inputs *inp, fuel_coefs *ptr, main_outs *at) - { - float fw,isz,mult,*mu=&mult,rsi ; - at->ff=ffmc_effect(inp->ffmc); - at->raz=inp->waz; - isz=0.208*at->ff; - if(inp->ps>0)at->wsv=slope_effect(inp,ptr,at,isz); - else at->wsv=inp->ws; - - if(at->wsv<40.0)fw=exp(0.05039*at->wsv); - else fw=12.0*(1.0-exp(-0.0818*(at->wsv-28))); - at->isi=isz*fw; - rsi=ros_calc(inp,ptr,at->isi,mu); - at->rss=rsi*bui_effect(ptr,at,inp->bui); - return(at->rss); - } - - float ros_calc(inputs *inp, fuel_coefs *ptr,float isi,float *mult) - { - float ros; - if(strncmp(inp->fueltype,"O1",2)==0) - return ( grass(ptr, inp->cur ,isi,mult) ); - if(strncmp(inp->fueltype,"M1",2)==0 || strncmp(inp->fueltype,"M2",2)==0) - return ( mixed_wood(ptr,isi,mult,inp->pc) ); - if(strncmp(inp->fueltype,"M3",2)==0 || strncmp(inp->fueltype,"M4",2)==0) - return ( dead_fir(ptr,inp->pdf,isi,mult) ); - if(strncmp(inp->fueltype,"D2",2)==0) - return ( D2_ROS(ptr,isi,inp->bui,mult) ); - /* if all else has fail its a conifer */ - return ( conifer(ptr,isi,mult)); - } - - - float grass(fuel_coefs *ptr,float cur,float isi,float *mult) - { - float mu,ros; - if((float)(cur)>=58.8) mu=0.176 + 0.02*( (float)(cur) - 58.8 ) ; - else mu=0.005*(exp(0.061*(float)(cur) ) - 1.0) ; - ros=mu * (ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi)) , ptr->p3)); - if(mu<0.001)mu=0.001; /* to have some value here*/ - *mult=mu; - return(ros); - } - - float mixed_wood(fuel_coefs *ptr, float isi,float *mu, int pc) - { - float ros, mult,ros_d1,ros_c2; - int i; - *mu=pc/100.0; - ros_c2=ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi)), ptr->p3); - if(strncmp(ptr->fueltype,"M2",2)==0) mult=0.2; - else mult=1.0; - for(i=0;strncmp(ptr->fueltype,"D1",2)!=0 && i=numfuels) { printf(" prob in mixedwood d1 not found \n");exit(9);} - ros_d1=ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi) ),ptr->p3); - - ros=(pc/100.0)*ros_c2 + mult* (100-pc)/100.0*ros_d1; - return(ros); - } - - float dead_fir(fuel_coefs *ptr, int pdf, float isi, float *mu) - { - double a,b,c; - int i; - float ros,rosm3or4_max,ros_d1, greenness=1.0; - if(strncmp(ptr->fueltype,"M4",2)==0)greenness=0.2; - - rosm3or4_max=ptr->p1*pow( ( 1.0-exp(-1.0*ptr->p2*isi)),ptr->p3); - - for(i=0;strncmp(ptr->fueltype,"D1",2)!=0 && i=numfuels) { printf(" prob in mixedwood d1 not found \n");exit(9);} - ros_d1=ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi) ),ptr->p3); - - ros=(float)(pdf)/100.0*rosm3or4_max + (100.0-(float)(pdf))/100.0*greenness*ros_d1; - - *mu=(float)(pdf)/100.0; - - return(ros); - } - - float D2_ROS(fuel_coefs *ptr, float isi, float bui, float *mu) - { - *mu=1.0; - if(bui>=80) return( ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi) ),ptr->p3) ); - else return (0.0); - } - - float conifer(fuel_coefs *ptr, float isi, float *mu) - { - *mu=1.0; - return( ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isi ) ),ptr->p3) ); - } - - float bui_effect(fuel_coefs *ptr,main_outs *at, float bui) - { - float bui_avg=50.0; - - if(bui==0) bui=1.0; - at->be=exp(bui_avg*log(ptr->q)*( (1.0/bui)-(1.0/ptr->bui0) ) ); - return (at->be); - } - - float slope_effect(inputs *inp,fuel_coefs *ptr,main_outs *at, float isi ) - /* ISI is ISZ really */ - { - double isf,rsf,wse,ps,rsz,wsx,wsy,wsex,wsey,wsvx,wsvy, - wrad,srad,wsv,raz,check,wse2,wse1; - float mu=0.0; - ps=inp->ps*1.0; - - if(ps>70.0)ps=70.0; /* edited in version 4.6*/ - at->sf=exp(3.533*pow(ps/100.0,1.2)); - if(at->sf>10.0)at->sf=10.00; /* added to ensure maximum is correct in version 4.6 */ - - if(strncmp(ptr->fueltype,"M1",2)==0 || strncmp(ptr->fueltype,"M2",2)==0) - isf=ISF_mixedwood(ptr,isi,inp->pc,at->sf); - else if(strncmp(ptr->fueltype,"M3",2)==0 || strncmp(ptr->fueltype,"M4",2)==0) - isf=ISF_deadfir(ptr,isi,inp->pdf,at->sf); - else{ - rsz=ros_calc(inp,ptr,isi,&mu); - rsf=rsz*at->sf; - - if(rsf>0.0)check=1.0-pow((rsf/(mu*ptr->p1)),(1.0/ptr->p3) ); - else check=1.0; - if(checkp2))*log(check); - } - if(isf==0.0)isf=isi; /* should this be 0.0001 really */ - wse1 = log(isf/(0.208*at->ff))/0.05039; - if(wse1<=40.0) wse=wse1; - else{ - if(isf>(0.999*2.496*at->ff) ) isf=0.999*2.496*at->ff; - wse2=28.0-log(1.0-isf/(2.496*at->ff))/0.0818; - wse=wse2; - } - wrad=inp->waz/180.0*3.1415926; - wsx=inp->ws*sin(wrad); - wsy=inp->ws*cos(wrad); - srad=inp->saz/180.0*3.1415926; - wsex=wse*sin(srad); - wsey=wse*cos(srad); - wsvx=wsx+wsex; - wsvy=wsy+wsey; - wsv=sqrt(wsvx*wsvx+wsvy*wsvy); - raz=acos(wsvy/wsv); - raz=raz/3.1415926*180.0; - if(wsvx<0)raz=360-raz; - at->raz=raz; - return( (float)(wsv) ); - } - - float ISF_mixedwood(fuel_coefs *ptr, float isz, int pc, float sf) - { - float check, mult,rsf_d1,rsf_c2,isf_d1,isf_c2; - int i; - - rsf_c2=sf*ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isz)), ptr->p3); - if(rsf_c2>0.0)check=1.0-pow((rsf_c2/(ptr->p1)),(1.0/ptr->p3) ); - else check=1.0; - if(checkp2))*log(check); - - if(strncmp(ptr->fueltype,"M2",2)==0) mult=0.2; - else mult=1.0; - for(i=0;strncmp(ptr->fueltype,"D1",2)!=0 && ip1)*pow( (1.0-exp(-1.0*ptr->p2*isz) ),ptr->p3); - - if(rsf_d1>0.0)check=1.0-pow((rsf_d1/(mult*ptr->p1)),(1.0/ptr->p3) ); - else check=1.0; - if(checkp2))*log(check); - - return ( ((float)(pc)/100.0)*isf_c2 + (100-(float)(pc))/100.0*isf_d1 ); - } - - float ISF_deadfir(fuel_coefs *ptr, float isz, int pdf, float sf) - { - float check, mult,rsf_d1,rsf_max,isf_d1,isf_max; - int i; - - rsf_max=sf*ptr->p1*pow( (1.0-exp(-1.0*ptr->p2*isz)), ptr->p3); - if(rsf_max>0.0)check=1.0-pow((rsf_max/(ptr->p1)),(1.0/ptr->p3) ); - else check=1.0; - if(checkp2))*log(check); - - if(strncmp(ptr->fueltype,"M4",2)==0) mult=0.2; - else mult=1.0; - - for(i=0;strncmp(ptr->fueltype,"D1",2)!=0 && ip1)*pow( (1.0-exp(-1.0*ptr->p2*isz) ),ptr->p3); - - if(rsf_d1>0.0)check=1.0-pow((rsf_d1/(mult*ptr->p1)),(1.0/ptr->p3) ); - else check=1.0; - if(checkp2))*log(check); - - return ( ((float)(pdf)/100.0)*isf_max + ( 100.0-(float)(pdf) )/100.0*isf_d1 ); - } - - - float fire_intensity (float fc,float ros) - { - return (300.0*fc*ros); - } - - float foliar_moisture(inputs *inp, main_outs *at) - { - float latn; - int nd; - at->jd=inp->jd; - at->jd_min=inp->jd_min; - if(inp->jd_min<=0) - { - if(inp->elev<0) - { - latn=23.4*exp(-0.0360*(150-inp->lon))+46.0; - at->jd_min=(int)(0.5+151.0*inp->lat/latn); - } - else - { - latn=33.7*exp(-0.0351*(150-inp->lon))+43.0; - at->jd_min=(int)(0.5+142.1*inp->lat/latn+(0.0172*inp->elev)); - } - } - nd=abs(inp->jd - at->jd_min); - if(nd>=50) return(120.0); - if(nd>=30 && nd<50) return (32.9+3.17*nd-0.0288*nd*nd); - return(85.0+0.0189*nd*nd); - } - - float surf_fuel_consump(inputs *inp) - { - float sfc,ffc,wfc,bui,ffmc,sfc_c2,sfc_d1; - char ft[3]; - strncpy(ft,inp->fueltype,2); - bui=inp->bui; - ffmc=inp->ffmc; - if(strncmp(ft,"C1",2)==0) - { -/* sfc=1.5*(1.0-exp(-0.23*(ffmc-81.0)));*/ - if(ffmc>84) sfc=0.75+0.75*sqrt(1-exp(-0.23*(ffmc-84) )); - else sfc=0.75-0.75*sqrt(1-exp(0.23*(ffmc-84) ) ); - return ( sfc>=0 ? sfc: 0.0 ); - } - if(strncmp(ft,"C2",2)==0 || strncmp(ft,"M3",2)==0 || - strncmp(ft,"M4",2)==0)return ( 5.0*(1.0-exp(-0.0115*bui)) ); - if(strncmp(ft,"C3",2)==0 || strncmp(ft,"C4",2)==0) - return( 5.0 * pow( (1.0-exp(-0.0164*bui)) , 2.24)); - if(strncmp(ft,"C5",2)==0 || strncmp(ft,"C6",2)==0 ) - return( 5.0* pow( (1.0-exp(-0.0149*bui)) , 2.48) ); - if(strncmp(ft,"C7",2)==0) - { - ffc=2.0*(1.0-exp(-0.104*(ffmc-70.0))); - if(ffc<0) ffc=0.0; - wfc=1.5*(1.0-exp(-0.0201*bui)); - return( ffc + wfc ); - } - if(strncmp(ft,"O1",2)==0) return( (inp->gfl) /* change this*/ ); - if(strncmp(ft,"M1",2)==0 || strncmp(ft,"M2",2)==0) - { - sfc_c2=5.0*(1.0-exp(-0.0115*bui)); - sfc_d1=1.5*(1.0-exp(-0.0183*bui)); - sfc=inp->pc/100.0*sfc_c2 + (100.0-inp->pc)/100.0*sfc_d1; - return(sfc); - } - if(strncmp(ft,"S1",2)==0) - { - ffc=4.0 * (1.0-exp(-0.025*bui)); - wfc=4.0*(1.0-exp(-0.034*bui)); - return ( ffc+wfc); - } - if(strncmp(ft,"S2",2)==0) - { - ffc=10.0*(1.0-exp(-0.013*bui)); - wfc=6.0*(1.0-exp(-0.060*bui)); - return (ffc+wfc); - } - if(strncmp(ft,"S3",2)==0) - { - ffc=12.0*(1.0-exp(-0.0166*bui)); - wfc=20.0*(1.0-exp(-0.0210*bui)); - return ( ffc+wfc); - } - if(strncmp(ft,"D1",2)==0) return ( 1.5*(1.0-exp(-0.0183*bui))); - if(strncmp(ft,"D2",2)==0) return ( bui>=80 ? 1.5*(1.0-exp(-0.0183*bui)) : 0.0); - - printf("prob in sfc func \n");exit(9); - return(-99); - } - - - float crit_surf_intensity(fuel_coefs *ptr, float fmc) - { - if (ptr->cbh>0){ - return ( 0.001*pow(ptr->cbh*(460.0+25.9*fmc),1.5) );} - else{ - return (999999999); // if cbh is equal to 0, critical intensity is set to big number - } - } - - float critical_ros(char ft[3],float sfc,float csi) - { - if(sfc>0)return ( csi/(300.0*sfc) ); - else return(0.0); - } - - float crown_frac_burn(float rss,float rso) - { - float cfb; - cfb=1.0-exp(-0.230*(rss-rso)); - return ( cfb>0 ? cfb :0.0 ); - } - - int fire_type( float csi,float sfi) - { - return ( sfi>csi ? 1 : 0 ); - } - - char fire_description(float cfb) - { - if(cfb<0.1)return('S'); - if(cfb<0.9 && cfb>=0.1)return('I'); - if(cfb>=0.9)return( 'C' ); - return('*'); - } - - float final_ros(inputs *inp, float fmc,float isi,float cfb,float rss) - { - float rsc,ros; - if(strncmp(inp->fueltype,"C6",2)==0) - { - rsc=foliar_mois_effect(isi,fmc); - ros = rss+cfb*(rsc-rss); - } - else ros=rss; - return(ros); - } - - float foliar_mois_effect(float isi,float fmc) - { - float fme,rsc, fme_avg = 0.778; - fme=1000.0*pow(1.5-0.00275*fmc,4.0)/(460.0 + 25.9*fmc); - rsc=60.0*(1.0-exp(-0.0497*isi))*fme/fme_avg; - return(rsc); - } - - float crown_consump(inputs *inp, fuel_coefs *ptr,float cfb) - { - float cfc; - cfc=ptr->cfl*cfb; - if(strncmp(inp->fueltype,"M1",2)==0 || strncmp(inp->fueltype,"M2",2)==0) - cfc = inp->pc/100.0*cfc; - if(strncmp(inp->fueltype,"M3",2)==0 || strncmp(inp->fueltype,"M4",2)==0) - cfc = inp->pdf/100.0*cfc; - return(cfc); - } - - - float l_to_b(char ft[3],float ws) - { - if(strncmp(ft,"O1",2)==0)return( ws<1.0 ? 1.0 : (1.1*pow(ws,0.464))); - else return (1.0 +8.729*pow(1.0-exp(-0.030*ws),2.155)); - } - - void set_all (fire_struc *ptr, int time) - { - ptr->time=0; - ptr->rost=ptr->ros; - ptr->dist=time*ptr->ros; - } - float backfire_isi(main_outs *at) - { - float bfw; - bfw = exp(-0.05039*at->wsv); - return ( 0.208*at->ff*bfw); - } - - float backfire_ros(inputs *inp,fuel_coefs *ptr,main_outs *at,float bisi) - { - float mult=0.0,bros; - bros=ros_calc(inp,ptr,bisi,&mult); - bros *= bui_effect(ptr,at,inp->bui); - return(bros); - } - - float area(float dt,float df) - { - float a,b; - a=dt/2.0; - b=df; - return ( a*b*3.1415926/10000.0); - } - - float perimeter (fire_struc *h,fire_struc *b, snd_outs *sec, float lb) - { - float mult,p; - mult=3.1415926*(1.0+1.0/lb)*(1.0+pow(((lb-1.0)/(2.0*(lb+1.0))),2.0)); - p=(h->dist + b->dist)/2.0*mult; - sec->pgr = (h->rost + b->rost)/2.0*mult; - - return(p); - } - - float acceleration(inputs *inp,float cfb) - { - int i; - char canopy='c', - open_list[10][3]={"O1","C1","S1","S2","S3","o1","c1","s1","s2","s3"}; - for(i=0;strncmp(inp->fueltype,open_list[i],2)!=0 && i<10;i++); - if(i<10) canopy='o'; - if(canopy=='o') return(0.115); - else return(0.115 -18.8*pow(cfb,2.5)*exp(-8.0*cfb) ); - } - - float flankfire_ros(float ros,float bros,float lb) - { - return ( (ros+bros)/(lb*2.0) ); - } - - float flank_spread_distance(inputs *inp,fire_struc *ptr,snd_outs *sec, - float hrost,float brost,float hd, float bd,float lb,float a) - { - sec->lbt=(lb-1.0)*(1.0-exp(-a*inp->time)) +1.0; - ptr->rost=(hrost+brost)/(sec->lbt*2.0); - return ( (hd+bd)/(2.0*sec->lbt) ); - } - - float spread_distance(inputs *inp,fire_struc *ptr,float a) - { - ptr->rost= ptr->ros*(1.0-exp(-a*inp->time)); - return ( ptr->ros*(inp->time+(exp(-a*inp->time)/a)-1.0/a)); - } - - int time_to_crown(float ros,float rso,float a) - { - float ratio; - if(ros>0)ratio= rso/ros; - else ratio=1.1; - if(ratio>0.9 && ratio<=1.0 )ratio=0.9; - if(ratio<1.0)return (int)(log(1.0-ratio)/-a); - else return(99); - } - - float fire_behaviour(inputs *inp,fuel_coefs *ptr,main_outs *at, - fire_struc *f) - { - float sfi,fi; - int firetype=0; - sfi=fire_intensity(at->sfc,f->rss); - firetype=fire_type(at->csi,sfi); - if(firetype==1) - { - f->cfb = crown_frac_burn(f->rss,at->rso); - f->fd = fire_description(f->cfb); - f->ros = final_ros(inp,at->fmc,f->isi,f->cfb,f->rss); - f->cfc = crown_consump(inp,ptr,f->cfb); - f->fc = f->cfc + at->sfc; - fi = fire_intensity(f->fc,f->ros); - } - if(firetype!=1 || at->covertype=='n') - { - f->fc = at->sfc; - fi = sfi; - f->cfb=0.0; - f->fd='S'; - f->ros=f->rss; - } - return(fi); - } - - float flank_fire_behaviour(inputs *inp,fuel_coefs *ptr,main_outs *at, - fire_struc *f) - { - float sfi,fi; - int firetype=0; - sfi=fire_intensity(at->sfc,f->rss); - firetype=fire_type(at->csi,sfi); - if(firetype==1) - { - f->cfb = crown_frac_burn(f->rss,at->rso); - f->fd = fire_description(f->cfb); - f->cfc = crown_consump(inp,ptr,f->cfb); - f->fc = f->cfc + at->sfc; - fi = fire_intensity(f->fc,f->ros); - } - if(firetype!=1 || at->covertype=='n') - { - f->fc = at->sfc; - fi = sfi; - f->cfb=0.0; - f->fd='S'; - /* f->ros=f->rss; removed...v4.5 should not have been here ros set in flankfire_ros() */ - } - return(fi); - } - - - void zero_main(main_outs *m) - { - //printf("dlw debug, enter zero_main\n"); - m->sfc=0.0; - //printf("dlw debug, completed sfc zero assign\n"); - m->csi=0.0;m->rso=0.0;m->fmc=0;m->sfi=0.0; - m->rss=0.0;m->isi=0.0;m->be=0.0;m->sf=1.0;m->raz=0.0;m->wsv=0.0; - m->ff=0.0; m->jd=0;m->jd_min=0; - m->covertype=' '; - } - - void zero_sec (snd_outs *s) - { - //printf("dlw debug, enter zero_sec\n"); - //printf("dlw debug, trying s->lb=%f\n",s->lb); - s->lb=0.0; - //printf("dlw debug, completed s->lb=0.0\n"); - s->area=0.0; - //printf("dlw debug, completed s->area=0.0\n"); - s->perm=0.0; - //printf("dlw debug, completed s->perm=0.0\n"); - s->pgr=0.0; - //printf("dlw debug, completed s->pgr=0.0\n"); - } - - void zero_fire (fire_struc *a) - { - //printf("dlw debug, enter zero_fire\n"); - //printf("try before assign a->ros=%f\n", a->ros); - a->ros=0.0; - //printf("dlw debug, did a->ros\n"); - a->dist=0.0;a->rost=0.0;a->cfb=0.0;a->fi=0.0; - //printf("dlw debug, did a->fi\n"); - a->fc=0.0;a->cfc=0.0;a->time=0.0; - //printf("dlw debug, did a->time\n"); - } \ No newline at end of file +/* Subroutine of FBP.C version 4.4 Aug,2007 + Canadian Forest Fire Behaviour Prediction System +This code is copyright of the Canadian Forest Service, Natural Resources Canada +(1992-2005) It is provide free of charge to anyone who wishes to incorporate it +within their forest fire management applications, however users should note in +their application that the FBP calucaltions come from the Canadianf Forest +Services Fire Behaviour Prediction System. The Canadian Forest Service has gone +through considerable testing to ensure that these computer functions duplicate +the system as laid out in ST-X-3 (The Development and Structure of the Canadian +Forest Fire Behaviour Prediction System (1992)) and the subsequent corrections +and additions to the system (the draft "FBP Note"), however no guarentte is +given as to the absolute accuracy of the code. This file contains a series of +functions that go thru all the FBP System calculations. Originally Written at +P.N.F.I. December 91, by Mike Wotton Corrections to version 1.0 1.01 - b +value in O1b was wrong. KA at nofc (mar5,92) ...bmw 1.01a - no error just +added upper and lowercase fueltype entry ...bmw 1.02 - l_to_b problem with +inequalitiy...minor prob fixed 1.5 - modifications to stop small(improbable) +numbers from blowing up the slope calculation stuff this caused a slope problem +which BA @ PFC pointed out may 93.......bmw 3.0 jan /96 bmw + - c6 - constant sfc + 3.01 apr/97 + - add line to recognize uppercase in grass fuels + 3.02 apr/97 + - change accn funtion to recognize lower case fuels for open + 3.1 jul/97 + - change slope function to stop overflow when cur<=50 in O1 + 3.2 sept/97 + - change the c6 calc of flank ros to avoid variation in l/b with + RSC calculation in flank. + 3.3 jan/98 + - error was SFC >0 if CUR<50 (and hence ROS=0) + changed this within the surf_fuel_consump() fn + 3.4 apr/98 (ya i know the dates aren't in sequence) + - change O1a A value from 1.41 to 1.4 from KA apr/98 + + 4.0 jan/98 + - changes listed within the FBP note and TEST dataset + 4.1 - August 2004 + - final changes in the FBP note (new M-3/M-4 model) and a new grass +CF model -removed some verstigaes of older functions for input /output 4.2 - +Oct 2004 + - changes as a result of discussion with Prometheus team + - SFC in grass ...4.1 did not include changes to grass consumption +though spread at values of CUR<50% are now possible (see point 3.3 above) + - at very short time periods using acceleration a CFB(t) should be +caluclated and used for final ROS in the C-6 model. 4.3 - August 2005 + - changes as a result of further discussions with Prometheus team. +These were: + - changes to include the alternate ISI calculation formula (53a +footnote 2) in the calculation of WSE (...added as a section to The FBP Note) + - addition of D-2 for the promtheus team to evaluate their model + ( D-2 is leafed out pure aspen + ROS(D-2)= 0.2 * ROS(D-1) if BUI>80 otherwise ROS(D-2)=0) + - NOTE that this (D-2) is not an official part of the FBP System +however. 4.4 August 2007 + - crown consump in m3/m4. It was calcuating based full conifer +content. but should be modifed by PDF + - change to match changes in FBP Note section 3.3 (eqn 66c) + 4.5 Nov 2007 + - perimeter calc wasn't based on LB(t). + - Flankfire final ROS (FROS) could be set to FRSS if flank fire did +not involve crowning + - change to function headers in perimeter() and +flank_spread_distance() to accomodate LB(t) assignment + - LB(t) is now added to the secondary inputs structure and kept + it is asdsigned in flank_spread_distance(). + 4.6 jan 2009 + - uping the slope limit to 70%...and so the default after that +is 10.0 5.0 Oct 2014 + - PGR is corrected to be a function of ROS(t) not equilibrium ROS + 5.0001 June 2015 + - forgot to change the encoded version number to 5.0. now 5.0001 + - updated header to FBP5.h +*/ +#include "FuelModelFBP.h" +#include "Cells.h" +#include +#include +#include + +char version[50] = "Last modified June 2015, by BMW ", ver[17] = "Version 5.0001 "; + +float slopelimit_isi = 0.01; +int numfuels = 18; + +void +calculate_fbp( + inputs* data, fuel_coefs* pt, main_outs* at, snd_outs* sec, fire_struc* hptr, fire_struc* fptr, fire_struc* bptr) +{ + int firetype = 0; + float accn; + fuel_coefs** ptr = &pt; + setup_const(*ptr); + zero_main(at); + zero_sec(sec); + zero_fire(hptr); + zero_fire(fptr); + zero_fire(bptr); + at->covertype = get_fueltype_number(ptr, data->fueltype); + at->ff = ffmc_effect(data->ffmc); + at->rss = rate_of_spread(data, (*ptr), at); + hptr->rss = at->rss; + at->sfc = surf_fuel_consump(data); + at->sfi = fire_intensity(at->sfc, at->rss); + + if (at->covertype == 'c') + { + at->fmc = foliar_moisture(data, at); + at->csi = crit_surf_intensity((*ptr), at->fmc); + at->rso = critical_ros(data->fueltype, at->sfc, at->csi); + firetype = fire_type(at->csi, at->sfi); + at->crown = firetype; + if (firetype == 1) + { + hptr->cfb = crown_frac_burn(at->rss, at->rso); + hptr->fd = fire_description(hptr->cfb); + hptr->ros = final_ros(data, at->fmc, at->isi, hptr->cfb, at->rss); + hptr->cfc = crown_consump(data, (*ptr), hptr->cfb); + hptr->fc = hptr->cfc + at->sfc; + hptr->fi = fire_intensity(hptr->fc, hptr->ros); + } + } + if (at->covertype == 'n' || firetype == 0) + { + hptr->fd = 'S'; + hptr->ros = at->rss; + hptr->fc = at->sfc; + hptr->fi = at->sfi; + hptr->cfb = 0.0; + } + sec->lb = l_to_b(data->fueltype, at->wsv); + bptr->isi = backfire_isi(at); + bptr->rss = backfire_ros(data, (*ptr), at, bptr->isi); + fptr->rss = flankfire_ros(hptr->rss, bptr->rss, sec->lb); + bptr->fi = fire_behaviour(data, (*ptr), at, bptr); + fptr->ros = flankfire_ros(hptr->ros, bptr->ros, sec->lb); + fptr->fi = flank_fire_behaviour(data, (*ptr), at, fptr); + at->a = hptr->ros; + at->b = fptr->ros; + + if (data->pattern == 1 && data->time > 0) + { + accn = acceleration(data, hptr->cfb); + hptr->dist = spread_distance(data, hptr, accn); + bptr->dist = spread_distance(data, bptr, accn); + fptr->dist + = flank_spread_distance(data, fptr, sec, hptr->rost, bptr->rost, hptr->dist, bptr->dist, sec->lb, accn); + at->fl = hptr->dist; + hptr->time = time_to_crown(hptr->ros, at->rso, accn); + fptr->time = time_to_crown(fptr->ros, at->rso, accn); + bptr->time = time_to_crown(bptr->ros, at->rso, accn); + } + else + { + set_all(hptr, data->time); + set_all(fptr, data->time); + set_all(bptr, data->time); + } + sec->area = area((hptr->dist + bptr->dist), fptr->dist); + if (data->pattern == 1 && data->time > 0) + sec->perm = perimeter(hptr, bptr, sec, sec->lbt); + else + sec->perm = perimeter(hptr, bptr, sec, sec->lb); + at->c = bptr->ros; +} + +void +determine_destiny_metrics_fbp(inputs* data, fuel_coefs* pt, main_outs* metrics, fire_struc* metrics2) +{ + int firetype = 0; + fuel_coefs** ptr = &pt; + setup_const(*ptr); + zero_main(metrics); + metrics->covertype = get_fueltype_number(ptr, data->fueltype); + if (metrics->covertype == 'f') + { + metrics->rss = 0; + metrics->sfi = 0; + metrics->crown = 0; + } + else + { + metrics->ff = ffmc_effect(data->ffmc); + metrics->rss = rate_of_spread(data, (*ptr), metrics); + metrics->sfc = surf_fuel_consump(data); + metrics->sfi = fire_intensity(metrics->sfc, metrics->rss); + + if (metrics->covertype == 'c') + { + metrics->fmc = foliar_moisture(data, metrics); + metrics->csi = crit_surf_intensity((*ptr), metrics->fmc); + metrics->rso = critical_ros(data->fueltype, metrics->sfc, metrics->csi); + firetype = fire_type(metrics->csi, metrics->sfi); + metrics->crown = firetype; + if (firetype == 1) + { + metrics2->cfb = crown_frac_burn(metrics->rss, metrics->rso); + } + } + } +} + +void +setup_const(fuel_coefs* ptr) +{ + // printf("dlw debug, enter fuel_coefs\n"); + /* fuel type 0 */ + strncpy(ptr->fueltype, "M1 ", 3); + ptr->p1 = 110.0; + ptr->p2 = 0.0282; + ptr->p3 = 1.5; + ptr->q = 0.80; + ptr->bui0 = 50; + ptr->cbh = 6; + ptr->cfl = 0.80; + /* fuel type 1 */ + ptr++; + strncpy(ptr->fueltype, "M2 ", 3); + ptr->p1 = 110.0; + ptr->p2 = 0.0282; + ptr->p3 = 1.5; + ptr->q = 0.80; + ptr->bui0 = 50; + ptr->cbh = 6; + ptr->cfl = 0.80; + /* fuel type 2 */ + ptr++; + strncpy(ptr->fueltype, "M3 ", 3); + ptr->p1 = 120.0; + ptr->p2 = 0.0572; + ptr->p3 = 1.4; + ptr->q = 0.80; + ptr->bui0 = 50; + ptr->cbh = 6; + ptr->cfl = 0.80; + /* fuel type 3 */ + ptr++; + strncpy(ptr->fueltype, "M4 ", 3); + ptr->p1 = 100.0; + ptr->p2 = 0.0404; + ptr->p3 = 1.48; + ptr->q = 0.80; + ptr->bui0 = 50; + ptr->cbh = 6; + ptr->cfl = 0.80; + /* fuel type 4 */ + ptr++; + strncpy(ptr->fueltype, "C1 ", 3); + ptr->p1 = 90.0; + ptr->p2 = 0.0649; + ptr->p3 = 4.5; + ptr->q = 0.90; + ptr->bui0 = 72; + ptr->cbh = 2; + ptr->cfl = 0.75; + /* fuel type 5 */ + ptr++; + strncpy(ptr->fueltype, "C2 ", 3); + ptr->p1 = 110.0; + ptr->p2 = 0.0282; + ptr->p3 = 1.5; + ptr->q = 0.70; + ptr->bui0 = 64; + ptr->cbh = 3; + ptr->cfl = 0.80; + /* fuel type 6 */ + ptr++; + strncpy(ptr->fueltype, "C3 ", 3); + ptr->p1 = 110.0; + ptr->p2 = 0.0444; + ptr->p3 = 3.0; + ptr->q = 0.75; + ptr->bui0 = 62; + ptr->cbh = 8; + ptr->cfl = 1.15; + /* fuel type 7 */ + ptr++; + strncpy(ptr->fueltype, "C4 ", 3); + ptr->p1 = 110.0; + ptr->p2 = 0.0293; + ptr->p3 = 1.5; + ptr->q = 0.80; + ptr->bui0 = 66; + ptr->cbh = 4; + ptr->cfl = 1.20; + /* fuel type 8 */ + ptr++; + strncpy(ptr->fueltype, "C5 ", 3); + ptr->p1 = 30.0; + ptr->p2 = 0.0697; + ptr->p3 = 4.0; + ptr->q = 0.80; + ptr->bui0 = 56; + ptr->cbh = 18; + ptr->cfl = 1.20; + /* fuel type 9 */ + ptr++; + strncpy(ptr->fueltype, "C6 ", 3); + ptr->p1 = 30.0; + ptr->p2 = 0.0800; + ptr->p3 = 3.0; + ptr->q = 0.80; + ptr->bui0 = 62; + ptr->cbh = 7; + ptr->cfl = 1.80; + /* fuel type 10 */ + ptr++; + strncpy(ptr->fueltype, "C7 ", 3); + ptr->p1 = 45.0; + ptr->p2 = 0.0305; + ptr->p3 = 2.0; + ptr->q = 0.85; + ptr->bui0 = 106; + ptr->cbh = 10; + ptr->cfl = 0.50; + /* fuel type 11 */ + ptr++; + strncpy(ptr->fueltype, "D1 ", 3); + ptr->p1 = 30.0; + ptr->p2 = 0.0232; + ptr->p3 = 1.6; + ptr->q = 0.90; + ptr->bui0 = 32; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 12 */ + ptr++; + strncpy(ptr->fueltype, "S1 ", 3); + ptr->p1 = 75.0; + ptr->p2 = 0.0297; + ptr->p3 = 1.3; + ptr->q = 0.75; + ptr->bui0 = 38; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 13 */ + ptr++; + strncpy(ptr->fueltype, "S2 ", 3); + ptr->p1 = 40.0; + ptr->p2 = 0.0438; + ptr->p3 = 1.7; + ptr->q = 0.75; + ptr->bui0 = 63; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 14 */ + ptr++; + strncpy(ptr->fueltype, "S3 ", 3); + ptr->p1 = 55.0; + ptr->p2 = 0.0829; + ptr->p3 = 3.2; + ptr->q = 0.75; + ptr->bui0 = 31; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 15 */ + ptr++; + strncpy(ptr->fueltype, "O1a", 3); + ptr->p1 = 190.0; + ptr->p2 = 0.0310; + ptr->p3 = 1.40; + ptr->q = 1.000; + ptr->bui0 = 01; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 16 */ + ptr++; + strncpy(ptr->fueltype, "O1b", 3); + ptr->p1 = 250.0; + ptr->p2 = 0.0350; + ptr->p3 = 1.7; + ptr->q = 1.000; + ptr->bui0 = 1; + ptr->cbh = 0; + ptr->cfl = 0.0; + /* fuel type 17 */ + ptr++; + strncpy(ptr->fueltype, "D2 ", 3); + ptr->p1 = 6.0; + ptr->p2 = 0.0232; + ptr->p3 = 1.6; + ptr->q = 0.90; + ptr->bui0 = 32; + ptr->cbh = 0; + ptr->cfl = 0.0; +} + +char +get_fueltype_number(fuel_coefs** ptr, char fuel[4]) +{ + int i; + char cover; + if (fuel[0] >= 'a' && fuel[0] <= 'z') + fuel[0] += 'A' - 'a'; + if (fuel[2] >= 'A' && fuel[2] <= 'Z') + fuel[2] += 'a' - 'A'; + for (i = 0; i < numfuels && (strncmp((*ptr)->fueltype, fuel, 3) != 0); i++) + (*ptr)++; + if (i >= numfuels) + { + printf(" %s not a recognizable fuel type\n ", fuel); + // exit(9); + cover = 'f'; + return (cover); + } + if (fuel[0] == 'C' || fuel[0] == 'M') + cover = 'c'; + else + cover = 'n'; + + return (cover); +} + +float +ffmc_effect(float ffmc) +{ + float mc, ff; + mc = 147.2 * (101.0 - ffmc) / (59.5 + ffmc); + ff = 91.9 * exp(-0.1386 * mc) * (1 + pow(mc, 5.31) / 49300000.0); + return (ff); +} + +float +rate_of_spread(inputs* inp, fuel_coefs* ptr, main_outs* at) +{ + float fw, isz, mult, *mu = &mult, rsi; + at->ff = ffmc_effect(inp->ffmc); + at->raz = inp->waz; + isz = 0.208 * at->ff; + if (inp->ps > 0) + at->wsv = slope_effect(inp, ptr, at, isz); + else + at->wsv = inp->ws; + + if (at->wsv < 40.0) + fw = exp(0.05039 * at->wsv); + else + fw = 12.0 * (1.0 - exp(-0.0818 * (at->wsv - 28))); + at->isi = isz * fw; + rsi = ros_calc(inp, ptr, at->isi, mu); + at->rss = rsi * bui_effect(ptr, at, inp->bui); + return (at->rss); +} + +float +ros_calc(inputs* inp, fuel_coefs* ptr, float isi, float* mult) +{ + float ros; + if (strncmp(inp->fueltype, "O1", 2) == 0) + return (grass(ptr, inp->cur, isi, mult)); + if (strncmp(inp->fueltype, "M1", 2) == 0 || strncmp(inp->fueltype, "M2", 2) == 0) + return (mixed_wood(ptr, isi, mult, inp->pc)); + if (strncmp(inp->fueltype, "M3", 2) == 0 || strncmp(inp->fueltype, "M4", 2) == 0) + return (dead_fir(ptr, inp->pdf, isi, mult)); + if (strncmp(inp->fueltype, "D2", 2) == 0) + return (D2_ROS(ptr, isi, inp->bui, mult)); + /* if all else has fail its a conifer */ + return (conifer(ptr, isi, mult)); +} + +float +grass(fuel_coefs* ptr, float cur, float isi, float* mult) +{ + float mu, ros; + if ((float)(cur) >= 58.8) + mu = 0.176 + 0.02 * ((float)(cur)-58.8); + else + mu = 0.005 * (exp(0.061 * (float)(cur)) - 1.0); + ros = mu * (ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3)); + if (mu < 0.001) + mu = 0.001; /* to have some value here*/ + *mult = mu; + return (ros); +} + +float +mixed_wood(fuel_coefs* ptr, float isi, float* mu, int pc) +{ + float ros, mult, ros_d1, ros_c2; + int i; + *mu = pc / 100.0; + ros_c2 = ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3); + if (strncmp(ptr->fueltype, "M2", 2) == 0) + mult = 0.2; + else + mult = 1.0; + for (i = 0; strncmp(ptr->fueltype, "D1", 2) != 0 && i < numfuels; ptr++, i++) + ; + if (i >= numfuels) + { + printf(" prob in mixedwood d1 not found \n"); + exit(9); + } + ros_d1 = ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3); + + ros = (pc / 100.0) * ros_c2 + mult * (100 - pc) / 100.0 * ros_d1; + return (ros); +} + +float +dead_fir(fuel_coefs* ptr, int pdf, float isi, float* mu) +{ + double a, b, c; + int i; + float ros, rosm3or4_max, ros_d1, greenness = 1.0; + if (strncmp(ptr->fueltype, "M4", 2) == 0) + greenness = 0.2; + + rosm3or4_max = ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3); + + for (i = 0; strncmp(ptr->fueltype, "D1", 2) != 0 && i < numfuels; ptr++, i++) + ; + if (i >= numfuels) + { + printf(" prob in mixedwood d1 not found \n"); + exit(9); + } + ros_d1 = ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3); + + ros = (float)(pdf) / 100.0 * rosm3or4_max + (100.0 - (float)(pdf)) / 100.0 * greenness * ros_d1; + + *mu = (float)(pdf) / 100.0; + + return (ros); +} + +float +D2_ROS(fuel_coefs* ptr, float isi, float bui, float* mu) +{ + *mu = 1.0; + if (bui >= 80) + return (ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3)); + else + return (0.0); +} + +float +conifer(fuel_coefs* ptr, float isi, float* mu) +{ + *mu = 1.0; + return (ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isi)), ptr->p3)); +} + +float +bui_effect(fuel_coefs* ptr, main_outs* at, float bui) +{ + float bui_avg = 50.0; + + if (bui == 0) + bui = 1.0; + at->be = exp(bui_avg * log(ptr->q) * ((1.0 / bui) - (1.0 / ptr->bui0))); + return (at->be); +} + +float +slope_effect(inputs* inp, fuel_coefs* ptr, main_outs* at, float isi) +/* ISI is ISZ really */ +{ + double isf, rsf, wse, ps, rsz, wsx, wsy, wsex, wsey, wsvx, wsvy, wrad, srad, wsv, raz, check, wse2, wse1; + float mu = 0.0; + ps = inp->ps * 1.0; + + if (ps > 70.0) + ps = 70.0; /* edited in version 4.6*/ + at->sf = exp(3.533 * pow(ps / 100.0, 1.2)); + if (at->sf > 10.0) + at->sf = 10.00; /* added to ensure maximum is correct in version 4.6 */ + + if (strncmp(ptr->fueltype, "M1", 2) == 0 || strncmp(ptr->fueltype, "M2", 2) == 0) + isf = ISF_mixedwood(ptr, isi, inp->pc, at->sf); + else if (strncmp(ptr->fueltype, "M3", 2) == 0 || strncmp(ptr->fueltype, "M4", 2) == 0) + isf = ISF_deadfir(ptr, isi, inp->pdf, at->sf); + else + { + rsz = ros_calc(inp, ptr, isi, &mu); + rsf = rsz * at->sf; + + if (rsf > 0.0) + check = 1.0 - pow((rsf / (mu * ptr->p1)), (1.0 / ptr->p3)); + else + check = 1.0; + if (check < slopelimit_isi) + check = slopelimit_isi; + + isf = (1.0 / (-1.0 * ptr->p2)) * log(check); + } + if (isf == 0.0) + isf = isi; /* should this be 0.0001 really */ + wse1 = log(isf / (0.208 * at->ff)) / 0.05039; + if (wse1 <= 40.0) + wse = wse1; + else + { + if (isf > (0.999 * 2.496 * at->ff)) + isf = 0.999 * 2.496 * at->ff; + wse2 = 28.0 - log(1.0 - isf / (2.496 * at->ff)) / 0.0818; + wse = wse2; + } + wrad = inp->waz / 180.0 * 3.1415926; + wsx = inp->ws * sin(wrad); + wsy = inp->ws * cos(wrad); + srad = inp->saz / 180.0 * 3.1415926; + wsex = wse * sin(srad); + wsey = wse * cos(srad); + wsvx = wsx + wsex; + wsvy = wsy + wsey; + wsv = sqrt(wsvx * wsvx + wsvy * wsvy); + raz = acos(wsvy / wsv); + raz = raz / 3.1415926 * 180.0; + if (wsvx < 0) + raz = 360 - raz; + at->raz = raz; + return ((float)(wsv)); +} + +float +ISF_mixedwood(fuel_coefs* ptr, float isz, int pc, float sf) +{ + float check, mult, rsf_d1, rsf_c2, isf_d1, isf_c2; + int i; + + rsf_c2 = sf * ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isz)), ptr->p3); + if (rsf_c2 > 0.0) + check = 1.0 - pow((rsf_c2 / (ptr->p1)), (1.0 / ptr->p3)); + else + check = 1.0; + if (check < slopelimit_isi) + check = slopelimit_isi; + isf_c2 = (1.0 / (-1.0 * ptr->p2)) * log(check); + + if (strncmp(ptr->fueltype, "M2", 2) == 0) + mult = 0.2; + else + mult = 1.0; + for (i = 0; strncmp(ptr->fueltype, "D1", 2) != 0 && i < numfuels; ptr++, i++) + ; + rsf_d1 = sf * (mult * ptr->p1) * pow((1.0 - exp(-1.0 * ptr->p2 * isz)), ptr->p3); + + if (rsf_d1 > 0.0) + check = 1.0 - pow((rsf_d1 / (mult * ptr->p1)), (1.0 / ptr->p3)); + else + check = 1.0; + if (check < slopelimit_isi) + check = slopelimit_isi; + isf_d1 = (1.0 / (-1.0 * ptr->p2)) * log(check); + + return (((float)(pc) / 100.0) * isf_c2 + (100 - (float)(pc)) / 100.0 * isf_d1); +} + +float +ISF_deadfir(fuel_coefs* ptr, float isz, int pdf, float sf) +{ + float check, mult, rsf_d1, rsf_max, isf_d1, isf_max; + int i; + + rsf_max = sf * ptr->p1 * pow((1.0 - exp(-1.0 * ptr->p2 * isz)), ptr->p3); + if (rsf_max > 0.0) + check = 1.0 - pow((rsf_max / (ptr->p1)), (1.0 / ptr->p3)); + else + check = 1.0; + if (check < slopelimit_isi) + check = slopelimit_isi; + isf_max = (1.0 / (-1.0 * ptr->p2)) * log(check); + + if (strncmp(ptr->fueltype, "M4", 2) == 0) + mult = 0.2; + else + mult = 1.0; + + for (i = 0; strncmp(ptr->fueltype, "D1", 2) != 0 && i < numfuels; ptr++, i++) + ; + rsf_d1 = sf * (mult * ptr->p1) * pow((1.0 - exp(-1.0 * ptr->p2 * isz)), ptr->p3); + + if (rsf_d1 > 0.0) + check = 1.0 - pow((rsf_d1 / (mult * ptr->p1)), (1.0 / ptr->p3)); + else + check = 1.0; + if (check < slopelimit_isi) + check = slopelimit_isi; + isf_d1 = (1.0 / (-1.0 * ptr->p2)) * log(check); + + return (((float)(pdf) / 100.0) * isf_max + (100.0 - (float)(pdf)) / 100.0 * isf_d1); +} + +float +fire_intensity(float fc, float ros) +{ + return (300.0 * fc * ros); +} + +float +foliar_moisture(inputs* inp, main_outs* at) +{ + float latn; + int nd; + at->jd = inp->jd; + at->jd_min = inp->jd_min; + if (inp->jd_min <= 0) + { + if (inp->elev < 0) + { + latn = 23.4 * exp(-0.0360 * (150 - inp->lon)) + 46.0; + at->jd_min = (int)(0.5 + 151.0 * inp->lat / latn); + } + else + { + latn = 33.7 * exp(-0.0351 * (150 - inp->lon)) + 43.0; + at->jd_min = (int)(0.5 + 142.1 * inp->lat / latn + (0.0172 * inp->elev)); + } + } + nd = abs(inp->jd - at->jd_min); + if (nd >= 50) + return (120.0); + if (nd >= 30 && nd < 50) + return (32.9 + 3.17 * nd - 0.0288 * nd * nd); + return (85.0 + 0.0189 * nd * nd); +} + +float +surf_fuel_consump(inputs* inp) +{ + float sfc, ffc, wfc, bui, ffmc, sfc_c2, sfc_d1; + char ft[3]; + strncpy(ft, inp->fueltype, 2); + bui = inp->bui; + ffmc = inp->ffmc; + if (strncmp(ft, "C1", 2) == 0) + { + /* sfc=1.5*(1.0-exp(-0.23*(ffmc-81.0)));*/ + if (ffmc > 84) + sfc = 0.75 + 0.75 * sqrt(1 - exp(-0.23 * (ffmc - 84))); + else + sfc = 0.75 - 0.75 * sqrt(1 - exp(0.23 * (ffmc - 84))); + return (sfc >= 0 ? sfc : 0.0); + } + if (strncmp(ft, "C2", 2) == 0 || strncmp(ft, "M3", 2) == 0 || strncmp(ft, "M4", 2) == 0) + return (5.0 * (1.0 - exp(-0.0115 * bui))); + if (strncmp(ft, "C3", 2) == 0 || strncmp(ft, "C4", 2) == 0) + return (5.0 * pow((1.0 - exp(-0.0164 * bui)), 2.24)); + if (strncmp(ft, "C5", 2) == 0 || strncmp(ft, "C6", 2) == 0) + return (5.0 * pow((1.0 - exp(-0.0149 * bui)), 2.48)); + if (strncmp(ft, "C7", 2) == 0) + { + ffc = 2.0 * (1.0 - exp(-0.104 * (ffmc - 70.0))); + if (ffc < 0) + ffc = 0.0; + wfc = 1.5 * (1.0 - exp(-0.0201 * bui)); + return (ffc + wfc); + } + if (strncmp(ft, "O1", 2) == 0) + return ((inp->gfl) /* change this*/); + if (strncmp(ft, "M1", 2) == 0 || strncmp(ft, "M2", 2) == 0) + { + sfc_c2 = 5.0 * (1.0 - exp(-0.0115 * bui)); + sfc_d1 = 1.5 * (1.0 - exp(-0.0183 * bui)); + sfc = inp->pc / 100.0 * sfc_c2 + (100.0 - inp->pc) / 100.0 * sfc_d1; + return (sfc); + } + if (strncmp(ft, "S1", 2) == 0) + { + ffc = 4.0 * (1.0 - exp(-0.025 * bui)); + wfc = 4.0 * (1.0 - exp(-0.034 * bui)); + return (ffc + wfc); + } + if (strncmp(ft, "S2", 2) == 0) + { + ffc = 10.0 * (1.0 - exp(-0.013 * bui)); + wfc = 6.0 * (1.0 - exp(-0.060 * bui)); + return (ffc + wfc); + } + if (strncmp(ft, "S3", 2) == 0) + { + ffc = 12.0 * (1.0 - exp(-0.0166 * bui)); + wfc = 20.0 * (1.0 - exp(-0.0210 * bui)); + return (ffc + wfc); + } + if (strncmp(ft, "D1", 2) == 0) + return (1.5 * (1.0 - exp(-0.0183 * bui))); + if (strncmp(ft, "D2", 2) == 0) + return (bui >= 80 ? 1.5 * (1.0 - exp(-0.0183 * bui)) : 0.0); + + printf("prob in sfc func \n"); + exit(9); + return (-99); +} + +float +crit_surf_intensity(fuel_coefs* ptr, float fmc) +{ + if (ptr->cbh > 0) + { + return (0.001 * pow(ptr->cbh * (460.0 + 25.9 * fmc), 1.5)); + } + else + { + return (999999999); // if cbh is equal to 0, critical intensity is set to + // big number + } +} + +float +critical_ros(char ft[3], float sfc, float csi) +{ + if (sfc > 0) + return (csi / (300.0 * sfc)); + else + return (0.0); +} + +float +crown_frac_burn(float rss, float rso) +{ + float cfb; + cfb = 1.0 - exp(-0.230 * (rss - rso)); + return (cfb > 0 ? cfb : 0.0); +} + +int +fire_type(float csi, float sfi) +{ + return (sfi > csi ? 1 : 0); +} + +char +fire_description(float cfb) +{ + if (cfb < 0.1) + return ('S'); + if (cfb < 0.9 && cfb >= 0.1) + return ('I'); + if (cfb >= 0.9) + return ('C'); + return ('*'); +} + +float +final_ros(inputs* inp, float fmc, float isi, float cfb, float rss) +{ + float rsc, ros; + if (strncmp(inp->fueltype, "C6", 2) == 0) + { + rsc = foliar_mois_effect(isi, fmc); + ros = rss + cfb * (rsc - rss); + } + else + ros = rss; + return (ros); +} + +float +foliar_mois_effect(float isi, float fmc) +{ + float fme, rsc, fme_avg = 0.778; + fme = 1000.0 * pow(1.5 - 0.00275 * fmc, 4.0) / (460.0 + 25.9 * fmc); + rsc = 60.0 * (1.0 - exp(-0.0497 * isi)) * fme / fme_avg; + return (rsc); +} + +float +crown_consump(inputs* inp, fuel_coefs* ptr, float cfb) +{ + float cfc; + cfc = ptr->cfl * cfb; + if (strncmp(inp->fueltype, "M1", 2) == 0 || strncmp(inp->fueltype, "M2", 2) == 0) + cfc = inp->pc / 100.0 * cfc; + if (strncmp(inp->fueltype, "M3", 2) == 0 || strncmp(inp->fueltype, "M4", 2) == 0) + cfc = inp->pdf / 100.0 * cfc; + return (cfc); +} + +float +l_to_b(char ft[3], float ws) +{ + if (strncmp(ft, "O1", 2) == 0) + return (ws < 1.0 ? 1.0 : (1.1 * pow(ws, 0.464))); + else + return (1.0 + 8.729 * pow(1.0 - exp(-0.030 * ws), 2.155)); +} + +void +set_all(fire_struc* ptr, int time) +{ + ptr->time = 0; + ptr->rost = ptr->ros; + ptr->dist = time * ptr->ros; +} +float +backfire_isi(main_outs* at) +{ + float bfw; + bfw = exp(-0.05039 * at->wsv); + return (0.208 * at->ff * bfw); +} + +float +backfire_ros(inputs* inp, fuel_coefs* ptr, main_outs* at, float bisi) +{ + float mult = 0.0, bros; + bros = ros_calc(inp, ptr, bisi, &mult); + bros *= bui_effect(ptr, at, inp->bui); + return (bros); +} + +float +area(float dt, float df) +{ + float a, b; + a = dt / 2.0; + b = df; + return (a * b * 3.1415926 / 10000.0); +} + +float +perimeter(fire_struc* h, fire_struc* b, snd_outs* sec, float lb) +{ + float mult, p; + mult = 3.1415926 * (1.0 + 1.0 / lb) * (1.0 + pow(((lb - 1.0) / (2.0 * (lb + 1.0))), 2.0)); + p = (h->dist + b->dist) / 2.0 * mult; + sec->pgr = (h->rost + b->rost) / 2.0 * mult; + + return (p); +} + +float +acceleration(inputs* inp, float cfb) +{ + int i; + char canopy = 'c', open_list[10][3] = { "O1", "C1", "S1", "S2", "S3", "o1", "c1", "s1", "s2", "s3" }; + for (i = 0; strncmp(inp->fueltype, open_list[i], 2) != 0 && i < 10; i++) + ; + if (i < 10) + canopy = 'o'; + if (canopy == 'o') + return (0.115); + else + return (0.115 - 18.8 * pow(cfb, 2.5) * exp(-8.0 * cfb)); +} + +float +flankfire_ros(float ros, float bros, float lb) +{ + return ((ros + bros) / (lb * 2.0)); +} + +float +flank_spread_distance( + inputs* inp, fire_struc* ptr, snd_outs* sec, float hrost, float brost, float hd, float bd, float lb, float a) +{ + sec->lbt = (lb - 1.0) * (1.0 - exp(-a * inp->time)) + 1.0; + ptr->rost = (hrost + brost) / (sec->lbt * 2.0); + return ((hd + bd) / (2.0 * sec->lbt)); +} + +float +spread_distance(inputs* inp, fire_struc* ptr, float a) +{ + ptr->rost = ptr->ros * (1.0 - exp(-a * inp->time)); + return (ptr->ros * (inp->time + (exp(-a * inp->time) / a) - 1.0 / a)); +} + +int +time_to_crown(float ros, float rso, float a) +{ + float ratio; + if (ros > 0) + ratio = rso / ros; + else + ratio = 1.1; + if (ratio > 0.9 && ratio <= 1.0) + ratio = 0.9; + if (ratio < 1.0) + return (int)(log(1.0 - ratio) / -a); + else + return (99); +} + +float +fire_behaviour(inputs* inp, fuel_coefs* ptr, main_outs* at, fire_struc* f) +{ + float sfi, fi; + int firetype = 0; + sfi = fire_intensity(at->sfc, f->rss); + firetype = fire_type(at->csi, sfi); + if (firetype == 1) + { + f->cfb = crown_frac_burn(f->rss, at->rso); + f->fd = fire_description(f->cfb); + f->ros = final_ros(inp, at->fmc, f->isi, f->cfb, f->rss); + f->cfc = crown_consump(inp, ptr, f->cfb); + f->fc = f->cfc + at->sfc; + fi = fire_intensity(f->fc, f->ros); + } + if (firetype != 1 || at->covertype == 'n') + { + f->fc = at->sfc; + fi = sfi; + f->cfb = 0.0; + f->fd = 'S'; + f->ros = f->rss; + } + return (fi); +} + +float +flank_fire_behaviour(inputs* inp, fuel_coefs* ptr, main_outs* at, fire_struc* f) +{ + float sfi, fi; + int firetype = 0; + sfi = fire_intensity(at->sfc, f->rss); + firetype = fire_type(at->csi, sfi); + if (firetype == 1) + { + f->cfb = crown_frac_burn(f->rss, at->rso); + f->fd = fire_description(f->cfb); + f->cfc = crown_consump(inp, ptr, f->cfb); + f->fc = f->cfc + at->sfc; + fi = fire_intensity(f->fc, f->ros); + } + if (firetype != 1 || at->covertype == 'n') + { + f->fc = at->sfc; + fi = sfi; + f->cfb = 0.0; + f->fd = 'S'; + /* f->ros=f->rss; removed...v4.5 should not have been here ros set + * in flankfire_ros() */ + } + return (fi); +} + +void +zero_main(main_outs* m) +{ + // printf("dlw debug, enter zero_main\n"); + m->sfc = 0.0; + // printf("dlw debug, completed sfc zero assign\n"); + m->csi = 0.0; + m->rso = 0.0; + m->fmc = 0; + m->sfi = 0.0; + m->rss = 0.0; + m->isi = 0.0; + m->be = 0.0; + m->sf = 1.0; + m->raz = 0.0; + m->wsv = 0.0; + m->ff = 0.0; + m->jd = 0; + m->jd_min = 0; + m->covertype = ' '; +} + +void +zero_sec(snd_outs* s) +{ + // printf("dlw debug, enter zero_sec\n"); + // printf("dlw debug, trying s->lb=%f\n",s->lb); + s->lb = 0.0; + // printf("dlw debug, completed s->lb=0.0\n"); + s->area = 0.0; + // printf("dlw debug, completed s->area=0.0\n"); + s->perm = 0.0; + // printf("dlw debug, completed s->perm=0.0\n"); + s->pgr = 0.0; + // printf("dlw debug, completed s->pgr=0.0\n"); +} + +void +zero_fire(fire_struc* a) +{ + // printf("dlw debug, enter zero_fire\n"); + // printf("try before assign a->ros=%f\n", a->ros); + a->ros = 0.0; + // printf("dlw debug, did a->ros\n"); + a->dist = 0.0; + a->rost = 0.0; + a->cfb = 0.0; + a->fi = 0.0; + // printf("dlw debug, did a->fi\n"); + a->fc = 0.0; + a->cfc = 0.0; + a->time = 0.0; + // printf("dlw debug, did a->time\n"); +} diff --git a/Cell2Fire/FuelModelFBP.h b/Cell2Fire/FuelModelFBP.h index 075a3a57..908c9085 100644 --- a/Cell2Fire/FuelModelFBP.h +++ b/Cell2Fire/FuelModelFBP.h @@ -11,93 +11,92 @@ #if !defined(_FBPHEAD) #define _FBPHEAD +#include "Cells.h" #include -float grass(fuel_coefs *ptr,float cur,float isi,float *mu); +float grass(fuel_coefs* ptr, float cur, float isi, float* mu); -float mixed_wood(fuel_coefs *ptr,float isi, float *mult,int pc); +float mixed_wood(fuel_coefs* ptr, float isi, float* mult, int pc); - float ISF_mixedwood(fuel_coefs *ptr, float isz, int pc, float sf); +float ISF_mixedwood(fuel_coefs* ptr, float isz, int pc, float sf); - float ISF_deadfir(fuel_coefs *ptr, float isz, int pdf, float sf); +float ISF_deadfir(fuel_coefs* ptr, float isz, int pdf, float sf); -float dead_fir(fuel_coefs *ptr,int pdf,float isi,float *mult); +float dead_fir(fuel_coefs* ptr, int pdf, float isi, float* mult); -float D2_ROS(fuel_coefs *ptr, float isi, float bui, float *mu); +float D2_ROS(fuel_coefs* ptr, float isi, float bui, float* mu); -float conifer(fuel_coefs *ptr,float isi,float *mult); +float conifer(fuel_coefs* ptr, float isi, float* mult); -float bui_effect(fuel_coefs *ptr,main_outs *at, float bui); +float bui_effect(fuel_coefs* ptr, main_outs* at, float bui); -float ros_calc(inputs *inp, fuel_coefs *ptr, float isi, float *mu); +float ros_calc(inputs* inp, fuel_coefs* ptr, float isi, float* mu); -float rate_of_spread(inputs *inp,fuel_coefs *ptr, main_outs *at); +float rate_of_spread(inputs* inp, fuel_coefs* ptr, main_outs* at); -float slope_effect(inputs *inp, fuel_coefs *ptr, main_outs *at,float isi); +float slope_effect(inputs* inp, fuel_coefs* ptr, main_outs* at, float isi); -float surf_fuel_consump(inputs *inp); +float surf_fuel_consump(inputs* inp); -float fire_intensity(float fc,float ros); +float fire_intensity(float fc, float ros); -void setup_const(fuel_coefs *ptr); +void setup_const(fuel_coefs* ptr); -char get_fueltype_number(fuel_coefs **ptr,char ft[4]); +char get_fueltype_number(fuel_coefs** ptr, char ft[4]); -float foliar_moisture(inputs *inp, main_outs *at); +float foliar_moisture(inputs* inp, main_outs* at); -float crit_surf_intensity(fuel_coefs *ptr,float fmc); +float crit_surf_intensity(fuel_coefs* ptr, float fmc); -float critical_ros(char ft[3],float sfc,float csi); +float critical_ros(char ft[3], float sfc, float csi); -int fire_type(float csi,float sfi); +int fire_type(float csi, float sfi); -float crown_frac_burn(float ros,float rso); +float crown_frac_burn(float ros, float rso); char fire_description(float cfb); -float final_ros(inputs *inp, float fmc,float isi,float cfb,float rss); +float final_ros(inputs* inp, float fmc, float isi, float cfb, float rss); -float crown_consump(inputs *inp, fuel_coefs *ptr, float cfb); +float crown_consump(inputs* inp, fuel_coefs* ptr, float cfb); -float foliar_mois_effect(float isi,float fmc); +float foliar_mois_effect(float isi, float fmc); -float l_to_b(char ft[3],float ws); +float l_to_b(char ft[3], float ws); float ffmc_effect(float ffmc); -float backfire_ros(inputs *inp,fuel_coefs *ptr, main_outs *at,float bisi); +float backfire_ros(inputs* inp, fuel_coefs* ptr, main_outs* at, float bisi); -float backfire_isi(main_outs *at); +float backfire_isi(main_outs* at); -float area(float dt,float df); +float area(float dt, float df); -float perimeter(fire_struc *h,fire_struc *b,snd_outs *sec,float lb); +float perimeter(fire_struc* h, fire_struc* b, snd_outs* sec, float lb); -float acceleration(inputs *inp, float cfb); +float acceleration(inputs* inp, float cfb); -float flankfire_ros(float ros,float bros,float lb); +float flankfire_ros(float ros, float bros, float lb); -float spread_distance(inputs *inp, fire_struc *ptr, float accn); +float spread_distance(inputs* inp, fire_struc* ptr, float accn); -float flank_spread_distance(inputs *inp,fire_struc *ptr, snd_outs *sec, - float hrost,float brost,float hd, float bd,float lb,float a); +float flank_spread_distance( + inputs* inp, fire_struc* ptr, snd_outs* sec, float hrost, float brost, float hd, float bd, float lb, float a); -int time_to_crown(float ros,float rso,float a); +int time_to_crown(float ros, float rso, float a); -float fire_behaviour(inputs *inp,fuel_coefs *ptr,main_outs *at, - fire_struc *f); -float flank_fire_behaviour(inputs *inp,fuel_coefs *ptr,main_outs *at, - fire_struc *f); +float fire_behaviour(inputs* inp, fuel_coefs* ptr, main_outs* at, fire_struc* f); +float flank_fire_behaviour(inputs* inp, fuel_coefs* ptr, main_outs* at, fire_struc* f); -void set_all(fire_struc *ptr, int time); +void set_all(fire_struc* ptr, int time); -void calculate_fbp(inputs *data,fuel_coefs *ptr,main_outs *at, - snd_outs *sec,fire_struc *hptr,fire_struc *fptr,fire_struc *bptr); -void determine_destiny_metrics_fbp(inputs* data, fuel_coefs* pt, main_outs* metrics,fire_struc* metrics2); -void zero_main(main_outs *m); +void calculate_fbp( + inputs* data, fuel_coefs* ptr, main_outs* at, snd_outs* sec, fire_struc* hptr, fire_struc* fptr, fire_struc* bptr); +void determine_destiny_metrics_fbp(inputs* data, fuel_coefs* pt, main_outs* metrics, fire_struc* metrics2); +void zero_main(main_outs* m); -void zero_sec (snd_outs *s); +void zero_sec(snd_outs* s); -void zero_fire(fire_struc *a); +void zero_fire(fire_struc* a); -#endif \ No newline at end of file +#endif diff --git a/Cell2Fire/FuelModelKitral.cpp b/Cell2Fire/FuelModelKitral.cpp index 46b52cd9..6d40918c 100644 --- a/Cell2Fire/FuelModelKitral.cpp +++ b/Cell2Fire/FuelModelKitral.cpp @@ -1,37 +1,35 @@ #include "FuelModelKitral.h" -#include "ReadArgs.h" #include "Cells.h" +#include "ReadArgs.h" +#include #include #include -#include #include #include -#include #include -#include #include +#include #include using namespace std; /* - Global coefficients -*/ + Global coefficients +*/ std::unordered_map> fmcs; std::unordered_map> cbhs; std::unordered_map> fls_david; std::unordered_map> hs; std::unordered_map> cbds; - - /* - Functions + Functions */ -void setup_const() +void +setup_const() { - //printf("dlw debug, enter fuel_coefs\n"); + // printf("dlw debug, enter fuel_coefs\n"); /* fuel type 1 */ int PCH1 = 1; std::vector fmc_pch1; @@ -67,7 +65,6 @@ void setup_const() hs.insert(std::make_pair(PCH2, h_pch2)); cbds.insert(std::make_pair(PCH2, cbd_pch2)); - int PCH3 = 3; std::vector fmc_pch3; std::vector cbh_pch3; @@ -85,7 +82,6 @@ void setup_const() hs.insert(std::make_pair(PCH3, h_pch3)); cbds.insert(std::make_pair(PCH3, cbd_pch3)); - int PCH4 = 4; std::vector fmc_pch4; std::vector cbh_pch4; @@ -103,7 +99,6 @@ void setup_const() hs.insert(std::make_pair(PCH4, h_pch4)); cbds.insert(std::make_pair(PCH4, cbd_pch4)); - int PCH5 = 5; std::vector fmc_pch5; std::vector cbh_pch5; @@ -172,7 +167,6 @@ void setup_const() hs.insert(std::make_pair(MT03, h_mt03)); cbds.insert(std::make_pair(MT03, cbd_mt03)); - int MT04 = 9; std::vector fmc_mt04; std::vector cbh_mt04; @@ -206,7 +200,7 @@ void setup_const() fls_david.insert(std::make_pair(MT05, fl_mt05)); hs.insert(std::make_pair(MT05, h_mt05)); cbds.insert(std::make_pair(MT05, cbd_mt05)); - + int MT06 = 11; std::vector fmc_mt06; std::vector cbh_mt06; @@ -224,7 +218,6 @@ void setup_const() hs.insert(std::make_pair(MT06, h_mt06)); cbds.insert(std::make_pair(MT06, cbd_mt06)); - int MT07 = 12; std::vector fmc_mt07; std::vector cbh_mt07; @@ -309,7 +302,7 @@ void setup_const() fls_david.insert(std::make_pair(BN03, fl_bn03)); hs.insert(std::make_pair(BN03, h_bn03)); cbds.insert(std::make_pair(BN03, cbd_bn03)); - + int BN04 = 17; std::vector fmc_bn04; std::vector cbh_bn04; @@ -378,7 +371,6 @@ void setup_const() hs.insert(std::make_pair(PL02, h_pl02)); cbds.insert(std::make_pair(PL02, cbd_pl02)); - int PL03 = 21; std::vector fmc_pl03; std::vector cbh_pl03; @@ -413,7 +405,6 @@ void setup_const() hs.insert(std::make_pair(PL04, h_pl04)); cbds.insert(std::make_pair(PL04, cbd_pl04)); - int PL05 = 23; std::vector fmc_pl05; std::vector cbh_pl05; @@ -431,7 +422,6 @@ void setup_const() hs.insert(std::make_pair(PL05, h_pl05)); cbds.insert(std::make_pair(PL05, cbd_pl05)); - int PL06 = 24; std::vector fmc_pl06; std::vector cbh_pl06; @@ -517,7 +507,6 @@ void setup_const() hs.insert(std::make_pair(PL10, h_pl10)); cbds.insert(std::make_pair(PL10, cbd_pl10)); - int PL11 = 29; std::vector fmc_pl11; std::vector cbh_pl11; @@ -568,133 +557,144 @@ void setup_const() fls_david.insert(std::make_pair(DX02, fl_dx02)); hs.insert(std::make_pair(DX02, h_dx02)); cbds.insert(std::make_pair(DX02, cbd_dx02)); +} +float +rate_of_spread_k(inputs* data, + fuel_coefs* ptr, + main_outs* at) // incluir efecto pendiente aqui y no afuera +{ + float p1, p2, p3, ws, tmp, rh, ch, fmc, fch, fv, ps, fp; + // se = slope_effect(inp) ; + ws = data->ws; + tmp = data->tmp; + rh = data->rh; + ps = at->se; // hacerlo con elevaciones + p1 = -12.86; + p2 = 0.04316; + p3 = 13.8; + ch = (-2.97374 + 0.262 * rh - 0.00982 * tmp); + fmc = fmcs[data->nftype][0] * 60; // factor de propagacion en m/min + fch = (389.1624 + 14.3 * ch + 0.02 * pow(ch, 2.0)) + / (3.559 + 1.6615 * ch + 2.62392 * pow(ch, 2.0)); // es -14.3 segun el libro + fv = p1 * exp(-p2 * ws) + p3; + if (ps == 0) + { + at->rss = fmc * fch * (fv); + } + else + { + at->rss = fmc * fch * (fv + ps); + } + // fp = 1.0 + 0.023322 * data->ps + 0.00013585 * pow(data->ps, 2.0); + // at->rss = fmc*fch*(fv); + return at->rss * (at->rss >= 0); } - -float rate_of_spread_k(inputs *data, fuel_coefs *ptr, main_outs *at) //incluir efecto pendiente aqui y no afuera - { - float p1, p2, p3, ws, tmp, rh, ch, fmc, fch, fv, ps,fp; - - //se = slope_effect(inp) ; - ws = data->ws; - tmp = data->tmp; - rh = data->rh; - ps = at->se; //hacerlo con elevaciones - p1 = -12.86; - p2 = 0.04316; - p3 = 13.8; - ch = (-2.97374 + 0.262 * rh - 0.00982 * tmp); - fmc = fmcs[data->nftype][0]*60; //factor de propagacion en m/min - fch = (389.1624 + 14.3 * ch + 0.02 * pow(ch, 2.0)) / (3.559 + 1.6615 * ch + 2.62392 * pow(ch, 2.0)); //es -14.3 segun el libro - fv = p1 * exp(-p2 * ws) + p3; - if (ps==0){ - at->rss = fmc*fch*(fv); - } - else{ - at->rss = fmc*fch*(fv+ps); - } - - //fp = 1.0 + 0.023322 * data->ps + 0.00013585 * pow(data->ps, 2.0); - //at->rss = fmc*fch*(fv); - return at->rss * (at->rss >= 0) ; - - } - -float flankfire_ros_k(float ros,float bros,float lb) - { - return ((ros + bros) / ( lb * 2.0)) ; - } +float +flankfire_ros_k(float ros, float bros, float lb) +{ + return ((ros + bros) / (lb * 2.0)); +} /* ----------------- Length-to-Breadth --------------------------*/ -float l_to_b(float ws, fuel_coefs *ptr) - { - float l1, l2, lb ; - l1 = 2.233;//1.411; // ptr->l1 ; - l2 = -0.01031; //0.01745; // ptr->l2 ; - lb = 1.0 + pow(l1 * exp(-l2 * ws) - l1, 2.0) ; +float +l_to_b(float ws, fuel_coefs* ptr) +{ + float l1, l2, lb; + l1 = 2.233; // 1.411; // ptr->l1 ; + l2 = -0.01031; // 0.01745; // ptr->l2 ; + lb = 1.0 + pow(l1 * exp(-l2 * ws) - l1, 2.0); return lb; - } +} /* ----------------- Back Rate of Spread --------------------------*/ -float backfire_ros_k(main_outs *at, snd_outs *sec) - { - float hb, bros, lb ; - //lb = l_to_b(data->fueltype,at->wsv) ; - lb = sec->lb ; - hb = (lb + sqrt(pow(lb,2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)) ; - - bros = at->rss / hb ; - +float +backfire_ros_k(main_outs* at, snd_outs* sec) +{ + float hb, bros, lb; + // lb = l_to_b(data->fueltype,at->wsv) ; + lb = sec->lb; + hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); + + bros = at->rss / hb; + return bros * (bros >= 0); - } +} -float slope_effect(float elev_i, float elev_j, int cellsize) - { - float ps_ij = (elev_j - elev_i) / (cellsize/4.); //cellsize corresponds to the perimeter of the cell +float +slope_effect(float elev_i, float elev_j, int cellsize) +{ + float ps_ij = (elev_j - elev_i) / (cellsize / 4.); // cellsize corresponds to the perimeter of the cell float se; - se = 1. + 0.023322 * ps_ij + 0.00013585 * std::pow(ps_ij, 2) ; - - return se; - } + se = 1. + 0.023322 * ps_ij + 0.00013585 * std::pow(ps_ij, 2); + return se; +} -float flame_length(inputs *data, main_outs *at) //REVISAR ESTA ECUACI�N - { - float ib, fl ; +float +flame_length(inputs* data, main_outs* at) // REVISAR ESTA ECUACI�N +{ + float ib, fl; - ib = at->sfi ; + ib = at->sfi; - fl = 0.0775*pow(ib, 0.46) ; - return fl; - } + fl = 0.0775 * pow(ib, 0.46); + return fl; +} -float angleFL(inputs *data, main_outs *at) - { - float angle, fl, y, ws ; - ws = data->ws ; - fl = at->fl; - y = 10.0 / 36.0 * ws ; +float +angleFL(inputs* data, main_outs* at) +{ + float angle, fl, y, ws; + ws = data->ws; + fl = at->fl; + y = 10.0 / 36.0 * ws; - angle = atan(2.24 * sqrt(fl / pow(y, 2))) ; - return angle; - } + angle = atan(2.24 * sqrt(fl / pow(y, 2))); + return angle; +} -float flame_height(inputs *data, main_outs *at) - { - float fh, phi ; - phi = angleFL(data, at) ; - fh = at->fl * sin(phi) ; - return fh ; - } +float +flame_height(inputs* data, main_outs* at) +{ + float fh, phi; + phi = angleFL(data, at); + fh = at->fl * sin(phi); + return fh; +} -float byram_intensity(inputs* data, main_outs* at) { - float ros,H,wa, ib; +float +byram_intensity(inputs* data, main_outs* at) +{ + float ros, H, wa, ib; ros = at->rss; H = hs[data->nftype][0]; wa = fls_david[data->nftype][0]; - ib = H*wa*ros/60; + ib = H * wa * ros / 60; ib = std::ceil(ib * 100.0) / 100.0; - return ib; //unidad de medida + return ib; // unidad de medida } +bool +fire_type(inputs* data, main_outs* at, int FMC) +{ + float intensity, critical_intensity, cbh; + bool crownFire = false; + intensity = at->sfi; + cbh = cbhs[data->nftype][0]; + // cbh = data->cbh; + critical_intensity = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); + if ((intensity > critical_intensity) && cbh != 0) + crownFire = true; + return crownFire; +} -bool fire_type(inputs *data, main_outs* at,int FMC) - { - float intensity, critical_intensity, cbh; - bool crownFire = false; - intensity = at->sfi; - cbh = cbhs[data->nftype][0]; - //cbh = data->cbh; - critical_intensity = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); - if ((intensity > critical_intensity) && cbh != 0) crownFire = true; - return crownFire ; - } - - -float crownfractionburn(inputs* data, main_outs* at,int FMC) { //generar output de cfb +float +crownfractionburn(inputs* data, main_outs* at, int FMC) +{ // generar output de cfb float a, cbd, ros, ros0, H, wa, i0, cbh, cfb; cbh = cbhs[data->nftype][0]; i0 = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); @@ -703,24 +703,26 @@ float crownfractionburn(inputs* data, main_outs* at,int FMC) { //generar output cbd = cbds[data->nftype][0]; ros0 = 60 * i0 / (H * wa); ros = at->rss; - if (cbd != 0) { + if (cbd != 0) + { a = -log(0.1) / (0.9 * (3.0 / cbd - ros0)); } - else { - a=0.23; + else + { + a = 0.23; } - cfb=1 - exp(-a * (ros - ros0)); + cfb = 1 - exp(-a * (ros - ros0)); return cfb; } - - -float active_rate_of_spreadPL04(inputs* data, main_outs *at) //En KITRAL SE USA PL04 +float +active_rate_of_spreadPL04(inputs* data, + main_outs* at) // En KITRAL SE USA PL04 { float p1, p2, p3, ws, tmp, rh, ch, fmc, fch, fv, ps, ros_active, rospl04, fp, ros_final, ros; - //se = slope_effect(inp) ; + // se = slope_effect(inp) ; ws = data->ws; tmp = data->tmp; rh = data->rh; @@ -730,32 +732,38 @@ float active_rate_of_spreadPL04(inputs* data, main_outs *at) //En KITRAL SE USA p3 = 13.8; ch = (-2.97374 + 0.262 * rh - 0.00982 * tmp); - fmc = 0.002712 * 60; //factor de propagacion en m/min de PL04 - fch = (389.1624 + 14.3 * ch + 0.02 * pow(ch, 2.0)) / (3.559 + 1.6615 * ch + 2.62392 * pow(ch, 2.0)); //es -14.3 segun el libro + fmc = 0.002712 * 60; // factor de propagacion en m/min de PL04 + fch = (389.1624 + 14.3 * ch + 0.02 * pow(ch, 2.0)) + / (3.559 + 1.6615 * ch + 2.62392 * pow(ch, 2.0)); // es -14.3 segun el libro fv = p1 * exp(-p2 * ws * 0.4) + p3; - //fp = 1.0 + 0.023322 * data->ps + 0.00013585 * pow(data->ps, 2.0); - if (ps==0){ - rospl04 = fmc*fch*(fv); + // fp = 1.0 + 0.023322 * data->ps + 0.00013585 * pow(data->ps, 2.0); + if (ps == 0) + { + rospl04 = fmc * fch * (fv); } - else{ - rospl04 = fmc*fch*(fv+ps); + else + { + rospl04 = fmc * fch * (fv + ps); } - ros_active = 3.34 * rospl04; //if rac*cbd>3.0, aplicar ros_final=3.34*rospl04 + ros_active = 3.34 * rospl04; // if rac*cbd>3.0, aplicar + // ros_final=3.34*rospl04 return ros_active; } -float final_rate_of_spreadPL04(main_outs* at) //En KITRAL SE USA PL04 +float +final_rate_of_spreadPL04(main_outs* at) // En KITRAL SE USA PL04 { - float ros_active, ros_final, ros; + float ros_active, ros_final, ros; ros = at->rss; - ros_active=at->ros_active; + ros_active = at->ros_active; ros_final = ros + at->cfb * (ros_active - ros); return ros_final; } -bool checkActive(inputs * data,main_outs* at, int FMC) //En KITRAL SE USA PL04 +bool +checkActive(inputs* data, main_outs* at, int FMC) // En KITRAL SE USA PL04 { - float ros_critical, cbd,H,wa,i0,cbh; + float ros_critical, cbd, H, wa, i0, cbh; bool active; cbh = cbhs[data->nftype][0]; i0 = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); @@ -766,226 +774,252 @@ bool checkActive(inputs * data,main_outs* at, int FMC) //En KITRAL SE USA PL04 cbd = cbds[data->nftype][0]; - active=cbd*ros_critical>=3; + active = cbd * ros_critical >= 3; return active; } +float +backfire_ros10_k(fire_struc* hptr, snd_outs* sec) +{ + float hb, bros, lb; + lb = sec->lb; + hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); - -float backfire_ros10_k(fire_struc *hptr, snd_outs *sec) - { - float hb, bros, lb ; - lb = sec->lb ; - hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)) ; + bros = hptr->ros / hb; - bros = hptr->ros / hb ; - return bros; - } +} /*** * fire_struc *hptr: headstruct * fire_struc *fptr: flankstruct * fire_struc *bptr: backstruct */ - void calculate_k(inputs *data, inputs *head,int cellsize, fuel_coefs * ptr,arguments *args, main_outs *at, snd_outs *sec, fire_struc *hptr, fire_struc *fptr,fire_struc *bptr, bool & activeCrown) +void +calculate_k(inputs* data, + inputs* head, + int cellsize, + fuel_coefs* ptr, + arguments* args, + main_outs* at, + snd_outs* sec, + fire_struc* hptr, + fire_struc* fptr, + fire_struc* bptr, + bool& activeCrown) { - // Hack: Initialize coefficients + // Hack: Initialize coefficients setup_const(); - // Aux - float ros, bros, lb, fros; + // Aux + float ros, bros, lb, fros; int FMC; - bool crownFire=false; - at->cfb=0; + bool crownFire = false; + at->cfb = 0; // Populate fuel coefs struct - if (args->verbose){ - std::cout << "Populate fuel types " << std::endl; - std::cout << "NfTypes:" << data->nftype << std::endl; - } - // FMC = Fuel Moisture Content - FMC=args->FMC; - ptr->nftype = data->nftype; + if (args->verbose) + { + std::cout << "Populate fuel types " << std::endl; + std::cout << "NfTypes:" << data->nftype << std::endl; + } + // FMC = Fuel Moisture Content + FMC = args->FMC; + ptr->nftype = data->nftype; ptr->fmc = fmcs[data->nftype][0]; ptr->cbh = cbhs[data->nftype][0]; - //cout << " cbh " << ptr->cbh << "\n"; + // cout << " cbh " << ptr->cbh << "\n"; ptr->fl = fls_david[data->nftype][0]; - //cout << " fl " << ptr->fl << "\n"; + // cout << " fl " << ptr->fl << "\n"; ptr->h = hs[data->nftype][0]; - //cout << " h " << ptr->h << "\n"; - float elevation_origin=data->elev; - float elevation_destiny=head->elev; - at->se=slope_effect(elevation_origin,elevation_destiny,cellsize); + // cout << " h " << ptr->h << "\n"; + float elevation_origin = data->elev; + float elevation_destiny = head->elev; + at->se = slope_effect(elevation_origin, elevation_destiny, cellsize); // Step 1: Calculate HROS (surface) at->rss = rate_of_spread_k(data, ptr, at); - hptr->rss = at->rss ; + hptr->rss = at->rss; // Step 2: Calculate Length-to-breadth - sec->lb = l_to_b(data->ws, ptr) ; - + sec->lb = l_to_b(data->ws, ptr); + // Step 3: Calculate BROS (surface) - bptr->rss = backfire_ros_k(at, sec) ; - + bptr->rss = backfire_ros_k(at, sec); + // Step 4: Calculate central FROS (surface) fptr->rss = flankfire_ros_k(hptr->rss, bptr->rss, sec->lb); - + // Step 5: Ellipse components - at->a = (hptr->rss + bptr->rss) / 2. ; - at->b = (hptr->rss + bptr->rss) / (2. * sec->lb) ; - at->c = (hptr->rss - bptr->rss) / 2. ; - + at->a = (hptr->rss + bptr->rss) / 2.; + at->b = (hptr->rss + bptr->rss) / (2. * sec->lb); + at->c = (hptr->rss - bptr->rss) / 2.; + // Step 6: Byram Intensity - at->sfi = byram_intensity(data,at); + at->sfi = byram_intensity(data, at); // Step 7: Flame Length at->fl = flame_length(data, at); - + // Step 8: Flame angle - at->angle = angleFL(data, at) ; - - // Step 9: Flame Height - at->fh = flame_height(data, at) ; - - - // Step 10: Criterion for Crown Fire Initiation (no init if user does not want to include it) - if (args->AllowCROS && cbhs[data->nftype][0]!=0) { - if (activeCrown){ //si el fuego esta activo en copas chequeamos condiciones - at->ros_active=active_rate_of_spreadPL04(data,at); - if (!checkActive(data,at,FMC)){ - activeCrown=false; - } + at->angle = angleFL(data, at); + + // Step 9: Flame Height + at->fh = flame_height(data, at); + + // Step 10: Criterion for Crown Fire Initiation (no init if user does not + // want to include it) + if (args->AllowCROS && cbhs[data->nftype][0] != 0) + { + if (activeCrown) + { // si el fuego esta activo en copas chequeamos condiciones + at->ros_active = active_rate_of_spreadPL04(data, at); + if (!checkActive(data, at, FMC)) + { + activeCrown = false; + } } - else{ + else + { crownFire = fire_type(data, at, FMC); - if (args->verbose) { + if (args->verbose) + { cout << "Checking crown Fire conditions " << crownFire << "\n"; - } + } } } - else { + else + { crownFire = false; - activeCrown=false; + activeCrown = false; } - // If we have Crown fire, update the ROSs - if (crownFire){ - at->ros_active=active_rate_of_spreadPL04(data,at); - at->cfb = crownfractionburn(data, at,FMC); - - hptr->ros = final_rate_of_spreadPL04(at) ; - at->rss=hptr->ros; - bptr->ros = backfire_ros10_k(hptr,sec) ; - fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb) ; - - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n" ; - cout << "bptr->ros = " << bptr->ros << "\n" ; - cout << "fptr->ros = " << fptr->ros << "\n" ; - } - - at->a = (hptr->ros + bptr->ros) / 2. ; - at->b = (hptr->ros + bptr->ros) / (2. * sec->lb) ; - at->c = (hptr->ros - bptr->rss) / 2 ; - at->crown = 1; - activeCrown=true; + // If we have Crown fire, update the ROSs + if (crownFire) + { + at->ros_active = active_rate_of_spreadPL04(data, at); + at->cfb = crownfractionburn(data, at, FMC); + + hptr->ros = final_rate_of_spreadPL04(at); + at->rss = hptr->ros; + bptr->ros = backfire_ros10_k(hptr, sec); + fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb); + + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } + at->a = (hptr->ros + bptr->ros) / 2.; + at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); + at->c = (hptr->ros - bptr->rss) / 2; + at->crown = 1; + activeCrown = true; } - else if (activeCrown){ - at->cfb = crownfractionburn(data, at,FMC); //lo calculamos igual porque lo necesitamos para el output - hptr->ros = at->ros_active ; - at->rss=hptr->ros; - bptr->ros = backfire_ros10_k(hptr,sec) ; - fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb) ; - - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n" ; - cout << "bptr->ros = " << bptr->ros << "\n" ; - cout << "fptr->ros = " << fptr->ros << "\n" ; - } - - at->a = (hptr->ros + bptr->ros) / 2. ; - at->b = (hptr->ros + bptr->ros) / (2. * sec->lb) ; - at->c = (hptr->ros - bptr->rss) / 2 ; - at->crown = 1; - //std::cout << "ros_activo: " <ros << std::endl; + else if (activeCrown) + { + at->cfb = crownfractionburn(data, at, + FMC); // lo calculamos igual porque lo necesitamos para el output + hptr->ros = at->ros_active; + at->rss = hptr->ros; + bptr->ros = backfire_ros10_k(hptr, sec); + fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb); + + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } + at->a = (hptr->ros + bptr->ros) / 2.; + at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); + at->c = (hptr->ros - bptr->rss) / 2; + at->crown = 1; + // std::cout << "ros_activo: " <ros << std::endl; } - - // Otherwise, use the surface values - else{ - at->crown=0; - hptr->ros = hptr->rss ; - bptr->ros = bptr->rss ; - fptr->ros = fptr->rss ; - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n" ; - cout << "bptr->ros = " << bptr->ros << "\n" ; - cout << "fptr->ros = " << fptr->ros << "\n" ; - } + // Otherwise, use the surface values + else + { + at->crown = 0; + hptr->ros = hptr->rss; + bptr->ros = bptr->rss; + fptr->ros = fptr->rss; + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } } - if (args->verbose){ - cout << "--------------- Inputs --------------- \n" ; - cout << "ws = " << data->ws << "\n" ; - cout << "coef data->cbh = " << data->cbh << "\n" ; - cout << "coef ptr->fmc = " << ptr->fmc << "\n" ; - cout << "coef ptr->cbh = " << ptr->cbh << "\n" ; - cout << "coef ptr->fl = " << ptr->fl << "\n" ; - cout << "coef ptr->h = " << ptr->h << "\n" ; - //cout << "coef ptr->q2 = " << ptr->q2 << "\n" ; - //cout << "coef ptr->q3 = " << ptr->q3 << "\n" ; - cout << "\n" ; - - cout << "---------------- Outputs --------------- \n" ; - cout << "at->rss = " << at->rss << "\n" ; - cout << "hptr->rss = " << hptr->rss << "\n" ; - cout << "lb = " << sec->lb << "\n" ; - cout << "bptr->rss = " << bptr->rss << "\n" ; - cout << "fptr->rss = " << fptr->rss << "\n" ; - cout << "axis a = " << at->a << "\n" ; - cout << "axis b = " << at->b << "\n" ; - cout << "axis c = " << at->c << "\n" ; - cout << "fl = " << at->fl << "\n"; - cout << "angle = " << at->angle << "\n"; - cout << "fh = " << at->fh << "\n"; - cout << "Crown Fire = " << crownFire << "\n"; - } - + if (args->verbose) + { + cout << "--------------- Inputs --------------- \n"; + cout << "ws = " << data->ws << "\n"; + cout << "coef data->cbh = " << data->cbh << "\n"; + cout << "coef ptr->fmc = " << ptr->fmc << "\n"; + cout << "coef ptr->cbh = " << ptr->cbh << "\n"; + cout << "coef ptr->fl = " << ptr->fl << "\n"; + cout << "coef ptr->h = " << ptr->h << "\n"; + // cout << "coef ptr->q2 = " << ptr->q2 << "\n" ; + // cout << "coef ptr->q3 = " << ptr->q3 << "\n" ; + cout << "\n"; + + cout << "---------------- Outputs --------------- \n"; + cout << "at->rss = " << at->rss << "\n"; + cout << "hptr->rss = " << hptr->rss << "\n"; + cout << "lb = " << sec->lb << "\n"; + cout << "bptr->rss = " << bptr->rss << "\n"; + cout << "fptr->rss = " << fptr->rss << "\n"; + cout << "axis a = " << at->a << "\n"; + cout << "axis b = " << at->b << "\n"; + cout << "axis c = " << at->c << "\n"; + cout << "fl = " << at->fl << "\n"; + cout << "angle = " << at->angle << "\n"; + cout << "fh = " << at->fh << "\n"; + cout << "Crown Fire = " << crownFire << "\n"; + } } -void determine_destiny_metrics_k(inputs* data, fuel_coefs* ptr,arguments *args ,main_outs* metrics) { - // Hack: Initialize coefficients +void +determine_destiny_metrics_k(inputs* data, fuel_coefs* ptr, arguments* args, main_outs* metrics) +{ + // Hack: Initialize coefficients setup_const(); // Aux - float ros=0, bros=0, lb=0, fros=0; - int FMC=args->FMC; + float ros = 0, bros = 0, lb = 0, fros = 0; + int FMC = args->FMC; bool crownFire = false; - metrics->cfb=0; - //ptr->q1 = q_coeff[data->nftype][0]; - //ptr->q2 = q_coeff[data->nftype][1]; - //ptr->q3 = q_coeff[data->nftype][2]; + metrics->cfb = 0; + // ptr->q1 = q_coeff[data->nftype][0]; + // ptr->q2 = q_coeff[data->nftype][1]; + // ptr->q3 = q_coeff[data->nftype][2]; ptr->nftype = data->nftype; // Step 6: Byram Intensity - metrics->sfi = byram_intensity(data,metrics); + metrics->sfi = byram_intensity(data, metrics); // Step 7: Flame Length metrics->fl = flame_length(data, metrics); - // Step 10: Criterion for Crown Fire Initiation (no init if user does not want to include it) - if (args->AllowCROS) { + // Step 10: Criterion for Crown Fire Initiation (no init if user does not + // want to include it) + if (args->AllowCROS) + { crownFire = fire_type(data, metrics, FMC); - if (crownFire){ - metrics->cfb = crownfractionburn(data, metrics,FMC); - + if (crownFire) + { + metrics->cfb = crownfractionburn(data, metrics, FMC); } - if (args->verbose) { + if (args->verbose) + { cout << "Checking crown Fire conditions " << crownFire << "\n"; } } - else { + else + { crownFire = false; } metrics->crown = int(crownFire); - } diff --git a/Cell2Fire/FuelModelKitral.h b/Cell2Fire/FuelModelKitral.h index 6adc8b38..c28cac5d 100644 --- a/Cell2Fire/FuelModelKitral.h +++ b/Cell2Fire/FuelModelKitral.h @@ -1,66 +1,76 @@ #ifndef FUELMODELKITRAL #define FUELMODELKITRAL -#include "ReadArgs.h" #include "Cells.h" +#include "ReadArgs.h" #include #include #include #include -#include #include -#include #include +#include #include - - /* - Functions - */ +/* + Functions +*/ // Initialize coefficients void setup_const(); - // Calculate flank fire -float flankfire_ros_k(float ros, float bros, float lb) ; +// Calculate flank fire +float flankfire_ros_k(float ros, float bros, float lb); // Calculate rate of spread -float rate_of_spread_k(inputs *data, fuel_coefs *ptr, main_outs *at) ; +float rate_of_spread_k(inputs* data, fuel_coefs* ptr, main_outs* at); // Length-to-Breadth ratio float l_to_b(float ws); // BROS -float backfire_ros_k(main_outs *at, snd_outs *sec) ; +float backfire_ros_k(main_outs* at, snd_outs* sec); // Flame length [m]) -float flame_length(inputs *data, main_outs *at); +float flame_length(inputs* data, main_outs* at); // Angle of the flame w.r.t. horizontal surface (Putnam's) -float angleFL(inputs *data, main_outs *at) ; +float angleFL(inputs* data, main_outs* at); -// Transformation from FL to FH using angle -float flame_height(inputs* data, main_outs *at); +// Transformation from FL to FH using angle +float flame_height(inputs* data, main_outs* at); -//byram intensity +// byram intensity float byram_intensity(inputs* data, main_outs* at); // Type of fire (Crown = 1, SROS = 0) -bool fire_type(inputs *data, main_outs* atr, int FMC) ; -//Active crown -bool checkActive(inputs * data,main_outs* at, int FMC); +bool fire_type(inputs* data, main_outs* atr, int FMC); +// Active crown +bool checkActive(inputs* data, main_outs* at, int FMC); // CROS adjustements -float final_rate_of_spreadPL04(main_outs* at) ; -float active_rate_of_spreadPL04(inputs* data,main_outs *at); //En KITRAL SE USA PL04 -float crownfractionburn(inputs* data, main_outs* at,int FMC); +float final_rate_of_spreadPL04(main_outs* at); +float active_rate_of_spreadPL04(inputs* data, + main_outs* at); // En KITRAL SE USA PL04 +float crownfractionburn(inputs* data, main_outs* at, int FMC); -// Back fire with CROS -float backfire_ros10_k(fire_struc *hptr, snd_outs *sec) ; +// Back fire with CROS +float backfire_ros10_k(fire_struc* hptr, snd_outs* sec); // Slope effect float slope_effect(float elev_i, float elev_j, int cellsize); -// Main function to populate spread outputs based on inputs provided from main class -void calculate_k(inputs *data, inputs *head , int cellsize, fuel_coefs * ptr, arguments *args,main_outs *at, snd_outs *sec, fire_struc *hptr, fire_struc *fptr,fire_struc *bptr,bool & activeCrown); - -void determine_destiny_metrics_k(inputs* data, fuel_coefs* ptr,arguments *args, main_outs* at); +// Main function to populate spread outputs based on inputs provided from main +// class +void calculate_k(inputs* data, + inputs* head, + int cellsize, + fuel_coefs* ptr, + arguments* args, + main_outs* at, + snd_outs* sec, + fire_struc* hptr, + fire_struc* fptr, + fire_struc* bptr, + bool& activeCrown); + +void determine_destiny_metrics_k(inputs* data, fuel_coefs* ptr, arguments* args, main_outs* at); #endif diff --git a/Cell2Fire/FuelModelSpain.cpp b/Cell2Fire/FuelModelSpain.cpp index 7523cc8d..16abae9a 100644 --- a/Cell2Fire/FuelModelSpain.cpp +++ b/Cell2Fire/FuelModelSpain.cpp @@ -1,15 +1,14 @@ #include "FuelModelSpain.h" -#include "ReadArgs.h" #include "Cells.h" +#include "ReadArgs.h" +#include #include #include -#include #include #include -#include #include -#include #include +#include #include using namespace std; @@ -21,2570 +20,2606 @@ std::unordered_map> p_coeff; std::unordered_map> q_coeff; std::unordered_map> fm_parameters; - /** * - * @param scenario Weather scenario used in the simulation. It determines the fuel model coefficients. + * @param scenario Weather scenario used in the simulation. It determines the + * fuel model coefficients. */ -void initialize_coeff(int scenario) +void +initialize_coeff(int scenario) { - if (scenario == 1){ - // Populate them - // FM101 - int F101 = 101; - std::vector p_101; - p_101.push_back(2.575); - p_101.push_back(0.6665); - p_101.push_back(0.1096); - - std::vector q_101; - q_101.push_back(-0.516); - q_101.push_back(0.288); - q_101.push_back(0.8972); - - p_coeff.insert(std::make_pair(F101, p_101)); - q_coeff.insert(std::make_pair(F101, q_101)); - - - // FM 102 - int F102 = 102; - std::vector p_102; - p_102.push_back(0.4218); - p_102.push_back(0.2915); - p_102.push_back(0.01212); - - std::vector q_102; - q_102.push_back(-1.307); - q_102.push_back(0.1322); - q_102.push_back(1.887); - - p_coeff.insert(std::make_pair(F102, p_102)); - q_coeff.insert(std::make_pair(F102, q_102)); - - // FM 103 - int F103 = 103; - std::vector p_103; - p_103.push_back(0.1638); - p_103.push_back(0.2095); - p_103.push_back(0.007809); - - std::vector q_103; - q_103.push_back(-1.572); - q_103.push_back(0.1068); - q_103.push_back(2.409); - - p_coeff.insert(std::make_pair(F103, p_103)); - q_coeff.insert(std::make_pair(F103, q_103)); - - - // FM 104 - int F104 = 104; - std::vector p_104; - p_104.push_back(0.07138); - p_104.push_back(0.1417); - p_104.push_back(0.002243); - - std::vector q_104; - q_104.push_back(-2.391); - q_104.push_back(0.05973); - q_104.push_back(3.334); - - p_coeff.insert(std::make_pair(F104, p_104)); - q_coeff.insert(std::make_pair(F104, q_104)); - - // FM 105 - int F105 = 105; - std::vector p_105; - p_105.push_back(0.03548); - p_105.push_back(0.07829); - p_105.push_back(0.001524); - - std::vector q_105; - q_105.push_back(-3.075); - q_105.push_back(0.03373); - q_105.push_back(4.391); - - p_coeff.insert(std::make_pair(F105, p_105)); - q_coeff.insert(std::make_pair(F105, q_105)); - - // FM 106 - int F106 = 106; - std::vector p_106; - p_106.push_back(0.02469); - p_106.push_back(0.08049); - p_106.push_back(0.0008245); - - std::vector q_106; - q_106.push_back(-4.006); - q_106.push_back(0.03019); - q_106.push_back(5.463); - - p_coeff.insert(std::make_pair(F106, p_106)); - q_coeff.insert(std::make_pair(F106, q_106)); - - // FM 107 - int F107 = 107; - std::vector p_107; - p_107.push_back(0.02329); - p_107.push_back(0.09086); - p_107.push_back(0.0009262); - - std::vector q_107; - q_107.push_back(-3.979); - q_107.push_back(0.03746); - q_107.push_back(5.587); - - p_coeff.insert(std::make_pair(F107, p_107)); - q_coeff.insert(std::make_pair(F107, q_107)); - - // FM 108 - int F108 = 108; - std::vector p_108; - p_108.push_back(0.02111); - p_108.push_back(0.07793); - p_108.push_back(0.001174); - - std::vector q_108; - q_108.push_back(-3.842); - q_108.push_back(0.03855); - q_108.push_back(5.817); - - p_coeff.insert(std::make_pair(F108, p_108)); - q_coeff.insert(std::make_pair(F108, q_108)); - - // FM 121 - int F121 = 121; - std::vector p_121; - p_121.push_back(0.613); - p_121.push_back(0.2139); - p_121.push_back(0.0187); - - std::vector q_121; - q_121.push_back(-1.267); - q_121.push_back(0.0922); - q_121.push_back(1.845); - - p_coeff.insert(std::make_pair(F121, p_121)); - q_coeff.insert(std::make_pair(F121, q_121)); - - // FM 122 - int F122 = 122; - std::vector p_122; - p_122.push_back(0.195); - p_122.push_back(0.1243); - p_122.push_back(0.006478); - - std::vector q_122; - q_122.push_back(-1.939); - q_122.push_back(0.05084); - q_122.push_back(2.706); - - p_coeff.insert(std::make_pair(F122, p_122)); - q_coeff.insert(std::make_pair(F122, q_122)); - - // FM 123 - int F123 = 123; - std::vector p_123; - p_123.push_back(0.06515); - p_123.push_back(0.07833); - p_123.push_back(0.002831); - - std::vector q_123; - q_123.push_back(-2.646); - q_123.push_back(0.03365); - q_123.push_back(3.788); - - p_coeff.insert(std::make_pair(F123, p_123)); - q_coeff.insert(std::make_pair(F123, q_123)); - - // FM 124 - int F124 = 124; - std::vector p_124; - p_124.push_back(0.07867); - p_124.push_back(0.07788); - p_124.push_back(0.003431); - - std::vector q_124; - q_124.push_back(-3.508); - q_124.push_back(0.03246); - q_124.push_back(5.098); - - p_coeff.insert(std::make_pair(F124, p_124)); - q_coeff.insert(std::make_pair(F124, q_124)); - - // FM 142 - int F142 = 142; - std::vector p_142; - p_142.push_back(0.3505); - p_142.push_back(0.07768); - p_142.push_back(0.01498); - - std::vector q_142; - q_142.push_back(-1.959); - q_142.push_back(0.0322); - q_142.push_back(2.819); - - p_coeff.insert(std::make_pair(F142, p_142)); - q_coeff.insert(std::make_pair(F142, q_142)); - - // FM 143 - int F143 = 143; - std::vector p_143; - p_143.push_back(1.748); - p_143.push_back(0.1589); - p_143.push_back(0.08249); - - std::vector q_143; - q_143.push_back(-0.938); - q_143.push_back(0.07674); - q_143.push_back(1.479); - - p_coeff.insert(std::make_pair(F143, p_143)); - q_coeff.insert(std::make_pair(F143, q_143)); - - // FM 144 - int F144 = 144; - std::vector p_144; - p_144.push_back(0.08116); - p_144.push_back(0.07849); - p_144.push_back(0.003353); - - std::vector q_144; - q_144.push_back(-2.452); - q_144.push_back(0.03347); - q_144.push_back(3.486); - - p_coeff.insert(std::make_pair(F144, p_144)); - q_coeff.insert(std::make_pair(F144, q_144)); - - // FM 145 - int F145 = 145; - std::vector p_145; - p_145.push_back(0.0483); - p_145.push_back(0.0781); - p_145.push_back(0.002783); - - std::vector q_145; - q_145.push_back(-2.796); - q_145.push_back(0.04029); - q_145.push_back(4.24); - - p_coeff.insert(std::make_pair(F145, p_145)); - q_coeff.insert(std::make_pair(F145, q_145)); - - // FM 146 - int F146 = 146; - std::vector p_146; - p_146.push_back(0.1248); - p_146.push_back(0.07783); - p_146.push_back(0.007999); - - std::vector q_146; - q_146.push_back(-2.121); - q_146.push_back(0.04111); - q_146.push_back(3.327); - - p_coeff.insert(std::make_pair(F146, p_146)); - q_coeff.insert(std::make_pair(F146, q_146)); - - // FM 146 - int F147 = 147; - std::vector p_147; - p_147.push_back(0.07431); - p_147.push_back(0.07791); - p_147.push_back(0.004384); - - std::vector q_147; - q_147.push_back(-2.668); - q_147.push_back(0.04027); - q_147.push_back(4.089); - - p_coeff.insert(std::make_pair(F147, p_147)); - q_coeff.insert(std::make_pair(F147, q_147)); - - // FM 148 - int F148 = 148; - std::vector p_148; - p_148.push_back(0.1238); - p_148.push_back(0.07772); - p_148.push_back(0.00647); - - std::vector q_148; - q_148.push_back(-2.506); - q_148.push_back(0.03664); - q_148.push_back(3.756); - - p_coeff.insert(std::make_pair(F148, p_148)); - q_coeff.insert(std::make_pair(F148, q_148)); - - // FM 149 - int F149 = 149; - std::vector p_149; - p_149.push_back(0.0667); - p_149.push_back(0.07779); - p_149.push_back(0.003506); - - std::vector q_149; - q_149.push_back(-3.209); - q_149.push_back(0.03641); - q_149.push_back(4.839); - - p_coeff.insert(std::make_pair(F149, p_149)); - q_coeff.insert(std::make_pair(F149, q_149)); - - // FM 161 - int F161 = 161; - std::vector p_161; - p_161.push_back(2.616); - p_161.push_back(0.1744); - p_161.push_back(0.1004); - - std::vector q_161; - q_161.push_back(-0.867); - q_161.push_back(0.08398); - q_161.push_back(1.326); - - p_coeff.insert(std::make_pair(F161, p_161)); - q_coeff.insert(std::make_pair(F161, q_161)); - - // FM 162 - int F162 = 162; - std::vector p_162; - p_162.push_back(0.6444); - p_162.push_back(0.1574); - p_162.push_back(0.02134); - - std::vector q_162; - q_162.push_back(-1.347); - q_162.push_back(0.0649); - q_162.push_back(1.958); - - p_coeff.insert(std::make_pair(F162, p_162)); - q_coeff.insert(std::make_pair(F162, q_162)); - - // FM 163 - int F163 = 163; - std::vector p_163; - p_163.push_back(0.08987); - p_163.push_back(0.07819); - p_163.push_back(0.003927); - - std::vector q_163; - q_163.push_back(-2.419); - q_163.push_back(0.03439); - q_163.push_back(3.493); - - p_coeff.insert(std::make_pair(F163, p_163)); - q_coeff.insert(std::make_pair(F163, q_163)); - - // FM 164 - int F164 = 164; - std::vector p_164; - p_164.push_back(0.1843); - p_164.push_back(0.07912); - p_164.push_back(0.005477); - - std::vector q_164; - q_164.push_back(-2.661); - q_164.push_back(0.0271); - q_164.push_back(3.579); - - p_coeff.insert(std::make_pair(F164, p_164)); - q_coeff.insert(std::make_pair(F164, q_164)); - - // FM 165 - int F165 = 165; - std::vector p_165; - p_165.push_back(0.3291); - p_165.push_back(0.07679); - p_165.push_back(0.02046); - - std::vector q_165; - q_165.push_back(-1.891); - q_165.push_back(0.03665); - q_165.push_back(3.027); - - p_coeff.insert(std::make_pair(F165, p_165)); - q_coeff.insert(std::make_pair(F165, q_165)); - - // FM 181 - int F181 = 181; - std::vector p_181; - p_181.push_back(14.96); - p_181.push_back(0.401); - p_181.push_back(1.983); - - std::vector q_181; - q_181.push_back(-0.1525); - q_181.push_back(0.4018); - q_181.push_back(0.4484); - - p_coeff.insert(std::make_pair(F181, p_181)); - q_coeff.insert(std::make_pair(F181, q_181)); - - // FM 182 - int F182 = 182; - std::vector p_182; - p_182.push_back(11.01); - p_182.push_back(0.3366); - p_182.push_back(0.7639); - - std::vector q_182; - q_182.push_back(-0.3704); - q_182.push_back(0.202); - q_182.push_back(0.6365); - - p_coeff.insert(std::make_pair(F182, p_182)); - q_coeff.insert(std::make_pair(F182, q_182)); - - // FM 183 - int F183 = 183; - std::vector p_183; - p_183.push_back(10.09); - p_183.push_back(0.3454); - p_183.push_back(0.584); - - std::vector q_183; - q_183.push_back(-0.4398); - q_183.push_back(0.1448); - q_183.push_back(0.7804); - - p_coeff.insert(std::make_pair(F183, p_183)); - q_coeff.insert(std::make_pair(F183, q_183)); - - // FM 185 - int F185 = 185; - std::vector p_185; - p_185.push_back(2.195); - p_185.push_back(0.1807); - p_185.push_back(0.07939); - - std::vector q_185; - q_185.push_back(-0.8838); - q_185.push_back(0.08234); - q_185.push_back(1.368); - - p_coeff.insert(std::make_pair(F185, p_185)); - q_coeff.insert(std::make_pair(F185, q_185)); - - // FM 186 - int F186 = 186; - std::vector p_186; - p_186.push_back(0.9183); - p_186.push_back(0.1224); - p_186.push_back(0.02969); - - std::vector q_186; - q_186.push_back(-1.306); - q_186.push_back(0.04578); - q_186.push_back(1.908); - - p_coeff.insert(std::make_pair(F186, p_186)); - q_coeff.insert(std::make_pair(F186, q_186)); - - // FM 188 - int F188 = 188; - std::vector p_188; - p_188.push_back(0.4789); - p_188.push_back(0.07735); - p_188.push_back(0.0195); - - std::vector q_188; - q_188.push_back(-1.68); - q_188.push_back(0.02617); - q_188.push_back(2.451); - - p_coeff.insert(std::make_pair(F188, p_188)); - q_coeff.insert(std::make_pair(F188, q_188)); - - // FM 189 - int F189 = 189; - std::vector p_189; - p_189.push_back(0.3229); - p_189.push_back(0.07716); - p_189.push_back(0.01346); - - std::vector q_189; - q_189.push_back(-1.916); - q_189.push_back(0.02961); - q_189.push_back(2.816); - - p_coeff.insert(std::make_pair(F189, p_189)); - q_coeff.insert(std::make_pair(F189, q_189)); - } - - if (scenario == 2){ - // Populate them - // FM 101 - int F101 = 101; - std::vector p_101; - p_101.push_back(4.941); - p_101.push_back(0.7086); - p_101.push_back(0.2124); - - std::vector q_101; - q_101.push_back(-0.4535); - q_101.push_back(0.2682); - q_101.push_back(0.777); - - p_coeff.insert(std::make_pair(F101, p_101)); - q_coeff.insert(std::make_pair(F101, q_101)); - - // FM 102 - int F102 = 102; - std::vector p_102; - p_102.push_back(0.8112); - p_102.push_back(0.3045); - p_102.push_back(0.02528); - - std::vector q_102; - q_102.push_back(-1.036); - q_102.push_back(0.1385); - q_102.push_back(1.561); - - p_coeff.insert(std::make_pair(F102, p_102)); - q_coeff.insert(std::make_pair(F102, q_102)); - - // FM 103 - int F103 = 103; - std::vector p_103; - p_103.push_back(0.3609); - p_103.push_back(0.2318); - p_103.push_back(0.01738); - - std::vector q_103; - q_103.push_back(-1.273); - q_103.push_back(0.1135); - q_103.push_back(1.966); - - p_coeff.insert(std::make_pair(F103, p_103)); - q_coeff.insert(std::make_pair(F103, q_103)); - - - // FM 104 - int F104 = 104; - std::vector p_104; - p_104.push_back(0.1486); - p_104.push_back(0.153); - p_104.push_back(0.004652); - - std::vector q_104; - q_104.push_back(-1.98); - q_104.push_back(0.06712); - q_104.push_back(2.744); - - p_coeff.insert(std::make_pair(F104, p_104)); - q_coeff.insert(std::make_pair(F104, q_104)); - - // FM 105 - int F105 = 105; - std::vector p_105; - p_105.push_back(0.0681); - p_105.push_back(0.07832); - p_105.push_back(0.002926); - - std::vector q_105; - q_105.push_back(-2.578); - q_105.push_back(0.03345); - q_105.push_back(3.694); - - p_coeff.insert(std::make_pair(F105, p_105)); - q_coeff.insert(std::make_pair(F105, q_105)); - - // FM 106 - int F106 = 106; - std::vector p_106; - p_106.push_back(0.04896); - p_106.push_back(0.07908); - p_106.push_back(0.001631); - - std::vector q_106; - q_106.push_back(-3.334); - q_106.push_back(0.03012); - q_106.push_back(4.525); - - p_coeff.insert(std::make_pair(F106, p_106)); - q_coeff.insert(std::make_pair(F106, q_106)); - - // FM 107 - int F107 = 107; - std::vector p_107; - p_107.push_back(0.03528); - p_107.push_back(0.07869); - p_107.push_back(0.001315); - - std::vector q_107; - q_107.push_back(-3.658); - q_107.push_back(0.03158); - q_107.push_back(5.09); - - p_coeff.insert(std::make_pair(F107, p_107)); - q_coeff.insert(std::make_pair(F107, q_107)); - - // FM 108 - int F108 = 108; - std::vector p_108; - p_108.push_back(0.04173); - p_108.push_back(0.07796); - p_108.push_back(0.002318); - - std::vector q_108; - q_108.push_back(-3.209); - q_108.push_back(0.03823); - q_108.push_back(4.86); - - p_coeff.insert(std::make_pair(F108, p_108)); - q_coeff.insert(std::make_pair(F108, q_108)); - - // FM 121 - - int F121 = 121; - std::vector p_121; - p_121.push_back(1.64); - p_121.push_back(0.2795); - p_121.push_back(0.05015); - - std::vector q_121; - q_121.push_back(-0.9854); - q_121.push_back(0.1202); - q_121.push_back(1.392); - - p_coeff.insert(std::make_pair(F121, p_121)); - q_coeff.insert(std::make_pair(F121, q_121)); - - // FM 122 - - int F122 = 122; - std::vector p_122; - p_122.push_back(0.4834); - p_122.push_back(0.1577); - p_122.push_back(0.01499); - - std::vector q_122; - q_122.push_back(-1.486); - q_122.push_back(0.06882); - q_122.push_back(2.084); - - p_coeff.insert(std::make_pair(F122, p_122)); - q_coeff.insert(std::make_pair(F122, q_122)); - - // FM 123 - - int F123 = 123; - std::vector p_123; - p_123.push_back(0.1385); - p_123.push_back(0.08614); - p_123.push_back(0.005977); - - std::vector q_123; - q_123.push_back(-2.108); - q_123.push_back(0.03642); - q_123.push_back(3.029); - - p_coeff.insert(std::make_pair(F123, p_123)); - q_coeff.insert(std::make_pair(F123, q_123)); - - // FM 124 - - int F124 = 124; - std::vector p_124; - p_124.push_back(0.1333); - p_124.push_back(0.07794); - p_124.push_back(0.005812); - - std::vector q_124; - q_124.push_back(-2.963); - q_124.push_back(0.03259); - q_124.push_back(4.318); - - p_coeff.insert(std::make_pair(F124, p_124)); - q_coeff.insert(std::make_pair(F124, q_124)); - - // FM 142 - - int F142 = 142; - std::vector p_142; - p_142.push_back(3.016); - p_142.push_back(0.1405); - p_142.push_back(0.117); - - std::vector q_142; - q_142.push_back(-0.8923); - q_142.push_back(0.06068); - q_142.push_back(1.351); + if (scenario == 1) + { + // Populate them + // FM101 + int F101 = 101; + std::vector p_101; + p_101.push_back(2.575); + p_101.push_back(0.6665); + p_101.push_back(0.1096); + + std::vector q_101; + q_101.push_back(-0.516); + q_101.push_back(0.288); + q_101.push_back(0.8972); + + p_coeff.insert(std::make_pair(F101, p_101)); + q_coeff.insert(std::make_pair(F101, q_101)); + + // FM 102 + int F102 = 102; + std::vector p_102; + p_102.push_back(0.4218); + p_102.push_back(0.2915); + p_102.push_back(0.01212); + + std::vector q_102; + q_102.push_back(-1.307); + q_102.push_back(0.1322); + q_102.push_back(1.887); + + p_coeff.insert(std::make_pair(F102, p_102)); + q_coeff.insert(std::make_pair(F102, q_102)); + + // FM 103 + int F103 = 103; + std::vector p_103; + p_103.push_back(0.1638); + p_103.push_back(0.2095); + p_103.push_back(0.007809); + + std::vector q_103; + q_103.push_back(-1.572); + q_103.push_back(0.1068); + q_103.push_back(2.409); + + p_coeff.insert(std::make_pair(F103, p_103)); + q_coeff.insert(std::make_pair(F103, q_103)); + + // FM 104 + int F104 = 104; + std::vector p_104; + p_104.push_back(0.07138); + p_104.push_back(0.1417); + p_104.push_back(0.002243); + + std::vector q_104; + q_104.push_back(-2.391); + q_104.push_back(0.05973); + q_104.push_back(3.334); + + p_coeff.insert(std::make_pair(F104, p_104)); + q_coeff.insert(std::make_pair(F104, q_104)); + + // FM 105 + int F105 = 105; + std::vector p_105; + p_105.push_back(0.03548); + p_105.push_back(0.07829); + p_105.push_back(0.001524); + + std::vector q_105; + q_105.push_back(-3.075); + q_105.push_back(0.03373); + q_105.push_back(4.391); + + p_coeff.insert(std::make_pair(F105, p_105)); + q_coeff.insert(std::make_pair(F105, q_105)); + + // FM 106 + int F106 = 106; + std::vector p_106; + p_106.push_back(0.02469); + p_106.push_back(0.08049); + p_106.push_back(0.0008245); + + std::vector q_106; + q_106.push_back(-4.006); + q_106.push_back(0.03019); + q_106.push_back(5.463); + + p_coeff.insert(std::make_pair(F106, p_106)); + q_coeff.insert(std::make_pair(F106, q_106)); + + // FM 107 + int F107 = 107; + std::vector p_107; + p_107.push_back(0.02329); + p_107.push_back(0.09086); + p_107.push_back(0.0009262); + + std::vector q_107; + q_107.push_back(-3.979); + q_107.push_back(0.03746); + q_107.push_back(5.587); + + p_coeff.insert(std::make_pair(F107, p_107)); + q_coeff.insert(std::make_pair(F107, q_107)); + + // FM 108 + int F108 = 108; + std::vector p_108; + p_108.push_back(0.02111); + p_108.push_back(0.07793); + p_108.push_back(0.001174); + + std::vector q_108; + q_108.push_back(-3.842); + q_108.push_back(0.03855); + q_108.push_back(5.817); + + p_coeff.insert(std::make_pair(F108, p_108)); + q_coeff.insert(std::make_pair(F108, q_108)); + + // FM 121 + int F121 = 121; + std::vector p_121; + p_121.push_back(0.613); + p_121.push_back(0.2139); + p_121.push_back(0.0187); + + std::vector q_121; + q_121.push_back(-1.267); + q_121.push_back(0.0922); + q_121.push_back(1.845); + + p_coeff.insert(std::make_pair(F121, p_121)); + q_coeff.insert(std::make_pair(F121, q_121)); + + // FM 122 + int F122 = 122; + std::vector p_122; + p_122.push_back(0.195); + p_122.push_back(0.1243); + p_122.push_back(0.006478); + + std::vector q_122; + q_122.push_back(-1.939); + q_122.push_back(0.05084); + q_122.push_back(2.706); + + p_coeff.insert(std::make_pair(F122, p_122)); + q_coeff.insert(std::make_pair(F122, q_122)); + + // FM 123 + int F123 = 123; + std::vector p_123; + p_123.push_back(0.06515); + p_123.push_back(0.07833); + p_123.push_back(0.002831); + + std::vector q_123; + q_123.push_back(-2.646); + q_123.push_back(0.03365); + q_123.push_back(3.788); + + p_coeff.insert(std::make_pair(F123, p_123)); + q_coeff.insert(std::make_pair(F123, q_123)); + + // FM 124 + int F124 = 124; + std::vector p_124; + p_124.push_back(0.07867); + p_124.push_back(0.07788); + p_124.push_back(0.003431); + + std::vector q_124; + q_124.push_back(-3.508); + q_124.push_back(0.03246); + q_124.push_back(5.098); + + p_coeff.insert(std::make_pair(F124, p_124)); + q_coeff.insert(std::make_pair(F124, q_124)); + + // FM 142 + int F142 = 142; + std::vector p_142; + p_142.push_back(0.3505); + p_142.push_back(0.07768); + p_142.push_back(0.01498); + + std::vector q_142; + q_142.push_back(-1.959); + q_142.push_back(0.0322); + q_142.push_back(2.819); + + p_coeff.insert(std::make_pair(F142, p_142)); + q_coeff.insert(std::make_pair(F142, q_142)); + + // FM 143 + int F143 = 143; + std::vector p_143; + p_143.push_back(1.748); + p_143.push_back(0.1589); + p_143.push_back(0.08249); + + std::vector q_143; + q_143.push_back(-0.938); + q_143.push_back(0.07674); + q_143.push_back(1.479); + + p_coeff.insert(std::make_pair(F143, p_143)); + q_coeff.insert(std::make_pair(F143, q_143)); + + // FM 144 + int F144 = 144; + std::vector p_144; + p_144.push_back(0.08116); + p_144.push_back(0.07849); + p_144.push_back(0.003353); + + std::vector q_144; + q_144.push_back(-2.452); + q_144.push_back(0.03347); + q_144.push_back(3.486); + + p_coeff.insert(std::make_pair(F144, p_144)); + q_coeff.insert(std::make_pair(F144, q_144)); + + // FM 145 + int F145 = 145; + std::vector p_145; + p_145.push_back(0.0483); + p_145.push_back(0.0781); + p_145.push_back(0.002783); + + std::vector q_145; + q_145.push_back(-2.796); + q_145.push_back(0.04029); + q_145.push_back(4.24); + + p_coeff.insert(std::make_pair(F145, p_145)); + q_coeff.insert(std::make_pair(F145, q_145)); + + // FM 146 + int F146 = 146; + std::vector p_146; + p_146.push_back(0.1248); + p_146.push_back(0.07783); + p_146.push_back(0.007999); + + std::vector q_146; + q_146.push_back(-2.121); + q_146.push_back(0.04111); + q_146.push_back(3.327); + + p_coeff.insert(std::make_pair(F146, p_146)); + q_coeff.insert(std::make_pair(F146, q_146)); + + // FM 146 + int F147 = 147; + std::vector p_147; + p_147.push_back(0.07431); + p_147.push_back(0.07791); + p_147.push_back(0.004384); + + std::vector q_147; + q_147.push_back(-2.668); + q_147.push_back(0.04027); + q_147.push_back(4.089); + + p_coeff.insert(std::make_pair(F147, p_147)); + q_coeff.insert(std::make_pair(F147, q_147)); + + // FM 148 + int F148 = 148; + std::vector p_148; + p_148.push_back(0.1238); + p_148.push_back(0.07772); + p_148.push_back(0.00647); + + std::vector q_148; + q_148.push_back(-2.506); + q_148.push_back(0.03664); + q_148.push_back(3.756); + + p_coeff.insert(std::make_pair(F148, p_148)); + q_coeff.insert(std::make_pair(F148, q_148)); + + // FM 149 + int F149 = 149; + std::vector p_149; + p_149.push_back(0.0667); + p_149.push_back(0.07779); + p_149.push_back(0.003506); + + std::vector q_149; + q_149.push_back(-3.209); + q_149.push_back(0.03641); + q_149.push_back(4.839); + + p_coeff.insert(std::make_pair(F149, p_149)); + q_coeff.insert(std::make_pair(F149, q_149)); + + // FM 161 + int F161 = 161; + std::vector p_161; + p_161.push_back(2.616); + p_161.push_back(0.1744); + p_161.push_back(0.1004); + + std::vector q_161; + q_161.push_back(-0.867); + q_161.push_back(0.08398); + q_161.push_back(1.326); + + p_coeff.insert(std::make_pair(F161, p_161)); + q_coeff.insert(std::make_pair(F161, q_161)); + + // FM 162 + int F162 = 162; + std::vector p_162; + p_162.push_back(0.6444); + p_162.push_back(0.1574); + p_162.push_back(0.02134); + + std::vector q_162; + q_162.push_back(-1.347); + q_162.push_back(0.0649); + q_162.push_back(1.958); + + p_coeff.insert(std::make_pair(F162, p_162)); + q_coeff.insert(std::make_pair(F162, q_162)); + + // FM 163 + int F163 = 163; + std::vector p_163; + p_163.push_back(0.08987); + p_163.push_back(0.07819); + p_163.push_back(0.003927); + + std::vector q_163; + q_163.push_back(-2.419); + q_163.push_back(0.03439); + q_163.push_back(3.493); + + p_coeff.insert(std::make_pair(F163, p_163)); + q_coeff.insert(std::make_pair(F163, q_163)); + + // FM 164 + int F164 = 164; + std::vector p_164; + p_164.push_back(0.1843); + p_164.push_back(0.07912); + p_164.push_back(0.005477); + + std::vector q_164; + q_164.push_back(-2.661); + q_164.push_back(0.0271); + q_164.push_back(3.579); + + p_coeff.insert(std::make_pair(F164, p_164)); + q_coeff.insert(std::make_pair(F164, q_164)); + + // FM 165 + int F165 = 165; + std::vector p_165; + p_165.push_back(0.3291); + p_165.push_back(0.07679); + p_165.push_back(0.02046); + + std::vector q_165; + q_165.push_back(-1.891); + q_165.push_back(0.03665); + q_165.push_back(3.027); + + p_coeff.insert(std::make_pair(F165, p_165)); + q_coeff.insert(std::make_pair(F165, q_165)); + + // FM 181 + int F181 = 181; + std::vector p_181; + p_181.push_back(14.96); + p_181.push_back(0.401); + p_181.push_back(1.983); + + std::vector q_181; + q_181.push_back(-0.1525); + q_181.push_back(0.4018); + q_181.push_back(0.4484); + + p_coeff.insert(std::make_pair(F181, p_181)); + q_coeff.insert(std::make_pair(F181, q_181)); + + // FM 182 + int F182 = 182; + std::vector p_182; + p_182.push_back(11.01); + p_182.push_back(0.3366); + p_182.push_back(0.7639); + + std::vector q_182; + q_182.push_back(-0.3704); + q_182.push_back(0.202); + q_182.push_back(0.6365); + + p_coeff.insert(std::make_pair(F182, p_182)); + q_coeff.insert(std::make_pair(F182, q_182)); + + // FM 183 + int F183 = 183; + std::vector p_183; + p_183.push_back(10.09); + p_183.push_back(0.3454); + p_183.push_back(0.584); + + std::vector q_183; + q_183.push_back(-0.4398); + q_183.push_back(0.1448); + q_183.push_back(0.7804); + + p_coeff.insert(std::make_pair(F183, p_183)); + q_coeff.insert(std::make_pair(F183, q_183)); + + // FM 185 + int F185 = 185; + std::vector p_185; + p_185.push_back(2.195); + p_185.push_back(0.1807); + p_185.push_back(0.07939); + + std::vector q_185; + q_185.push_back(-0.8838); + q_185.push_back(0.08234); + q_185.push_back(1.368); + + p_coeff.insert(std::make_pair(F185, p_185)); + q_coeff.insert(std::make_pair(F185, q_185)); + + // FM 186 + int F186 = 186; + std::vector p_186; + p_186.push_back(0.9183); + p_186.push_back(0.1224); + p_186.push_back(0.02969); + + std::vector q_186; + q_186.push_back(-1.306); + q_186.push_back(0.04578); + q_186.push_back(1.908); + + p_coeff.insert(std::make_pair(F186, p_186)); + q_coeff.insert(std::make_pair(F186, q_186)); + + // FM 188 + int F188 = 188; + std::vector p_188; + p_188.push_back(0.4789); + p_188.push_back(0.07735); + p_188.push_back(0.0195); + + std::vector q_188; + q_188.push_back(-1.68); + q_188.push_back(0.02617); + q_188.push_back(2.451); + + p_coeff.insert(std::make_pair(F188, p_188)); + q_coeff.insert(std::make_pair(F188, q_188)); + + // FM 189 + int F189 = 189; + std::vector p_189; + p_189.push_back(0.3229); + p_189.push_back(0.07716); + p_189.push_back(0.01346); + + std::vector q_189; + q_189.push_back(-1.916); + q_189.push_back(0.02961); + q_189.push_back(2.816); + + p_coeff.insert(std::make_pair(F189, p_189)); + q_coeff.insert(std::make_pair(F189, q_189)); + } + + if (scenario == 2) + { + // Populate them + // FM 101 + int F101 = 101; + std::vector p_101; + p_101.push_back(4.941); + p_101.push_back(0.7086); + p_101.push_back(0.2124); + + std::vector q_101; + q_101.push_back(-0.4535); + q_101.push_back(0.2682); + q_101.push_back(0.777); + + p_coeff.insert(std::make_pair(F101, p_101)); + q_coeff.insert(std::make_pair(F101, q_101)); + + // FM 102 + int F102 = 102; + std::vector p_102; + p_102.push_back(0.8112); + p_102.push_back(0.3045); + p_102.push_back(0.02528); + + std::vector q_102; + q_102.push_back(-1.036); + q_102.push_back(0.1385); + q_102.push_back(1.561); + + p_coeff.insert(std::make_pair(F102, p_102)); + q_coeff.insert(std::make_pair(F102, q_102)); + + // FM 103 + int F103 = 103; + std::vector p_103; + p_103.push_back(0.3609); + p_103.push_back(0.2318); + p_103.push_back(0.01738); + + std::vector q_103; + q_103.push_back(-1.273); + q_103.push_back(0.1135); + q_103.push_back(1.966); + + p_coeff.insert(std::make_pair(F103, p_103)); + q_coeff.insert(std::make_pair(F103, q_103)); + + // FM 104 + int F104 = 104; + std::vector p_104; + p_104.push_back(0.1486); + p_104.push_back(0.153); + p_104.push_back(0.004652); + + std::vector q_104; + q_104.push_back(-1.98); + q_104.push_back(0.06712); + q_104.push_back(2.744); + + p_coeff.insert(std::make_pair(F104, p_104)); + q_coeff.insert(std::make_pair(F104, q_104)); + + // FM 105 + int F105 = 105; + std::vector p_105; + p_105.push_back(0.0681); + p_105.push_back(0.07832); + p_105.push_back(0.002926); + + std::vector q_105; + q_105.push_back(-2.578); + q_105.push_back(0.03345); + q_105.push_back(3.694); + + p_coeff.insert(std::make_pair(F105, p_105)); + q_coeff.insert(std::make_pair(F105, q_105)); + + // FM 106 + int F106 = 106; + std::vector p_106; + p_106.push_back(0.04896); + p_106.push_back(0.07908); + p_106.push_back(0.001631); + + std::vector q_106; + q_106.push_back(-3.334); + q_106.push_back(0.03012); + q_106.push_back(4.525); + + p_coeff.insert(std::make_pair(F106, p_106)); + q_coeff.insert(std::make_pair(F106, q_106)); + + // FM 107 + int F107 = 107; + std::vector p_107; + p_107.push_back(0.03528); + p_107.push_back(0.07869); + p_107.push_back(0.001315); + + std::vector q_107; + q_107.push_back(-3.658); + q_107.push_back(0.03158); + q_107.push_back(5.09); + + p_coeff.insert(std::make_pair(F107, p_107)); + q_coeff.insert(std::make_pair(F107, q_107)); + + // FM 108 + int F108 = 108; + std::vector p_108; + p_108.push_back(0.04173); + p_108.push_back(0.07796); + p_108.push_back(0.002318); + + std::vector q_108; + q_108.push_back(-3.209); + q_108.push_back(0.03823); + q_108.push_back(4.86); + + p_coeff.insert(std::make_pair(F108, p_108)); + q_coeff.insert(std::make_pair(F108, q_108)); + + // FM 121 + + int F121 = 121; + std::vector p_121; + p_121.push_back(1.64); + p_121.push_back(0.2795); + p_121.push_back(0.05015); + + std::vector q_121; + q_121.push_back(-0.9854); + q_121.push_back(0.1202); + q_121.push_back(1.392); + + p_coeff.insert(std::make_pair(F121, p_121)); + q_coeff.insert(std::make_pair(F121, q_121)); + + // FM 122 + + int F122 = 122; + std::vector p_122; + p_122.push_back(0.4834); + p_122.push_back(0.1577); + p_122.push_back(0.01499); + + std::vector q_122; + q_122.push_back(-1.486); + q_122.push_back(0.06882); + q_122.push_back(2.084); + + p_coeff.insert(std::make_pair(F122, p_122)); + q_coeff.insert(std::make_pair(F122, q_122)); + + // FM 123 + + int F123 = 123; + std::vector p_123; + p_123.push_back(0.1385); + p_123.push_back(0.08614); + p_123.push_back(0.005977); + + std::vector q_123; + q_123.push_back(-2.108); + q_123.push_back(0.03642); + q_123.push_back(3.029); + + p_coeff.insert(std::make_pair(F123, p_123)); + q_coeff.insert(std::make_pair(F123, q_123)); + + // FM 124 + + int F124 = 124; + std::vector p_124; + p_124.push_back(0.1333); + p_124.push_back(0.07794); + p_124.push_back(0.005812); + + std::vector q_124; + q_124.push_back(-2.963); + q_124.push_back(0.03259); + q_124.push_back(4.318); + + p_coeff.insert(std::make_pair(F124, p_124)); + q_coeff.insert(std::make_pair(F124, q_124)); + + // FM 142 + + int F142 = 142; + std::vector p_142; + p_142.push_back(3.016); + p_142.push_back(0.1405); + p_142.push_back(0.117); + + std::vector q_142; + q_142.push_back(-0.8923); + q_142.push_back(0.06068); + q_142.push_back(1.351); + + p_coeff.insert(std::make_pair(F142, p_142)); + q_coeff.insert(std::make_pair(F142, q_142)); + + // FM 143 + + int F143 = 143; + std::vector p_143; + p_143.push_back(3.263); + p_143.push_back(0.1853); + p_143.push_back(0.1567); + + std::vector q_143; + q_143.push_back(-0.7716); + q_143.push_back(0.08453); + q_143.push_back(1.244); + + p_coeff.insert(std::make_pair(F143, p_143)); + q_coeff.insert(std::make_pair(F143, q_143)); + + // FM 144 + + int F144 = 144; + std::vector p_144; + p_144.push_back(0.2209); + p_144.push_back(0.1077); + p_144.push_back(0.00858); + + std::vector q_144; + q_144.push_back(-1.841); + q_144.push_back(0.04621); + q_144.push_back(2.634); + + p_coeff.insert(std::make_pair(F144, p_144)); + q_coeff.insert(std::make_pair(F144, q_144)); + + // FM 145 + + int F145 = 145; + std::vector p_145; + p_145.push_back(0.07661); + p_145.push_back(0.07807); + p_145.push_back(0.004418); + + std::vector q_145; + q_145.push_back(-2.425); + q_145.push_back(0.03922); + q_145.push_back(3.681); + + p_coeff.insert(std::make_pair(F145, p_145)); + q_coeff.insert(std::make_pair(F145, q_145)); + + // FM 146 + + int F146 = 146; + std::vector p_146; + p_146.push_back(0.1924); + p_146.push_back(0.07805); + p_146.push_back(0.01232); + + std::vector q_146; + q_146.push_back(-1.864); + q_146.push_back(0.04114); + q_146.push_back(2.908); + + p_coeff.insert(std::make_pair(F146, p_146)); + q_coeff.insert(std::make_pair(F146, q_146)); + + // FM 146 + + int F147 = 147; + std::vector p_147; + p_147.push_back(0.118); + p_147.push_back(0.07792); + p_147.push_back(0.006965); + + std::vector q_147; + q_147.push_back(-2.312); + q_147.push_back(0.03944); + q_147.push_back(3.548); + + p_coeff.insert(std::make_pair(F147, p_147)); + q_coeff.insert(std::make_pair(F147, q_147)); + + // FM 148 + + int F148 = 148; + std::vector p_148; + p_148.push_back(0.1863); + p_148.push_back(0.07774); + p_148.push_back(0.009734); + + std::vector q_148; + q_148.push_back(-2.218); + q_148.push_back(0.03714); + q_148.push_back(3.323); + + p_coeff.insert(std::make_pair(F148, p_148)); + q_coeff.insert(std::make_pair(F148, q_148)); + + // FM 149 + + int F149 = 149; + std::vector p_149; + p_149.push_back(0.1014); + p_149.push_back(0.07776); + p_149.push_back(0.005332); + + std::vector q_149; + q_149.push_back(-2.845); + q_149.push_back(0.03678); + q_149.push_back(4.283); - p_coeff.insert(std::make_pair(F142, p_142)); - q_coeff.insert(std::make_pair(F142, q_142)); + p_coeff.insert(std::make_pair(F149, p_149)); + q_coeff.insert(std::make_pair(F149, q_149)); - // FM 143 + // FM 161 - int F143 = 143; - std::vector p_143; - p_143.push_back(3.263); - p_143.push_back(0.1853); - p_143.push_back(0.1567); - - std::vector q_143; - q_143.push_back(-0.7716); - q_143.push_back(0.08453); - q_143.push_back(1.244); + int F161 = 161; + std::vector p_161; + p_161.push_back(5.028); + p_161.push_back(0.2037); + p_161.push_back(0.1978); + + std::vector q_161; + q_161.push_back(-0.7292); + q_161.push_back(0.08708); + q_161.push_back(1.115); - p_coeff.insert(std::make_pair(F143, p_143)); - q_coeff.insert(std::make_pair(F143, q_143)); + p_coeff.insert(std::make_pair(F161, p_161)); + q_coeff.insert(std::make_pair(F161, q_161)); - // FM 144 + // FM 162 - int F144 = 144; - std::vector p_144; - p_144.push_back(0.2209); - p_144.push_back(0.1077); - p_144.push_back(0.00858); - - std::vector q_144; - q_144.push_back(-1.841); - q_144.push_back(0.04621); - q_144.push_back(2.634); + int F162 = 162; + std::vector p_162; + p_162.push_back(1.128); + p_162.push_back(0.1848); + p_162.push_back(0.03716); + + std::vector q_162; + q_162.push_back(-1.119); + q_162.push_back(0.07944); + q_162.push_back(1.645); - p_coeff.insert(std::make_pair(F144, p_144)); - q_coeff.insert(std::make_pair(F144, q_144)); + p_coeff.insert(std::make_pair(F162, p_162)); + q_coeff.insert(std::make_pair(F162, q_162)); - // FM 145 + // FM 163 - int F145 = 145; - std::vector p_145; - p_145.push_back(0.07661); - p_145.push_back(0.07807); - p_145.push_back(0.004418); - - std::vector q_145; - q_145.push_back(-2.425); - q_145.push_back(0.03922); - q_145.push_back(3.681); + int F163 = 163; + std::vector p_163; + p_163.push_back(0.1554); + p_163.push_back(0.08058); + p_163.push_back(0.006821); + + std::vector q_163; + q_163.push_back(-2.03); + q_163.push_back(0.03518); + q_163.push_back(2.943); - p_coeff.insert(std::make_pair(F145, p_145)); - q_coeff.insert(std::make_pair(F145, q_145)); + p_coeff.insert(std::make_pair(F163, p_163)); + q_coeff.insert(std::make_pair(F163, q_163)); - // FM 146 + // FM 164 - int F146 = 146; - std::vector p_146; - p_146.push_back(0.1924); - p_146.push_back(0.07805); - p_146.push_back(0.01232); - - std::vector q_146; - q_146.push_back(-1.864); - q_146.push_back(0.04114); - q_146.push_back(2.908); + int F164 = 164; + std::vector p_164; + p_164.push_back(0.272); + p_164.push_back(0.07915); + p_164.push_back(0.008083); + + std::vector q_164; + q_164.push_back(-2.345); + q_164.push_back(0.02613); + q_164.push_back(3.187); - p_coeff.insert(std::make_pair(F146, p_146)); - q_coeff.insert(std::make_pair(F146, q_146)); + p_coeff.insert(std::make_pair(F164, p_164)); + q_coeff.insert(std::make_pair(F164, q_164)); - // FM 146 + // FM 165 - int F147 = 147; - std::vector p_147; - p_147.push_back(0.118); - p_147.push_back(0.07792); - p_147.push_back(0.006965); - - std::vector q_147; - q_147.push_back(-2.312); - q_147.push_back(0.03944); - q_147.push_back(3.548); + int F165 = 165; + std::vector p_165; + p_165.push_back(0.4786); + p_165.push_back(0.0766); + p_165.push_back(0.02979); + + std::vector q_165; + q_165.push_back(-1.676); + q_165.push_back(0.03638); + q_165.push_back(2.685); - p_coeff.insert(std::make_pair(F147, p_147)); - q_coeff.insert(std::make_pair(F147, q_147)); + p_coeff.insert(std::make_pair(F165, p_165)); + q_coeff.insert(std::make_pair(F165, q_165)); - // FM 148 + // FM 181 - int F148 = 148; - std::vector p_148; - p_148.push_back(0.1863); - p_148.push_back(0.07774); - p_148.push_back(0.009734); - - std::vector q_148; - q_148.push_back(-2.218); - q_148.push_back(0.03714); - q_148.push_back(3.323); + int F181 = 181; + std::vector p_181; + p_181.push_back(21.49); + p_181.push_back(0.5351); + p_181.push_back(3.327); + + std::vector q_181; + q_181.push_back(-0.1561); + q_181.push_back(0.1462); + q_181.push_back(0.4506); - p_coeff.insert(std::make_pair(F148, p_148)); - q_coeff.insert(std::make_pair(F148, q_148)); + p_coeff.insert(std::make_pair(F181, p_181)); + q_coeff.insert(std::make_pair(F181, q_181)); - // FM 149 + // FM 182 - int F149 = 149; - std::vector p_149; - p_149.push_back(0.1014); - p_149.push_back(0.07776); - p_149.push_back(0.005332); - - std::vector q_149; - q_149.push_back(-2.845); - q_149.push_back(0.03678); - q_149.push_back(4.283); + int F182 = 182; + std::vector p_182; + p_182.push_back(11.87); + p_182.push_back(0.3804); + p_182.push_back(1.424); + + std::vector q_182; + q_182.push_back(-0.2634); + q_182.push_back(0.2267); + q_182.push_back(0.55); - p_coeff.insert(std::make_pair(F149, p_149)); - q_coeff.insert(std::make_pair(F149, q_149)); + p_coeff.insert(std::make_pair(F182, p_182)); + q_coeff.insert(std::make_pair(F182, q_182)); - // FM 161 + // FM 183 - int F161 = 161; - std::vector p_161; - p_161.push_back(5.028); - p_161.push_back(0.2037); - p_161.push_back(0.1978); - - std::vector q_161; - q_161.push_back(-0.7292); - q_161.push_back(0.08708); - q_161.push_back(1.115); + int F183 = 183; + std::vector p_183; + p_183.push_back(16.14); + p_183.push_back(0.4104); + p_183.push_back(0.9961); + + std::vector q_183; + q_183.push_back(-0.3704); + q_183.push_back(0.2021); + q_183.push_back(0.6365); - p_coeff.insert(std::make_pair(F161, p_161)); - q_coeff.insert(std::make_pair(F161, q_161)); + p_coeff.insert(std::make_pair(F183, p_183)); + q_coeff.insert(std::make_pair(F183, q_183)); - // FM 162 + // FM 185 - int F162 = 162; - std::vector p_162; - p_162.push_back(1.128); - p_162.push_back(0.1848); - p_162.push_back(0.03716); - - std::vector q_162; - q_162.push_back(-1.119); - q_162.push_back(0.07944); - q_162.push_back(1.645); + int F185 = 185; + std::vector p_185; + p_185.push_back(4.008); + p_185.push_back(0.2228); + p_185.push_back(0.1393); + + std::vector q_185; + q_185.push_back(-0.7146); + q_185.push_back(0.09259); + q_185.push_back(1.158); - p_coeff.insert(std::make_pair(F162, p_162)); - q_coeff.insert(std::make_pair(F162, q_162)); + p_coeff.insert(std::make_pair(F185, p_185)); + q_coeff.insert(std::make_pair(F185, q_185)); - // FM 163 + // FM 186 - int F163 = 163; - std::vector p_163; - p_163.push_back(0.1554); - p_163.push_back(0.08058); - p_163.push_back(0.006821); - - std::vector q_163; - q_163.push_back(-2.03); - q_163.push_back(0.03518); - q_163.push_back(2.943); + int F186 = 186; + std::vector p_186; + p_186.push_back(1.783); + p_186.push_back(0.1537); + p_186.push_back(0.05478); + + std::vector q_186; + q_186.push_back(-1.056); + q_186.push_back(0.06279); + q_186.push_back(1.538); - p_coeff.insert(std::make_pair(F163, p_163)); - q_coeff.insert(std::make_pair(F163, q_163)); + p_coeff.insert(std::make_pair(F186, p_186)); + q_coeff.insert(std::make_pair(F186, q_186)); - // FM 164 + // FM 188 - int F164 = 164; - std::vector p_164; - p_164.push_back(0.272); - p_164.push_back(0.07915); - p_164.push_back(0.008083); - - std::vector q_164; - q_164.push_back(-2.345); - q_164.push_back(0.02613); - q_164.push_back(3.187); + int F188 = 188; + std::vector p_188; + p_188.push_back(0.8048); + p_188.push_back(0.09159); + p_188.push_back(0.03249); + + std::vector q_188; + q_188.push_back(-1.364); + q_188.push_back(0.03338); + q_188.push_back(2.04); - p_coeff.insert(std::make_pair(F164, p_164)); - q_coeff.insert(std::make_pair(F164, q_164)); + p_coeff.insert(std::make_pair(F188, p_188)); + q_coeff.insert(std::make_pair(F188, q_188)); - // FM 165 + // FM 189 - int F165 = 165; - std::vector p_165; - p_165.push_back(0.4786); - p_165.push_back(0.0766); - p_165.push_back(0.02979); - - std::vector q_165; - q_165.push_back(-1.676); - q_165.push_back(0.03638); - q_165.push_back(2.685); + int F189 = 189; + std::vector p_189; + p_189.push_back(0.4263); + p_189.push_back(0.07714); + p_189.push_back(0.01775); + + std::vector q_189; + q_189.push_back(-1.758); + q_189.push_back(0.03012); + q_189.push_back(2.544); - p_coeff.insert(std::make_pair(F165, p_165)); - q_coeff.insert(std::make_pair(F165, q_165)); + p_coeff.insert(std::make_pair(F189, p_189)); + q_coeff.insert(std::make_pair(F189, q_189)); + } + + if (scenario == 3) + { + + // Populate them + // FM 101 + int F101 = 101; + std::vector p_101; + p_101.push_back(10.54); + p_101.push_back(0.9248); + p_101.push_back(0.6665); + + std::vector q_101; + q_101.push_back(-0.2781); + q_101.push_back(0.4427); + q_101.push_back(0.5494); + + p_coeff.insert(std::make_pair(F101, p_101)); + q_coeff.insert(std::make_pair(F101, q_101)); + + // FM 102 + int F102 = 102; + std::vector p_102; + p_102.push_back(9.046); + p_102.push_back(0.6935); + p_102.push_back(0.6243); + + std::vector q_102; + q_102.push_back(-0.2777); + q_102.push_back(0.4381); + q_102.push_back(0.5495); + + p_coeff.insert(std::make_pair(F102, p_102)); + q_coeff.insert(std::make_pair(F102, q_102)); + + // FM 103 + int F103 = 103; + std::vector p_103; + p_103.push_back(1.101); + p_103.push_back(0.2945); + p_103.push_back(0.05263); + + std::vector q_103; + q_103.push_back(-0.864); + q_103.push_back(0.1465); + q_103.push_back(1.422); + + p_coeff.insert(std::make_pair(F103, p_103)); + q_coeff.insert(std::make_pair(F103, q_103)); + + // FM 104 + int F104 = 104; + std::vector p_104; + p_104.push_back(2.828); + p_104.push_back(0.4191); + p_104.push_back(0.1083); + + std::vector q_104; + q_104.push_back(-0.6279); + q_104.push_back(0.2175); + q_104.push_back(1.004); + + p_coeff.insert(std::make_pair(F104, p_104)); + q_coeff.insert(std::make_pair(F104, q_104)); + + // FM 105 + int F105 = 105; + std::vector p_105; + p_105.push_back(0.2066); + p_105.push_back(0.09646); + p_105.push_back(0.008649); + + std::vector q_105; + q_105.push_back(-1.891); + q_105.push_back(0.04173); + q_105.push_back(2.707); + + p_coeff.insert(std::make_pair(F105, p_105)); + q_coeff.insert(std::make_pair(F105, q_105)); + + // FM 106 + int F106 = 106; + std::vector p_106; + p_106.push_back(0.1252); + p_106.push_back(0.07909); + p_106.push_back(0.004167); + + std::vector q_106; + q_106.push_back(-2.484); + q_106.push_back(0.0302); + q_106.push_back(3.375); + + p_coeff.insert(std::make_pair(F106, p_106)); + q_coeff.insert(std::make_pair(F106, q_106)); + + // FM 107 + int F107 = 107; + std::vector p_107; + p_107.push_back(0.2693); + p_107.push_back(0.1079); + p_107.push_back(0.009412); + + std::vector q_107; + q_107.push_back(-1.823); + q_107.push_back(0.04448); + q_107.push_back(2.545); + + p_coeff.insert(std::make_pair(F107, p_107)); + q_coeff.insert(std::make_pair(F107, q_107)); + + // FM 108 + int F108 = 108; + std::vector p_108; + p_108.push_back(0.09611); + p_108.push_back(0.07795); + p_108.push_back(0.005342); + + std::vector q_108; + q_108.push_back(-2.517); + q_108.push_back(0.03868); + q_108.push_back(3.788); + + p_coeff.insert(std::make_pair(F108, p_108)); + q_coeff.insert(std::make_pair(F108, q_108)); + + // FM 121 + + int F121 = 121; + std::vector p_121; + p_121.push_back(25.52); + p_121.push_back(0.7635); + p_121.push_back(1.428); + + std::vector q_121; + q_121.push_back(-0.1525); + q_121.push_back(0.4017); + q_121.push_back(0.4484); + + p_coeff.insert(std::make_pair(F121, p_121)); + q_coeff.insert(std::make_pair(F121, q_121)); + + // FM 122 + + int F122 = 122; + std::vector p_122; + p_122.push_back(8.922); + p_122.push_back(0.4899); + p_122.push_back(0.3328); + + std::vector q_122; + q_122.push_back(-0.4465); + q_122.push_back(0.1749); + q_122.push_back(0.7789); + + p_coeff.insert(std::make_pair(F122, p_122)); + q_coeff.insert(std::make_pair(F122, q_122)); + + // FM 123 + + int F123 = 123; + std::vector p_123; + p_123.push_back(5.884); + p_123.push_back(0.3888); + p_123.push_back(0.2259); + + std::vector q_123; + q_123.push_back(-0.5876); + q_123.push_back(0.1976); + q_123.push_back(0.8988); + + p_coeff.insert(std::make_pair(F123, p_123)); + q_coeff.insert(std::make_pair(F123, q_123)); + + // FM 124 + + int F124 = 124; + std::vector p_124; + p_124.push_back(0.6756); + p_124.push_back(0.07785); + p_124.push_back(0.02949); + + std::vector q_124; + q_124.push_back(-1.518); + q_124.push_back(0.03362); + q_124.push_back(2.179); + + p_coeff.insert(std::make_pair(F124, p_124)); + q_coeff.insert(std::make_pair(F124, q_124)); + + // FM 142 + + int F142 = 142; + std::vector p_142; + p_142.push_back(10.39); + p_142.push_back(0.2182); + p_142.push_back(0.3807); + + std::vector q_142; + q_142.push_back(-0.5648); + q_142.push_back(0.1069); + q_142.push_back(0.9037); + + p_coeff.insert(std::make_pair(F142, p_142)); + q_coeff.insert(std::make_pair(F142, q_142)); + + // FM 143 + + int F143 = 143; + std::vector p_143; + p_143.push_back(5.59); + p_143.push_back(0.2107); + p_143.push_back(0.254); + + std::vector q_143; + q_143.push_back(-0.6817); + q_143.push_back(0.1007); + q_143.push_back(1.064); + + p_coeff.insert(std::make_pair(F143, p_143)); + q_coeff.insert(std::make_pair(F143, q_143)); + + // FM 144 + + int F144 = 144; + std::vector p_144; + p_144.push_back(5.257); + p_144.push_back(0.3809); + p_144.push_back(0.1807); + + std::vector q_144; + q_144.push_back(-0.6294); + q_144.push_back(0.1919); + q_144.push_back(0.9523); - // FM 181 + p_coeff.insert(std::make_pair(F144, p_144)); + q_coeff.insert(std::make_pair(F144, q_144)); - int F181 = 181; - std::vector p_181; - p_181.push_back(21.49); - p_181.push_back(0.5351); - p_181.push_back(3.327); - - std::vector q_181; - q_181.push_back(-0.1561); - q_181.push_back(0.1462); - q_181.push_back(0.4506); - - p_coeff.insert(std::make_pair(F181, p_181)); - q_coeff.insert(std::make_pair(F181, q_181)); + // FM 145 - // FM 182 - - int F182 = 182; - std::vector p_182; - p_182.push_back(11.87); - p_182.push_back(0.3804); - p_182.push_back(1.424); - - std::vector q_182; - q_182.push_back(-0.2634); - q_182.push_back(0.2267); - q_182.push_back(0.55); - - p_coeff.insert(std::make_pair(F182, p_182)); - q_coeff.insert(std::make_pair(F182, q_182)); - - // FM 183 - - int F183 = 183; - std::vector p_183; - p_183.push_back(16.14); - p_183.push_back(0.4104); - p_183.push_back(0.9961); - - std::vector q_183; - q_183.push_back(-0.3704); - q_183.push_back(0.2021); - q_183.push_back(0.6365); - - p_coeff.insert(std::make_pair(F183, p_183)); - q_coeff.insert(std::make_pair(F183, q_183)); - - // FM 185 - - int F185 = 185; - std::vector p_185; - p_185.push_back(4.008); - p_185.push_back(0.2228); - p_185.push_back(0.1393); - - std::vector q_185; - q_185.push_back(-0.7146); - q_185.push_back(0.09259); - q_185.push_back(1.158); - - p_coeff.insert(std::make_pair(F185, p_185)); - q_coeff.insert(std::make_pair(F185, q_185)); - - // FM 186 - - int F186 = 186; - std::vector p_186; - p_186.push_back(1.783); - p_186.push_back(0.1537); - p_186.push_back(0.05478); - - std::vector q_186; - q_186.push_back(-1.056); - q_186.push_back(0.06279); - q_186.push_back(1.538); - - p_coeff.insert(std::make_pair(F186, p_186)); - q_coeff.insert(std::make_pair(F186, q_186)); - - // FM 188 - - int F188 = 188; - std::vector p_188; - p_188.push_back(0.8048); - p_188.push_back(0.09159); - p_188.push_back(0.03249); - - std::vector q_188; - q_188.push_back(-1.364); - q_188.push_back(0.03338); - q_188.push_back(2.04); - - p_coeff.insert(std::make_pair(F188, p_188)); - q_coeff.insert(std::make_pair(F188, q_188)); - - // FM 189 - - int F189 = 189; - std::vector p_189; - p_189.push_back(0.4263); - p_189.push_back(0.07714); - p_189.push_back(0.01775); - - std::vector q_189; - q_189.push_back(-1.758); - q_189.push_back(0.03012); - q_189.push_back(2.544); - - p_coeff.insert(std::make_pair(F189, p_189)); - q_coeff.insert(std::make_pair(F189, q_189)); - - } - - if (scenario == 3){ - - // Populate them - // FM 101 - int F101 = 101; - std::vector p_101; - p_101.push_back(10.54); - p_101.push_back(0.9248); - p_101.push_back(0.6665); - - std::vector q_101; - q_101.push_back(-0.2781); - q_101.push_back(0.4427); - q_101.push_back(0.5494); - - p_coeff.insert(std::make_pair(F101, p_101)); - q_coeff.insert(std::make_pair(F101, q_101)); - - // FM 102 - int F102 = 102; - std::vector p_102; - p_102.push_back(9.046); - p_102.push_back(0.6935); - p_102.push_back(0.6243); - - std::vector q_102; - q_102.push_back(-0.2777); - q_102.push_back(0.4381); - q_102.push_back(0.5495); - - p_coeff.insert(std::make_pair(F102, p_102)); - q_coeff.insert(std::make_pair(F102, q_102)); - - // FM 103 - int F103 = 103; - std::vector p_103; - p_103.push_back(1.101); - p_103.push_back(0.2945); - p_103.push_back(0.05263); - - std::vector q_103; - q_103.push_back(-0.864); - q_103.push_back(0.1465); - q_103.push_back(1.422); - - p_coeff.insert(std::make_pair(F103, p_103)); - q_coeff.insert(std::make_pair(F103, q_103)); - - - // FM 104 - int F104 = 104; - std::vector p_104; - p_104.push_back(2.828); - p_104.push_back(0.4191); - p_104.push_back(0.1083); - - std::vector q_104; - q_104.push_back(-0.6279); - q_104.push_back(0.2175); - q_104.push_back(1.004); - - p_coeff.insert(std::make_pair(F104, p_104)); - q_coeff.insert(std::make_pair(F104, q_104)); - - // FM 105 - int F105 = 105; - std::vector p_105; - p_105.push_back(0.2066); - p_105.push_back(0.09646); - p_105.push_back(0.008649); - - std::vector q_105; - q_105.push_back(-1.891); - q_105.push_back(0.04173); - q_105.push_back(2.707); - - p_coeff.insert(std::make_pair(F105, p_105)); - q_coeff.insert(std::make_pair(F105, q_105)); - - // FM 106 - int F106 = 106; - std::vector p_106; - p_106.push_back(0.1252); - p_106.push_back(0.07909); - p_106.push_back(0.004167); - - std::vector q_106; - q_106.push_back(-2.484); - q_106.push_back(0.0302); - q_106.push_back(3.375); - - p_coeff.insert(std::make_pair(F106, p_106)); - q_coeff.insert(std::make_pair(F106, q_106)); - - // FM 107 - int F107 = 107; - std::vector p_107; - p_107.push_back(0.2693); - p_107.push_back(0.1079); - p_107.push_back(0.009412); - - std::vector q_107; - q_107.push_back(-1.823); - q_107.push_back(0.04448); - q_107.push_back(2.545); - - p_coeff.insert(std::make_pair(F107, p_107)); - q_coeff.insert(std::make_pair(F107, q_107)); - - // FM 108 - int F108 = 108; - std::vector p_108; - p_108.push_back(0.09611); - p_108.push_back(0.07795); - p_108.push_back(0.005342); - - std::vector q_108; - q_108.push_back(-2.517); - q_108.push_back(0.03868); - q_108.push_back(3.788); - - p_coeff.insert(std::make_pair(F108, p_108)); - q_coeff.insert(std::make_pair(F108, q_108)); - - // FM 121 - - int F121 = 121; - std::vector p_121; - p_121.push_back(25.52); - p_121.push_back(0.7635); - p_121.push_back(1.428); - - std::vector q_121; - q_121.push_back(-0.1525); - q_121.push_back(0.4017); - q_121.push_back(0.4484); - - p_coeff.insert(std::make_pair(F121, p_121)); - q_coeff.insert(std::make_pair(F121, q_121)); - - // FM 122 - - int F122 = 122; - std::vector p_122; - p_122.push_back(8.922); - p_122.push_back(0.4899); - p_122.push_back(0.3328); - - std::vector q_122; - q_122.push_back(-0.4465); - q_122.push_back(0.1749); - q_122.push_back(0.7789); - - p_coeff.insert(std::make_pair(F122, p_122)); - q_coeff.insert(std::make_pair(F122, q_122)); - - // FM 123 - - int F123 = 123; - std::vector p_123; - p_123.push_back(5.884); - p_123.push_back(0.3888); - p_123.push_back(0.2259); - - std::vector q_123; - q_123.push_back(-0.5876); - q_123.push_back(0.1976); - q_123.push_back(0.8988); - - p_coeff.insert(std::make_pair(F123, p_123)); - q_coeff.insert(std::make_pair(F123, q_123)); - - // FM 124 - - int F124 = 124; - std::vector p_124; - p_124.push_back(0.6756); - p_124.push_back(0.07785); - p_124.push_back(0.02949); - - std::vector q_124; - q_124.push_back(-1.518); - q_124.push_back(0.03362); - q_124.push_back(2.179); - - p_coeff.insert(std::make_pair(F124, p_124)); - q_coeff.insert(std::make_pair(F124, q_124)); - - // FM 142 - - int F142 = 142; - std::vector p_142; - p_142.push_back(10.39); - p_142.push_back(0.2182); - p_142.push_back(0.3807); - - std::vector q_142; - q_142.push_back(-0.5648); - q_142.push_back(0.1069); - q_142.push_back(0.9037); + int F145 = 145; + std::vector p_145; + p_145.push_back(0.1073); + p_145.push_back(0.0781); + p_145.push_back(0.00619); + + std::vector q_145; + q_145.push_back(-2.173); + q_145.push_back(0.04044); + q_145.push_back(3.293); - p_coeff.insert(std::make_pair(F142, p_142)); - q_coeff.insert(std::make_pair(F142, q_142)); + p_coeff.insert(std::make_pair(F145, p_145)); + q_coeff.insert(std::make_pair(F145, q_145)); - // FM 143 + // FM 146 - int F143 = 143; - std::vector p_143; - p_143.push_back(5.59); - p_143.push_back(0.2107); - p_143.push_back(0.254); - - std::vector q_143; - q_143.push_back(-0.6817); - q_143.push_back(0.1007); - q_143.push_back(1.064); + int F146 = 146; + std::vector p_146; + p_146.push_back(0.2664); + p_146.push_back(0.07788); + p_146.push_back(0.01707); + + std::vector q_146; + q_146.push_back(-1.698); + q_146.push_back(0.03934); + q_146.push_back(2.652); - p_coeff.insert(std::make_pair(F143, p_143)); - q_coeff.insert(std::make_pair(F143, q_143)); + p_coeff.insert(std::make_pair(F146, p_146)); + q_coeff.insert(std::make_pair(F146, q_146)); - // FM 144 + // FM 146 - int F144 = 144; - std::vector p_144; - p_144.push_back(5.257); - p_144.push_back(0.3809); - p_144.push_back(0.1807); - - std::vector q_144; - q_144.push_back(-0.6294); - q_144.push_back(0.1919); - q_144.push_back(0.9523); + int F147 = 147; + std::vector p_147; + p_147.push_back(0.1651); + p_147.push_back(0.07791); + p_147.push_back(0.009743); + + std::vector q_147; + q_147.push_back(-2.084); + q_147.push_back(0.03998); + q_147.push_back(3.193); - p_coeff.insert(std::make_pair(F144, p_144)); - q_coeff.insert(std::make_pair(F144, q_144)); + p_coeff.insert(std::make_pair(F147, p_147)); + q_coeff.insert(std::make_pair(F147, q_147)); - // FM 145 + // FM 148 - int F145 = 145; - std::vector p_145; - p_145.push_back(0.1073); - p_145.push_back(0.0781); - p_145.push_back(0.00619); - - std::vector q_145; - q_145.push_back(-2.173); - q_145.push_back(0.04044); - q_145.push_back(3.293); + int F148 = 148; + std::vector p_148; + p_148.push_back(0.2704); + p_148.push_back(0.07765); + p_148.push_back(0.0141); + + std::vector q_148; + q_148.push_back(-1.978); + q_148.push_back(0.03601); + q_148.push_back(2.975); - p_coeff.insert(std::make_pair(F145, p_145)); - q_coeff.insert(std::make_pair(F145, q_145)); + p_coeff.insert(std::make_pair(F148, p_148)); + q_coeff.insert(std::make_pair(F148, q_148)); - // FM 146 + // FM 149 - int F146 = 146; - std::vector p_146; - p_146.push_back(0.2664); - p_146.push_back(0.07788); - p_146.push_back(0.01707); - - std::vector q_146; - q_146.push_back(-1.698); - q_146.push_back(0.03934); - q_146.push_back(2.652); + int F149 = 149; + std::vector p_149; + p_149.push_back(0.1391); + p_149.push_back(0.07771); + p_149.push_back(0.007329); + + std::vector q_149; + q_149.push_back(-2.626); + q_149.push_back(0.03657); + q_149.push_back(3.945); - p_coeff.insert(std::make_pair(F146, p_146)); - q_coeff.insert(std::make_pair(F146, q_146)); + p_coeff.insert(std::make_pair(F149, p_149)); + q_coeff.insert(std::make_pair(F149, q_149)); - // FM 146 + // FM 161 - int F147 = 147; - std::vector p_147; - p_147.push_back(0.1651); - p_147.push_back(0.07791); - p_147.push_back(0.009743); - - std::vector q_147; - q_147.push_back(-2.084); - q_147.push_back(0.03998); - q_147.push_back(3.193); + int F161 = 161; + std::vector p_161; + p_161.push_back(3180); + p_161.push_back(1.235); + p_161.push_back(3.332); + + std::vector q_161; + q_161.push_back(-0.1562); + q_161.push_back(0.1467); + q_161.push_back(0.4505); - p_coeff.insert(std::make_pair(F147, p_147)); - q_coeff.insert(std::make_pair(F147, q_147)); + p_coeff.insert(std::make_pair(F161, p_161)); + q_coeff.insert(std::make_pair(F161, q_161)); - // FM 148 + // FM 162 - int F148 = 148; - std::vector p_148; - p_148.push_back(0.2704); - p_148.push_back(0.07765); - p_148.push_back(0.0141); - - std::vector q_148; - q_148.push_back(-1.978); - q_148.push_back(0.03601); - q_148.push_back(2.975); + int F162 = 162; + std::vector p_162; + p_162.push_back(1.631); + p_162.push_back(0.2024); + p_162.push_back(0.05519); + + std::vector q_162; + q_162.push_back(-0.9908); + q_162.push_back(0.08943); + q_162.push_back(1.472); - p_coeff.insert(std::make_pair(F148, p_148)); - q_coeff.insert(std::make_pair(F148, q_148)); + p_coeff.insert(std::make_pair(F162, p_162)); + q_coeff.insert(std::make_pair(F162, q_162)); - // FM 149 + // FM 163 - int F149 = 149; - std::vector p_149; - p_149.push_back(0.1391); - p_149.push_back(0.07771); - p_149.push_back(0.007329); - - std::vector q_149; - q_149.push_back(-2.626); - q_149.push_back(0.03657); - q_149.push_back(3.945); + int F163 = 163; + std::vector p_163; + p_163.push_back(0.3075); + p_163.push_back(0.09702); + p_163.push_back(0.01307); + + std::vector q_163; + q_163.push_back(-1.705); + q_163.push_back(0.04277); + q_163.push_back(2.452); - p_coeff.insert(std::make_pair(F149, p_149)); - q_coeff.insert(std::make_pair(F149, q_149)); + p_coeff.insert(std::make_pair(F163, p_163)); + q_coeff.insert(std::make_pair(F163, q_163)); - // FM 161 + // FM 164 - int F161 = 161; - std::vector p_161; - p_161.push_back(3180); - p_161.push_back(1.235); - p_161.push_back(3.332); - - std::vector q_161; - q_161.push_back(-0.1562); - q_161.push_back(0.1467); - q_161.push_back(0.4505); + int F164 = 164; + std::vector p_164; + p_164.push_back(0.4047); + p_164.push_back(0.0793); + p_164.push_back(0.01199); + + std::vector q_164; + q_164.push_back(-2.052); + q_164.push_back(0.02663); + q_164.push_back(2.765); - p_coeff.insert(std::make_pair(F161, p_161)); - q_coeff.insert(std::make_pair(F161, q_161)); + p_coeff.insert(std::make_pair(F164, p_164)); + q_coeff.insert(std::make_pair(F164, q_164)); - // FM 162 + // FM 165 - int F162 = 162; - std::vector p_162; - p_162.push_back(1.631); - p_162.push_back(0.2024); - p_162.push_back(0.05519); - - std::vector q_162; - q_162.push_back(-0.9908); - q_162.push_back(0.08943); - q_162.push_back(1.472); + int F165 = 165; + std::vector p_165; + p_165.push_back(0.6448); + p_165.push_back(0.07668); + p_165.push_back(0.03998); + + std::vector q_165; + q_165.push_back(-1.521); + q_165.push_back(0.03838); + q_165.push_back(2.417); - p_coeff.insert(std::make_pair(F162, p_162)); - q_coeff.insert(std::make_pair(F162, q_162)); + p_coeff.insert(std::make_pair(F165, p_165)); + q_coeff.insert(std::make_pair(F165, q_165)); - // FM 163 + // FM 181 - int F163 = 163; - std::vector p_163; - p_163.push_back(0.3075); - p_163.push_back(0.09702); - p_163.push_back(0.01307); - - std::vector q_163; - q_163.push_back(-1.705); - q_163.push_back(0.04277); - q_163.push_back(2.452); + int F181 = 181; + std::vector p_181; + p_181.push_back(1800); + p_181.push_back(1.178); + p_181.push_back(4.999); + + std::vector q_181; + q_181.push_back(0.0); + q_181.push_back(0.0); + q_181.push_back(0.0); - p_coeff.insert(std::make_pair(F163, p_163)); - q_coeff.insert(std::make_pair(F163, q_163)); + p_coeff.insert(std::make_pair(F181, p_181)); + q_coeff.insert(std::make_pair(F181, q_181)); - // FM 164 + // FM 182 - int F164 = 164; - std::vector p_164; - p_164.push_back(0.4047); - p_164.push_back(0.0793); - p_164.push_back(0.01199); - - std::vector q_164; - q_164.push_back(-2.052); - q_164.push_back(0.02663); - q_164.push_back(2.765); + int F182 = 182; + std::vector p_182; + p_182.push_back(38.8); + p_182.push_back(0.5491); + p_182.push_back(1.989); + + std::vector q_182; + q_182.push_back(-0.2492); + q_182.push_back(0.1422); + q_182.push_back(0.5509); - p_coeff.insert(std::make_pair(F164, p_164)); - q_coeff.insert(std::make_pair(F164, q_164)); + p_coeff.insert(std::make_pair(F182, p_182)); + q_coeff.insert(std::make_pair(F182, q_182)); - // FM 165 + // FM 183 - int F165 = 165; - std::vector p_165; - p_165.push_back(0.6448); - p_165.push_back(0.07668); - p_165.push_back(0.03998); - - std::vector q_165; - q_165.push_back(-1.521); - q_165.push_back(0.03838); - q_165.push_back(2.417); + int F183 = 183; + std::vector p_183; + p_183.push_back(11.37); + p_183.push_back(0.3397); + p_183.push_back(1.244); + + std::vector q_183; + q_183.push_back(-0.3582); + q_183.push_back(0.1543); + q_183.push_back(0.6369); - p_coeff.insert(std::make_pair(F165, p_165)); - q_coeff.insert(std::make_pair(F165, q_165)); + p_coeff.insert(std::make_pair(F183, p_183)); + q_coeff.insert(std::make_pair(F183, q_183)); - // FM 181 + // FM 185 - int F181 = 181; - std::vector p_181; - p_181.push_back(1800); - p_181.push_back(1.178); - p_181.push_back(4.999); - - std::vector q_181; - q_181.push_back(0.0); - q_181.push_back(0.0); - q_181.push_back(0.0); - - p_coeff.insert(std::make_pair(F181, p_181)); - q_coeff.insert(std::make_pair(F181, q_181)); - - // FM 182 - - int F182 = 182; - std::vector p_182; - p_182.push_back(38.8); - p_182.push_back(0.5491); - p_182.push_back(1.989); - - std::vector q_182; - q_182.push_back(-0.2492); - q_182.push_back(0.1422); - q_182.push_back(0.5509); - - p_coeff.insert(std::make_pair(F182, p_182)); - q_coeff.insert(std::make_pair(F182, q_182)); - - // FM 183 - - int F183 = 183; - std::vector p_183; - p_183.push_back(11.37); - p_183.push_back(0.3397); - p_183.push_back(1.244); - - std::vector q_183; - q_183.push_back(-0.3582); - q_183.push_back(0.1543); - q_183.push_back(0.6369); - - p_coeff.insert(std::make_pair(F183, p_183)); - q_coeff.insert(std::make_pair(F183, q_183)); - - // FM 185 - - int F185 = 185; - std::vector p_185; - p_185.push_back(5.163); - p_185.push_back(0.2396); - p_185.push_back(0.1943); - - std::vector q_185; - q_185.push_back(-0.6817); - q_185.push_back(0.1007); - q_185.push_back(1.064); - - p_coeff.insert(std::make_pair(F185, p_185)); - q_coeff.insert(std::make_pair(F185, q_185)); - - // FM 186 - - int F186 = 186; - std::vector p_186; - p_186.push_back(2.555); - p_186.push_back(0.171); - p_186.push_back(0.07786); - - std::vector q_186; - q_186.push_back(-0.9478); - q_186.push_back(0.07391); - q_186.push_back(1.375); - - p_coeff.insert(std::make_pair(F186, p_186)); - q_coeff.insert(std::make_pair(F186, q_186)); - - // FM 188 - - int F188 = 188; - std::vector p_188; - p_188.push_back(1.294); - p_188.push_back(0.1085); - p_188.push_back(0.04999); - - std::vector q_188; - q_188.push_back(-1.184); - q_188.push_back(0.04144); - q_188.push_back(1.768); - - p_coeff.insert(std::make_pair(F188, p_188)); - q_coeff.insert(std::make_pair(F188, q_188)); - - // FM 189 - - int F189 = 189; - std::vector p_189; - p_189.push_back(0.534); - p_189.push_back(0.07749); - p_189.push_back(0.02216); - - std::vector q_189; - q_189.push_back(-1.624); - q_189.push_back(0.02893); - q_189.push_back(2.369); - - p_coeff.insert(std::make_pair(F189, p_189)); - q_coeff.insert(std::make_pair(F189, q_189)); - - } - - if (scenario == 4){ - // Populate them - // FM 101 - int F101 = 101; - std::vector p_101; - std::vector q_101; - p_101.push_back(0.); - p_101.push_back(0.); - p_101.push_back(-1.); - q_101.push_back(0.); - q_101.push_back(0.); - q_101.push_back(0.); - p_coeff.insert(std::make_pair(F101, p_101)); - q_coeff.insert(std::make_pair(F101, q_101)); - - // FM 102 - int F102 = 102; - std::vector p_102; - std::vector q_102; - p_102.push_back(0.); - p_102.push_back(0.); - p_102.push_back(-1.); - q_102.push_back(0.); - q_102.push_back(0.); - q_102.push_back(0.); - p_coeff.insert(std::make_pair(F102, p_102)); - q_coeff.insert(std::make_pair(F102, q_102)); - - // FM 103 - int F103 = 103; - std::vector p_103; - p_103.push_back(1.02e+04); - p_103.push_back(2.51); - p_103.push_back(10); - - std::vector q_103; - q_103.push_back(-0.3984); - q_103.push_back(0.6339); - q_103.push_back(0.3173); - - p_coeff.insert(std::make_pair(F103, p_103)); - q_coeff.insert(std::make_pair(F103, q_103)); - - - // FM 104 - int F104 = 104; - std::vector p_104; - p_104.push_back(1706); - p_104.push_back(5.835); - p_104.push_back(4.999); - - std::vector q_104; - q_104.push_back(-0.3984); - q_104.push_back(0.6331); - q_104.push_back(0.3173); - - p_coeff.insert(std::make_pair(F104, p_104)); - q_coeff.insert(std::make_pair(F104, q_104)); - - // FM 105 - int F105 = 105; - std::vector p_105; - p_105.push_back(24.51); - p_105.push_back(0.6818); - p_105.push_back(1.665); - - std::vector q_105; - q_105.push_back(-0.1528); - q_105.push_back(0.4083); - q_105.push_back(0.4483); - - p_coeff.insert(std::make_pair(F105, p_105)); - q_coeff.insert(std::make_pair(F105, q_105)); - - // FM 106 - int F106 = 106; - std::vector p_106; - std::vector q_106; - p_106.push_back(0.); - p_106.push_back(0.); - p_106.push_back(-1.); - q_106.push_back(0.); - q_106.push_back(0.); - q_106.push_back(0.); - p_coeff.insert(std::make_pair(F106, p_106)); - q_coeff.insert(std::make_pair(F106, q_106)); - - // FM 107 - int F107 = 107; - std::vector p_107; - p_107.push_back(8.706); - p_107.push_back(0.397); - p_107.push_back(0.3983); - - std::vector q_107; - q_107.push_back(-0.5259); - q_107.push_back(0.19); - q_107.push_back(0.7787); - - p_coeff.insert(std::make_pair(F107, p_107)); - q_coeff.insert(std::make_pair(F107, q_107)); - - // FM 108 - int F108 = 108; - std::vector p_108; - p_108.push_back(29.63); - p_108.push_back(0.6425); - p_108.push_back(1.246); - - std::vector q_108; - q_108.push_back(-0.2634); - q_108.push_back(0.2268); - q_108.push_back(0.55); - - p_coeff.insert(std::make_pair(F108, p_108)); - q_coeff.insert(std::make_pair(F108, q_108)); - - // FM 121 - - int F121 = 121; - std::vector p_121; - p_121.push_back(1.02e+04); - p_121.push_back(2.505); - p_121.push_back(10); - - std::vector q_121; - q_121.push_back(-0.3942); - q_121.push_back(0.6206); - q_121.push_back(0.3174); - - p_coeff.insert(std::make_pair(F121, p_121)); - q_coeff.insert(std::make_pair(F121, q_121)); - - // FM 122 - - int F122 = 122; - std::vector p_122; - p_122.push_back(25.02); - p_122.push_back(0.7935); - p_122.push_back(2); - - std::vector q_122; - q_122.push_back(-0.153); - q_122.push_back(0.4129); - q_122.push_back(0.4483); - - p_coeff.insert(std::make_pair(F122, p_122)); - q_coeff.insert(std::make_pair(F122, q_122)); - - // FM 123 - - int F123 = 123; - std::vector p_123; - p_123.push_back(2423); - p_123.push_back(5.898); - p_123.push_back(3.333); - - std::vector q_123; - q_123.push_back(-0.271); - q_123.push_back(0.2323); - q_123.push_back(0.4489); - - p_coeff.insert(std::make_pair(F123, p_123)); - q_coeff.insert(std::make_pair(F123, q_123)); - - // FM 124 - - int F124 = 124; - std::vector p_124; - p_124.push_back(3.313); - p_124.push_back(0.1361); - p_124.push_back(0.1345); - - std::vector q_124; - q_124.push_back(-0.8735); - q_124.push_back(0.06301); - q_124.push_back(1.305); - - p_coeff.insert(std::make_pair(F124, p_124)); - q_coeff.insert(std::make_pair(F124, q_124)); - - // FM 142 - - int F142 = 142; - std::vector p_142; - p_142.push_back(23.95); - p_142.push_back(0.3007); - p_142.push_back(0.9045); - - std::vector q_142; - q_142.push_back(-0.4438); - q_142.push_back(0.1155); - q_142.push_back(0.7152); + int F185 = 185; + std::vector p_185; + p_185.push_back(5.163); + p_185.push_back(0.2396); + p_185.push_back(0.1943); + + std::vector q_185; + q_185.push_back(-0.6817); + q_185.push_back(0.1007); + q_185.push_back(1.064); - p_coeff.insert(std::make_pair(F142, p_142)); - q_coeff.insert(std::make_pair(F142, q_142)); + p_coeff.insert(std::make_pair(F185, p_185)); + q_coeff.insert(std::make_pair(F185, q_185)); - // FM 143 + // FM 186 - int F143 = 143; - std::vector p_143; - p_143.push_back(8.823); - p_143.push_back(0.2347); - p_143.push_back(0.3672); - - std::vector q_143; - q_143.push_back(-0.602); - q_143.push_back(0.1209); - q_143.push_back(0.9543); + int F186 = 186; + std::vector p_186; + p_186.push_back(2.555); + p_186.push_back(0.171); + p_186.push_back(0.07786); + + std::vector q_186; + q_186.push_back(-0.9478); + q_186.push_back(0.07391); + q_186.push_back(1.375); + + p_coeff.insert(std::make_pair(F186, p_186)); + q_coeff.insert(std::make_pair(F186, q_186)); + + // FM 188 + + int F188 = 188; + std::vector p_188; + p_188.push_back(1.294); + p_188.push_back(0.1085); + p_188.push_back(0.04999); + + std::vector q_188; + q_188.push_back(-1.184); + q_188.push_back(0.04144); + q_188.push_back(1.768); + + p_coeff.insert(std::make_pair(F188, p_188)); + q_coeff.insert(std::make_pair(F188, q_188)); + + // FM 189 + + int F189 = 189; + std::vector p_189; + p_189.push_back(0.534); + p_189.push_back(0.07749); + p_189.push_back(0.02216); + + std::vector q_189; + q_189.push_back(-1.624); + q_189.push_back(0.02893); + q_189.push_back(2.369); + + p_coeff.insert(std::make_pair(F189, p_189)); + q_coeff.insert(std::make_pair(F189, q_189)); + } - p_coeff.insert(std::make_pair(F143, p_143)); - q_coeff.insert(std::make_pair(F143, q_143)); + if (scenario == 4) + { + // Populate them + // FM 101 + int F101 = 101; + std::vector p_101; + std::vector q_101; + p_101.push_back(0.); + p_101.push_back(0.); + p_101.push_back(-1.); + q_101.push_back(0.); + q_101.push_back(0.); + q_101.push_back(0.); + p_coeff.insert(std::make_pair(F101, p_101)); + q_coeff.insert(std::make_pair(F101, q_101)); + + // FM 102 + int F102 = 102; + std::vector p_102; + std::vector q_102; + p_102.push_back(0.); + p_102.push_back(0.); + p_102.push_back(-1.); + q_102.push_back(0.); + q_102.push_back(0.); + q_102.push_back(0.); + p_coeff.insert(std::make_pair(F102, p_102)); + q_coeff.insert(std::make_pair(F102, q_102)); + + // FM 103 + int F103 = 103; + std::vector p_103; + p_103.push_back(1.02e+04); + p_103.push_back(2.51); + p_103.push_back(10); + + std::vector q_103; + q_103.push_back(-0.3984); + q_103.push_back(0.6339); + q_103.push_back(0.3173); + + p_coeff.insert(std::make_pair(F103, p_103)); + q_coeff.insert(std::make_pair(F103, q_103)); + + // FM 104 + int F104 = 104; + std::vector p_104; + p_104.push_back(1706); + p_104.push_back(5.835); + p_104.push_back(4.999); + + std::vector q_104; + q_104.push_back(-0.3984); + q_104.push_back(0.6331); + q_104.push_back(0.3173); + + p_coeff.insert(std::make_pair(F104, p_104)); + q_coeff.insert(std::make_pair(F104, q_104)); + + // FM 105 + int F105 = 105; + std::vector p_105; + p_105.push_back(24.51); + p_105.push_back(0.6818); + p_105.push_back(1.665); + + std::vector q_105; + q_105.push_back(-0.1528); + q_105.push_back(0.4083); + q_105.push_back(0.4483); + + p_coeff.insert(std::make_pair(F105, p_105)); + q_coeff.insert(std::make_pair(F105, q_105)); + + // FM 106 + int F106 = 106; + std::vector p_106; + std::vector q_106; + p_106.push_back(0.); + p_106.push_back(0.); + p_106.push_back(-1.); + q_106.push_back(0.); + q_106.push_back(0.); + q_106.push_back(0.); + p_coeff.insert(std::make_pair(F106, p_106)); + q_coeff.insert(std::make_pair(F106, q_106)); + + // FM 107 + int F107 = 107; + std::vector p_107; + p_107.push_back(8.706); + p_107.push_back(0.397); + p_107.push_back(0.3983); + + std::vector q_107; + q_107.push_back(-0.5259); + q_107.push_back(0.19); + q_107.push_back(0.7787); + + p_coeff.insert(std::make_pair(F107, p_107)); + q_coeff.insert(std::make_pair(F107, q_107)); + + // FM 108 + int F108 = 108; + std::vector p_108; + p_108.push_back(29.63); + p_108.push_back(0.6425); + p_108.push_back(1.246); + + std::vector q_108; + q_108.push_back(-0.2634); + q_108.push_back(0.2268); + q_108.push_back(0.55); + + p_coeff.insert(std::make_pair(F108, p_108)); + q_coeff.insert(std::make_pair(F108, q_108)); + + // FM 121 + + int F121 = 121; + std::vector p_121; + p_121.push_back(1.02e+04); + p_121.push_back(2.505); + p_121.push_back(10); + + std::vector q_121; + q_121.push_back(-0.3942); + q_121.push_back(0.6206); + q_121.push_back(0.3174); + + p_coeff.insert(std::make_pair(F121, p_121)); + q_coeff.insert(std::make_pair(F121, q_121)); + + // FM 122 + + int F122 = 122; + std::vector p_122; + p_122.push_back(25.02); + p_122.push_back(0.7935); + p_122.push_back(2); + + std::vector q_122; + q_122.push_back(-0.153); + q_122.push_back(0.4129); + q_122.push_back(0.4483); + + p_coeff.insert(std::make_pair(F122, p_122)); + q_coeff.insert(std::make_pair(F122, q_122)); + + // FM 123 + + int F123 = 123; + std::vector p_123; + p_123.push_back(2423); + p_123.push_back(5.898); + p_123.push_back(3.333); + + std::vector q_123; + q_123.push_back(-0.271); + q_123.push_back(0.2323); + q_123.push_back(0.4489); + + p_coeff.insert(std::make_pair(F123, p_123)); + q_coeff.insert(std::make_pair(F123, q_123)); + + // FM 124 + + int F124 = 124; + std::vector p_124; + p_124.push_back(3.313); + p_124.push_back(0.1361); + p_124.push_back(0.1345); + + std::vector q_124; + q_124.push_back(-0.8735); + q_124.push_back(0.06301); + q_124.push_back(1.305); + + p_coeff.insert(std::make_pair(F124, p_124)); + q_coeff.insert(std::make_pair(F124, q_124)); + + // FM 142 + + int F142 = 142; + std::vector p_142; + p_142.push_back(23.95); + p_142.push_back(0.3007); + p_142.push_back(0.9045); + + std::vector q_142; + q_142.push_back(-0.4438); + q_142.push_back(0.1155); + q_142.push_back(0.7152); - // FM 144 + p_coeff.insert(std::make_pair(F142, p_142)); + q_coeff.insert(std::make_pair(F142, q_142)); - int F144 = 144; - std::vector p_144; - p_144.push_back(6.334); - p_144.push_back(0.3903); - p_144.push_back(0.2486); - - std::vector q_144; - q_144.push_back(-0.5751); - q_144.push_back(0.1717); - q_144.push_back(0.8994); + // FM 143 - p_coeff.insert(std::make_pair(F144, p_144)); - q_coeff.insert(std::make_pair(F144, q_144)); + int F143 = 143; + std::vector p_143; + p_143.push_back(8.823); + p_143.push_back(0.2347); + p_143.push_back(0.3672); + + std::vector q_143; + q_143.push_back(-0.602); + q_143.push_back(0.1209); + q_143.push_back(0.9543); - // FM 145 + p_coeff.insert(std::make_pair(F143, p_143)); + q_coeff.insert(std::make_pair(F143, q_143)); - int F145 = 145; - std::vector p_145; - p_145.push_back(0.7965); - p_145.push_back(0.168); - p_145.push_back(0.04058); - - std::vector q_145; - q_145.push_back(-1.156); - q_145.push_back(0.08584); - q_145.push_back(1.756); + // FM 144 - p_coeff.insert(std::make_pair(F145, p_145)); - q_coeff.insert(std::make_pair(F145, q_145)); + int F144 = 144; + std::vector p_144; + p_144.push_back(6.334); + p_144.push_back(0.3903); + p_144.push_back(0.2486); + + std::vector q_144; + q_144.push_back(-0.5751); + q_144.push_back(0.1717); + q_144.push_back(0.8994); - // FM 146 + p_coeff.insert(std::make_pair(F144, p_144)); + q_coeff.insert(std::make_pair(F144, q_144)); - int F146 = 146; - std::vector p_146; - p_146.push_back(0.3421); - p_146.push_back(0.07793); - p_146.push_back(0.02181); - - std::vector q_146; - q_146.push_back(-1.558); - q_146.push_back(0.0402); - q_146.push_back(2.452); + // FM 145 - p_coeff.insert(std::make_pair(F146, p_146)); - q_coeff.insert(std::make_pair(F146, q_146)); + int F145 = 145; + std::vector p_145; + p_145.push_back(0.7965); + p_145.push_back(0.168); + p_145.push_back(0.04058); + + std::vector q_145; + q_145.push_back(-1.156); + q_145.push_back(0.08584); + q_145.push_back(1.756); - // FM 146 + p_coeff.insert(std::make_pair(F145, p_145)); + q_coeff.insert(std::make_pair(F145, q_145)); - int F147 = 147; - std::vector p_147; - p_147.push_back(0.9702); - p_147.push_back(0.1314); - p_147.push_back(0.05167); - - std::vector q_147; - q_147.push_back(-1.118); - q_147.push_back(0.0653); - q_147.push_back(1.746); - - p_coeff.insert(std::make_pair(F147, p_147)); - q_coeff.insert(std::make_pair(F147, q_147)); - - // FM 148 - - int F148 = 148; - std::vector p_148; - p_148.push_back(1.44); - p_148.push_back(0.1175); - p_148.push_back(0.07096); - - std::vector q_148; - q_148.push_back(-1.079); - q_148.push_back(0.05247); - q_148.push_back(1.652); - - p_coeff.insert(std::make_pair(F148, p_148)); - q_coeff.insert(std::make_pair(F148, q_148)); - - // FM 149 - - int F149 = 149; - std::vector p_149; - p_149.push_back(0.4281); - p_149.push_back(0.07778); - p_149.push_back(0.02246); - - std::vector q_149; - q_149.push_back(-1.631); - q_149.push_back(0.03661); - q_149.push_back(2.479); - - p_coeff.insert(std::make_pair(F149, p_149)); - q_coeff.insert(std::make_pair(F149, q_149)); - - // FM 161 - - int F161 = 161; - std::vector p_161; - p_161.push_back(1819); - p_161.push_back(1.18); - p_161.push_back(4.999); - - std::vector q_161; - q_161.push_back(-0.3084); - q_161.push_back(6.721); - q_161.push_back(0.3162); - - p_coeff.insert(std::make_pair(F161, p_161)); - q_coeff.insert(std::make_pair(F161, q_161)); - - // FM 162 - - int F162 = 162; - std::vector p_162; - p_162.push_back(2.199); - p_162.push_back(0.2162); - p_162.push_back(0.07223); - - std::vector q_162; - q_162.push_back(-0.9267); - q_162.push_back(0.09552); - q_162.push_back(1.36); - - p_coeff.insert(std::make_pair(F162, p_162)); - q_coeff.insert(std::make_pair(F162, q_162)); - - // FM 163 - - int F163 = 163; - std::vector p_163; - p_163.push_back(4.902); - p_163.push_back(0.2927); - p_163.push_back(0.1805); - - std::vector q_163; - q_163.push_back(-0.6625); - q_163.push_back(0.1263); - q_163.push_back(1.058); - - p_coeff.insert(std::make_pair(F163, p_163)); - q_coeff.insert(std::make_pair(F163, q_163)); - - // FM 164 - - int F164 = 164; - std::vector p_164; - std::vector q_164; - p_164.push_back(0.); - p_164.push_back(0.); - p_164.push_back(-1.); - q_164.push_back(0.); - q_164.push_back(0.); - q_164.push_back(0.); - p_coeff.insert(std::make_pair(F164, p_164)); - q_coeff.insert(std::make_pair(F164, q_164)); - - // FM 165 - - int F165 = 165; - std::vector p_165; - p_165.push_back(0.817); - p_165.push_back(0.07709); - p_165.push_back(0.05013); - - std::vector q_165; - q_165.push_back(-1.425); - q_165.push_back(0.03706); - q_165.push_back(2.275); - - p_coeff.insert(std::make_pair(F165, p_165)); - q_coeff.insert(std::make_pair(F165, q_165)); - - // FM 181 - - int F181 = 181; - std::vector p_181; - p_181.push_back(1804); - p_181.push_back(1.178); - p_181.push_back(4.999); - - std::vector q_181; - q_181.push_back(0.0); - q_181.push_back(0.0); - q_181.push_back(0.0); - - p_coeff.insert(std::make_pair(F181, p_181)); - q_coeff.insert(std::make_pair(F181, q_181)); - - // FM 182 - - int F182 = 182; - std::vector p_182; - p_182.push_back(26.13); - p_182.push_back(0.5009); - p_182.push_back(2.488); - - std::vector q_182; - q_182.push_back(-0.1525); - q_182.push_back(0.4025); - q_182.push_back(0.4484); - - p_coeff.insert(std::make_pair(F182, p_182)); - q_coeff.insert(std::make_pair(F182, q_182)); - - // FM 183 - - int F183 = 183; - std::vector p_183; - p_183.push_back(19.31); - p_183.push_back(0.4546); - p_183.push_back(1.428); - - std::vector q_183; - q_183.push_back(-0.2634); - q_183.push_back(0.2268); - q_183.push_back(0.55); - - p_coeff.insert(std::make_pair(F183, p_183)); - q_coeff.insert(std::make_pair(F183, q_183)); - - // FM 185 - - int F185 = 185; - std::vector p_185; - p_185.push_back(5.518); - p_185.push_back(0.2432); - p_185.push_back(0.2307); - - std::vector q_185; - q_185.push_back(-0.6166); - q_185.push_back(0.1085); - q_185.push_back(1.011); - - p_coeff.insert(std::make_pair(F185, p_185)); - q_coeff.insert(std::make_pair(F185, q_185)); - - // FM 186 - - int F186 = 186; - std::vector p_186; - p_186.push_back(2.956); - p_186.push_back(0.1765); - p_186.push_back(0.09361); - - std::vector q_186; - q_186.push_back(-0.8538); - q_186.push_back(0.07918); - q_186.push_back(1.292); - - p_coeff.insert(std::make_pair(F186, p_186)); - q_coeff.insert(std::make_pair(F186, q_186)); - - // FM 188 - - int F188 = 188; - std::vector p_188; - p_188.push_back(1.736); - p_188.push_back(0.1188); - p_188.push_back(0.06593); - - std::vector q_188; - q_188.push_back(-1.076); - q_188.push_back(0.04976); - q_188.push_back(1.599); - - p_coeff.insert(std::make_pair(F188, p_188)); - q_coeff.insert(std::make_pair(F188, q_188)); - - // FM 189 - - int F189 = 189; - std::vector p_189; - p_189.push_back(0.6251); - p_189.push_back(0.07753); - p_189.push_back(0.02607); - - std::vector q_189; - q_189.push_back(-1.505); - q_189.push_back(0.03052); - q_189.push_back(2.216); - - p_coeff.insert(std::make_pair(F189, p_189)); - q_coeff.insert(std::make_pair(F189, q_189)); - - } - -//Fuel Model Parameters for Crown Fire -std::vector fp_101; -fp_101.push_back(0.1+0.0+0.0+0.3+0.0); -fp_101.push_back(8000); -fm_parameters.insert(std::make_pair(101,fp_101)); - -std::vector fp_102; -fp_102.push_back(0.1+0.0+0.0+1.0+0.0); -fp_102.push_back(8000); -fm_parameters.insert(std::make_pair(102,fp_102)); - -std::vector fp_103; -fp_103.push_back(0.1+0.4+0.0+1.5+0.0); -fp_103.push_back(8000); -fm_parameters.insert(std::make_pair(103,fp_103)); - -std::vector fp_104; -fp_104.push_back(0.25+0.0+0.0+1.9+0.0); -fp_104.push_back(8000); -fm_parameters.insert(std::make_pair(104,fp_104)); - -std::vector fp_105; -fp_105.push_back(0.4+0.0+0.0+2.5+0.0); -fp_105.push_back(8000); -fm_parameters.insert(std::make_pair(105,fp_105)); - -std::vector fp_106; -fp_106.push_back(0.1+0.0+0.0+3.4+0.0); -fp_106.push_back(9000); -fm_parameters.insert(std::make_pair(106,fp_106)); - -std::vector fp_107; -fp_107.push_back(1.0+0.0+0.0+5.4+0.0); -fp_107.push_back(8000); -fm_parameters.insert(std::make_pair(107,fp_107)); - -std::vector fp_108; -fp_108.push_back(0.5+1.0+0.0+7.3+0.0); -fp_108.push_back(8000); -fm_parameters.insert(std::make_pair(108,fp_108)); - -std::vector fp_121; -fp_121.push_back(0.2+0.0+0.0+0.5+0.65); -fp_121.push_back(8000); -fm_parameters.insert(std::make_pair(121,fp_121)); - -std::vector fp_122; -fp_122.push_back(0.5+0.5+0.0+0.6+1.0); -fp_122.push_back(8000); -fm_parameters.insert(std::make_pair(122,fp_122)); - -std::vector fp_123; -fp_123.push_back(0.3+0.25+0.0+1.45+1.25); -fp_123.push_back(8000); -fm_parameters.insert(std::make_pair(123,fp_123)); - -std::vector fp_124; -fp_124.push_back(1.9+0.3+0.1+3.4+7.1); -fp_124.push_back(8000); -fm_parameters.insert(std::make_pair(124,fp_124)); - -std::vector fp_142; -fp_142.push_back(1.35+2.4+0.75+0.0+3.85); -fp_142.push_back(8000); -fm_parameters.insert(std::make_pair(142,fp_142)); - -std::vector fp_143; -fp_143.push_back(0.45+3.0+0.0+0.0+6.2); -fp_143.push_back(8000); -fm_parameters.insert(std::make_pair(143,fp_143)); - -std::vector fp_144; -fp_144.push_back(0.85+1.15+0.2+0.0+2.55); -fp_144.push_back(8000); -fm_parameters.insert(std::make_pair(144,fp_144)); - -std::vector fp_145; -fp_145.push_back(3.6+2.1+0.0+0.0+2.9); -fp_145.push_back(8000); -fm_parameters.insert(std::make_pair(145,fp_145)); - -std::vector fp_146; -fp_146.push_back(2.9+1.45+0.0+0.0+1.4); -fp_146.push_back(8000); -fm_parameters.insert(std::make_pair(146,fp_146)); - -std::vector fp_147; -fp_147.push_back(3.5+5.3+2.2+0.0+3.4); -fp_147.push_back(8000); -fm_parameters.insert(std::make_pair(147,fp_147)); - -std::vector fp_148; -fp_148.push_back(2.05+3.4+0.85+0.0+4.35); -fp_148.push_back(8000); -fm_parameters.insert(std::make_pair(148,fp_148)); - -std::vector fp_149; -fp_149.push_back(4.5+2.45+0.0+1.55+7.0); -fp_149.push_back(8000); -fm_parameters.insert(std::make_pair(149,fp_149)); - -std::vector fp_161; -fp_161.push_back(0.2+0.9+1.5+0.2+0.9); -fp_161.push_back(8000); -fm_parameters.insert(std::make_pair(161,fp_161)); - -std::vector fp_162; -fp_162.push_back(0.95+1.8+1.25+0.0+0.2); -fp_162.push_back(8000); -fm_parameters.insert(std::make_pair(162,fp_162)); - -std::vector fp_163; -fp_163.push_back(1.1+0.15+0.25+0.65+1.1); -fp_163.push_back(8000); -fm_parameters.insert(std::make_pair(163,fp_163)); - -std::vector fp_164; -fp_164.push_back(4.5+0.0+0.0+0.0+2.0); -fp_164.push_back(8000); -fm_parameters.insert(std::make_pair(164,fp_164)); - -std::vector fp_165; -fp_165.push_back(4.0+4.0+3.0+0.0+3.0); -fp_165.push_back(8000); -fm_parameters.insert(std::make_pair(165,fp_165)); - -std::vector fp_181; -fp_181.push_back(1.0+2.2+3.6+0.0+0.0); -fp_181.push_back(8000); -fm_parameters.insert(std::make_pair(181,fp_181)); - -std::vector fp_182; -fp_182.push_back(1.4+2.3+2.2+0.0+0.0); -fp_182.push_back(8000); -fm_parameters.insert(std::make_pair(182,fp_182)); - -std::vector fp_183; -fp_183.push_back(0.5+2.2+2.8+0.0+0.0); -fp_183.push_back(8000); -fm_parameters.insert(std::make_pair(183,fp_183)); - -std::vector fp_185; -fp_185.push_back(1.15+2.5+4.4+0.0+0.0); -fp_185.push_back(8000); -fm_parameters.insert(std::make_pair(185,fp_185)); - -std::vector fp_186; -fp_186.push_back(2.4+1.2+1.2+0.0+0.0); -fp_186.push_back(8000); -fm_parameters.insert(std::make_pair(186,fp_186)); - -std::vector fp_188; -fp_188.push_back(5.8+1.4+1.1+0.0+0.0); -fp_188.push_back(8000); -fm_parameters.insert(std::make_pair(188,fp_188)); - -std::vector fp_189; -fp_189.push_back(6.65+3.3+4.15+0.0+0.0); -fp_189.push_back(8000); -fm_parameters.insert(std::make_pair(189,fp_189)); + // FM 146 + int F146 = 146; + std::vector p_146; + p_146.push_back(0.3421); + p_146.push_back(0.07793); + p_146.push_back(0.02181); + + std::vector q_146; + q_146.push_back(-1.558); + q_146.push_back(0.0402); + q_146.push_back(2.452); + + p_coeff.insert(std::make_pair(F146, p_146)); + q_coeff.insert(std::make_pair(F146, q_146)); + + // FM 146 + + int F147 = 147; + std::vector p_147; + p_147.push_back(0.9702); + p_147.push_back(0.1314); + p_147.push_back(0.05167); + + std::vector q_147; + q_147.push_back(-1.118); + q_147.push_back(0.0653); + q_147.push_back(1.746); + + p_coeff.insert(std::make_pair(F147, p_147)); + q_coeff.insert(std::make_pair(F147, q_147)); + + // FM 148 + + int F148 = 148; + std::vector p_148; + p_148.push_back(1.44); + p_148.push_back(0.1175); + p_148.push_back(0.07096); + + std::vector q_148; + q_148.push_back(-1.079); + q_148.push_back(0.05247); + q_148.push_back(1.652); + + p_coeff.insert(std::make_pair(F148, p_148)); + q_coeff.insert(std::make_pair(F148, q_148)); + + // FM 149 + + int F149 = 149; + std::vector p_149; + p_149.push_back(0.4281); + p_149.push_back(0.07778); + p_149.push_back(0.02246); + + std::vector q_149; + q_149.push_back(-1.631); + q_149.push_back(0.03661); + q_149.push_back(2.479); + + p_coeff.insert(std::make_pair(F149, p_149)); + q_coeff.insert(std::make_pair(F149, q_149)); + + // FM 161 + + int F161 = 161; + std::vector p_161; + p_161.push_back(1819); + p_161.push_back(1.18); + p_161.push_back(4.999); + + std::vector q_161; + q_161.push_back(-0.3084); + q_161.push_back(6.721); + q_161.push_back(0.3162); + + p_coeff.insert(std::make_pair(F161, p_161)); + q_coeff.insert(std::make_pair(F161, q_161)); + + // FM 162 + + int F162 = 162; + std::vector p_162; + p_162.push_back(2.199); + p_162.push_back(0.2162); + p_162.push_back(0.07223); + + std::vector q_162; + q_162.push_back(-0.9267); + q_162.push_back(0.09552); + q_162.push_back(1.36); + + p_coeff.insert(std::make_pair(F162, p_162)); + q_coeff.insert(std::make_pair(F162, q_162)); + + // FM 163 + + int F163 = 163; + std::vector p_163; + p_163.push_back(4.902); + p_163.push_back(0.2927); + p_163.push_back(0.1805); + + std::vector q_163; + q_163.push_back(-0.6625); + q_163.push_back(0.1263); + q_163.push_back(1.058); + + p_coeff.insert(std::make_pair(F163, p_163)); + q_coeff.insert(std::make_pair(F163, q_163)); + + // FM 164 + + int F164 = 164; + std::vector p_164; + std::vector q_164; + p_164.push_back(0.); + p_164.push_back(0.); + p_164.push_back(-1.); + q_164.push_back(0.); + q_164.push_back(0.); + q_164.push_back(0.); + p_coeff.insert(std::make_pair(F164, p_164)); + q_coeff.insert(std::make_pair(F164, q_164)); + + // FM 165 + + int F165 = 165; + std::vector p_165; + p_165.push_back(0.817); + p_165.push_back(0.07709); + p_165.push_back(0.05013); + + std::vector q_165; + q_165.push_back(-1.425); + q_165.push_back(0.03706); + q_165.push_back(2.275); + + p_coeff.insert(std::make_pair(F165, p_165)); + q_coeff.insert(std::make_pair(F165, q_165)); + + // FM 181 + + int F181 = 181; + std::vector p_181; + p_181.push_back(1804); + p_181.push_back(1.178); + p_181.push_back(4.999); + + std::vector q_181; + q_181.push_back(0.0); + q_181.push_back(0.0); + q_181.push_back(0.0); + + p_coeff.insert(std::make_pair(F181, p_181)); + q_coeff.insert(std::make_pair(F181, q_181)); + + // FM 182 + + int F182 = 182; + std::vector p_182; + p_182.push_back(26.13); + p_182.push_back(0.5009); + p_182.push_back(2.488); + + std::vector q_182; + q_182.push_back(-0.1525); + q_182.push_back(0.4025); + q_182.push_back(0.4484); + + p_coeff.insert(std::make_pair(F182, p_182)); + q_coeff.insert(std::make_pair(F182, q_182)); + + // FM 183 + + int F183 = 183; + std::vector p_183; + p_183.push_back(19.31); + p_183.push_back(0.4546); + p_183.push_back(1.428); + + std::vector q_183; + q_183.push_back(-0.2634); + q_183.push_back(0.2268); + q_183.push_back(0.55); + + p_coeff.insert(std::make_pair(F183, p_183)); + q_coeff.insert(std::make_pair(F183, q_183)); + + // FM 185 + + int F185 = 185; + std::vector p_185; + p_185.push_back(5.518); + p_185.push_back(0.2432); + p_185.push_back(0.2307); + + std::vector q_185; + q_185.push_back(-0.6166); + q_185.push_back(0.1085); + q_185.push_back(1.011); + + p_coeff.insert(std::make_pair(F185, p_185)); + q_coeff.insert(std::make_pair(F185, q_185)); + + // FM 186 + + int F186 = 186; + std::vector p_186; + p_186.push_back(2.956); + p_186.push_back(0.1765); + p_186.push_back(0.09361); + + std::vector q_186; + q_186.push_back(-0.8538); + q_186.push_back(0.07918); + q_186.push_back(1.292); + + p_coeff.insert(std::make_pair(F186, p_186)); + q_coeff.insert(std::make_pair(F186, q_186)); + + // FM 188 + + int F188 = 188; + std::vector p_188; + p_188.push_back(1.736); + p_188.push_back(0.1188); + p_188.push_back(0.06593); + + std::vector q_188; + q_188.push_back(-1.076); + q_188.push_back(0.04976); + q_188.push_back(1.599); + + p_coeff.insert(std::make_pair(F188, p_188)); + q_coeff.insert(std::make_pair(F188, q_188)); + + // FM 189 + + int F189 = 189; + std::vector p_189; + p_189.push_back(0.6251); + p_189.push_back(0.07753); + p_189.push_back(0.02607); + + std::vector q_189; + q_189.push_back(-1.505); + q_189.push_back(0.03052); + q_189.push_back(2.216); + + p_coeff.insert(std::make_pair(F189, p_189)); + q_coeff.insert(std::make_pair(F189, q_189)); + } + + // Fuel Model Parameters for Crown Fire + std::vector fp_101; + fp_101.push_back(0.1 + 0.0 + 0.0 + 0.3 + 0.0); + fp_101.push_back(8000); + fm_parameters.insert(std::make_pair(101, fp_101)); + + std::vector fp_102; + fp_102.push_back(0.1 + 0.0 + 0.0 + 1.0 + 0.0); + fp_102.push_back(8000); + fm_parameters.insert(std::make_pair(102, fp_102)); + + std::vector fp_103; + fp_103.push_back(0.1 + 0.4 + 0.0 + 1.5 + 0.0); + fp_103.push_back(8000); + fm_parameters.insert(std::make_pair(103, fp_103)); + + std::vector fp_104; + fp_104.push_back(0.25 + 0.0 + 0.0 + 1.9 + 0.0); + fp_104.push_back(8000); + fm_parameters.insert(std::make_pair(104, fp_104)); + + std::vector fp_105; + fp_105.push_back(0.4 + 0.0 + 0.0 + 2.5 + 0.0); + fp_105.push_back(8000); + fm_parameters.insert(std::make_pair(105, fp_105)); + + std::vector fp_106; + fp_106.push_back(0.1 + 0.0 + 0.0 + 3.4 + 0.0); + fp_106.push_back(9000); + fm_parameters.insert(std::make_pair(106, fp_106)); + + std::vector fp_107; + fp_107.push_back(1.0 + 0.0 + 0.0 + 5.4 + 0.0); + fp_107.push_back(8000); + fm_parameters.insert(std::make_pair(107, fp_107)); + + std::vector fp_108; + fp_108.push_back(0.5 + 1.0 + 0.0 + 7.3 + 0.0); + fp_108.push_back(8000); + fm_parameters.insert(std::make_pair(108, fp_108)); + + std::vector fp_121; + fp_121.push_back(0.2 + 0.0 + 0.0 + 0.5 + 0.65); + fp_121.push_back(8000); + fm_parameters.insert(std::make_pair(121, fp_121)); + + std::vector fp_122; + fp_122.push_back(0.5 + 0.5 + 0.0 + 0.6 + 1.0); + fp_122.push_back(8000); + fm_parameters.insert(std::make_pair(122, fp_122)); + + std::vector fp_123; + fp_123.push_back(0.3 + 0.25 + 0.0 + 1.45 + 1.25); + fp_123.push_back(8000); + fm_parameters.insert(std::make_pair(123, fp_123)); + + std::vector fp_124; + fp_124.push_back(1.9 + 0.3 + 0.1 + 3.4 + 7.1); + fp_124.push_back(8000); + fm_parameters.insert(std::make_pair(124, fp_124)); + + std::vector fp_142; + fp_142.push_back(1.35 + 2.4 + 0.75 + 0.0 + 3.85); + fp_142.push_back(8000); + fm_parameters.insert(std::make_pair(142, fp_142)); + + std::vector fp_143; + fp_143.push_back(0.45 + 3.0 + 0.0 + 0.0 + 6.2); + fp_143.push_back(8000); + fm_parameters.insert(std::make_pair(143, fp_143)); + + std::vector fp_144; + fp_144.push_back(0.85 + 1.15 + 0.2 + 0.0 + 2.55); + fp_144.push_back(8000); + fm_parameters.insert(std::make_pair(144, fp_144)); + + std::vector fp_145; + fp_145.push_back(3.6 + 2.1 + 0.0 + 0.0 + 2.9); + fp_145.push_back(8000); + fm_parameters.insert(std::make_pair(145, fp_145)); + + std::vector fp_146; + fp_146.push_back(2.9 + 1.45 + 0.0 + 0.0 + 1.4); + fp_146.push_back(8000); + fm_parameters.insert(std::make_pair(146, fp_146)); + + std::vector fp_147; + fp_147.push_back(3.5 + 5.3 + 2.2 + 0.0 + 3.4); + fp_147.push_back(8000); + fm_parameters.insert(std::make_pair(147, fp_147)); + + std::vector fp_148; + fp_148.push_back(2.05 + 3.4 + 0.85 + 0.0 + 4.35); + fp_148.push_back(8000); + fm_parameters.insert(std::make_pair(148, fp_148)); + + std::vector fp_149; + fp_149.push_back(4.5 + 2.45 + 0.0 + 1.55 + 7.0); + fp_149.push_back(8000); + fm_parameters.insert(std::make_pair(149, fp_149)); + + std::vector fp_161; + fp_161.push_back(0.2 + 0.9 + 1.5 + 0.2 + 0.9); + fp_161.push_back(8000); + fm_parameters.insert(std::make_pair(161, fp_161)); + + std::vector fp_162; + fp_162.push_back(0.95 + 1.8 + 1.25 + 0.0 + 0.2); + fp_162.push_back(8000); + fm_parameters.insert(std::make_pair(162, fp_162)); + + std::vector fp_163; + fp_163.push_back(1.1 + 0.15 + 0.25 + 0.65 + 1.1); + fp_163.push_back(8000); + fm_parameters.insert(std::make_pair(163, fp_163)); + + std::vector fp_164; + fp_164.push_back(4.5 + 0.0 + 0.0 + 0.0 + 2.0); + fp_164.push_back(8000); + fm_parameters.insert(std::make_pair(164, fp_164)); + + std::vector fp_165; + fp_165.push_back(4.0 + 4.0 + 3.0 + 0.0 + 3.0); + fp_165.push_back(8000); + fm_parameters.insert(std::make_pair(165, fp_165)); + + std::vector fp_181; + fp_181.push_back(1.0 + 2.2 + 3.6 + 0.0 + 0.0); + fp_181.push_back(8000); + fm_parameters.insert(std::make_pair(181, fp_181)); + + std::vector fp_182; + fp_182.push_back(1.4 + 2.3 + 2.2 + 0.0 + 0.0); + fp_182.push_back(8000); + fm_parameters.insert(std::make_pair(182, fp_182)); + + std::vector fp_183; + fp_183.push_back(0.5 + 2.2 + 2.8 + 0.0 + 0.0); + fp_183.push_back(8000); + fm_parameters.insert(std::make_pair(183, fp_183)); + + std::vector fp_185; + fp_185.push_back(1.15 + 2.5 + 4.4 + 0.0 + 0.0); + fp_185.push_back(8000); + fm_parameters.insert(std::make_pair(185, fp_185)); + + std::vector fp_186; + fp_186.push_back(2.4 + 1.2 + 1.2 + 0.0 + 0.0); + fp_186.push_back(8000); + fm_parameters.insert(std::make_pair(186, fp_186)); + + std::vector fp_188; + fp_188.push_back(5.8 + 1.4 + 1.1 + 0.0 + 0.0); + fp_188.push_back(8000); + fm_parameters.insert(std::make_pair(188, fp_188)); + + std::vector fp_189; + fp_189.push_back(6.65 + 3.3 + 4.15 + 0.0 + 0.0); + fp_189.push_back(8000); + fm_parameters.insert(std::make_pair(189, fp_189)); } +float +rate_of_spread_s(inputs* data, fuel_coefs* ptr, main_outs* at) +{ + float p1, p2, p3, ws; + p1 = p_coeff[data->nftype][0]; + p2 = p_coeff[data->nftype][1]; + p3 = p_coeff[data->nftype][2]; + // se = slope_effect(inp); + ws = data->ws; + at->rss = 1.0 / (p1 * exp(-p2 * ws) + p3); -float rate_of_spread_s(inputs *data, fuel_coefs *ptr, main_outs *at) - { - float p1, p2, p3, ws ; - - p1 = p_coeff[data->nftype][0]; - p2 = p_coeff[data->nftype][1]; - p3 = p_coeff[data->nftype][2]; - //se = slope_effect(inp); - ws = data->ws; - at->rss = 1.0 / (p1 * exp(-p2 * ws) + p3); - - return at->rss * (at->rss >= 0); - - } + return at->rss * (at->rss >= 0); +} -float flankfire_ros_s(float ros,float bros,float lb) - { - return ((ros + bros) / ( lb * 2.0)); - } +float +flankfire_ros_s(float ros, float bros, float lb) +{ + return ((ros + bros) / (lb * 2.0)); +} /* ----------------- Length-to-Breadth --------------------------*/ -float l_to_b(float ws) - { - //if(strncmp(ft,"O1",2)==0)return( ws<1.0 ? 1.0 : (1.1*pow(ws,0.464))); +float +l_to_b(float ws) +{ + // if(strncmp(ft,"O1",2)==0)return( ws<1.0 ? 1.0 : (1.1*pow(ws,0.464))); float alpha, beta, factor; alpha = 0.2566; beta = -0.1548; factor = 1000.0 / 3600.0; return pow((0.936 * exp(alpha * factor * ws) + 0.461 * exp(beta * factor * ws) - 0.397), 0.45); - } +} /* ----------------- Back Rate of Spread --------------------------*/ -float backfire_ros_s(main_outs *at, snd_outs *sec) - { +float +backfire_ros_s(main_outs* at, snd_outs* sec) +{ float hb, bros, lb; - //lb = l_to_b(data->fueltype,at->wsv); + // lb = l_to_b(data->fueltype,at->wsv); lb = sec->lb; - hb = (lb + sqrt(pow(lb,2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); + hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); bros = at->rss / hb; - + return bros * (bros >= 0); - } - -float flame_length(inputs *data, fuel_coefs *ptr) - { - float q1, q2, q3, fl, ws; - - ws = data->ws; - q1 = q_coeff[data->nftype][0]; - q2 = q_coeff[data->nftype][1]; - q3 = q_coeff[data->nftype][2]; - - fl = pow(q1 * exp(-q2 * ws) + q3, 2); - return fl; - } - -float angleFL(inputs *data, fuel_coefs *ptr) - { - float angle, fl, y, ws; - ws = data->ws; - fl = flame_length(data, ptr); - y = 10.0 / 36.0 * ws; - - angle = atan(2.24 * sqrt(fl / pow(y, 2))); - return angle; - } - -float flame_height(inputs *data, fuel_coefs *ptr) - { - float fh, phi; - phi = angleFL(data, ptr); - fh = flame_length(data, ptr) * sin(phi); - return fh; - } - - -float byram_intensity(main_outs* at, fuel_coefs* ptr) { - float fl, ib; - fl = at->fl; - ib = 259.833 * pow(fl, 2.174); - ib=std::ceil(ib * 100.0) / 100.0; - return ib; } -int fmc_scen(inputs* data) { - int fmc; - fmc= data->FMC; - return fmc; +float +flame_length(inputs* data, fuel_coefs* ptr) +{ + float q1, q2, q3, fl, ws; + + ws = data->ws; + q1 = q_coeff[data->nftype][0]; + q2 = q_coeff[data->nftype][1]; + q3 = q_coeff[data->nftype][2]; + fl = pow(q1 * exp(-q2 * ws) + q3, 2); + return fl; } -bool fire_type(inputs* data, main_outs* at) +float +angleFL(inputs* data, fuel_coefs* ptr) { - float intensity, critical_intensity, cbh; - int fmc; - bool crownFire = false; + float angle, fl, y, ws; + ws = data->ws; + fl = flame_length(data, ptr); + y = 10.0 / 36.0 * ws; + + angle = atan(2.24 * sqrt(fl / pow(y, 2))); + return angle; +} - intensity = at->sfi; - cbh = data->cbh; - fmc = fmc_scen(data); - critical_intensity = pow((0.01 * cbh * (460 + 25.9 * fmc)), 1.5); +float +flame_height(inputs* data, fuel_coefs* ptr) +{ + float fh, phi; + phi = angleFL(data, ptr); + fh = flame_length(data, ptr) * sin(phi); + return fh; +} - if ((intensity > critical_intensity) && cbh != 0) crownFire = true; +float +byram_intensity(main_outs* at, fuel_coefs* ptr) +{ + float fl, ib; + fl = at->fl; + ib = 259.833 * pow(fl, 2.174); + ib = std::ceil(ib * 100.0) / 100.0; + return ib; +} - return crownFire; +int +fmc_scen(inputs* data) +{ + int fmc; + fmc = data->FMC; + return fmc; } +bool +fire_type(inputs* data, main_outs* at) +{ + float intensity, critical_intensity, cbh; + int fmc; + bool crownFire = false; -float rate_of_spread10(inputs *data, arguments *args) - { - // FM 10 coef - float p1 = 0.2802, p2 = 0.07786, p3 = 0.01123; - float ros, ros10, ws, ffros, fcbd, fccf; + intensity = at->sfi; + cbh = data->cbh; + fmc = fmc_scen(data); + critical_intensity = pow((0.01 * cbh * (460 + 25.9 * fmc)), 1.5); - ffros = args->ROS10Factor; - fcbd = args->CBDFactor; - fccf = args->CCFFactor; - - ws = data->ws; - ros10 = 1. / (p1 * exp(-p2 * ws) + p3); - ros = ffros * ros10 + fccf * data->ccf + fcbd * args->CBDFactor; - - return(ros); - } + if ((intensity > critical_intensity) && cbh != 0) + crownFire = true; + return crownFire; +} -float final_rate_of_spread10(inputs *data, main_outs* at) - { - float ros_active, ros_final, ros; +float +rate_of_spread10(inputs* data, arguments* args) +{ + // FM 10 coef + float p1 = 0.2802, p2 = 0.07786, p3 = 0.01123; + float ros, ros10, ws, ffros, fcbd, fccf; + + ffros = args->ROS10Factor; + fcbd = args->CBDFactor; + fccf = args->CCFFactor; + + ws = data->ws; + ros10 = 1. / (p1 * exp(-p2 * ws) + p3); + ros = ffros * ros10 + fccf * data->ccf + fcbd * args->CBDFactor; + + return (ros); +} + +float +final_rate_of_spread10(inputs* data, main_outs* at) +{ + float ros_active, ros_final, ros; ros = at->rss; - ros_active=at->ros_active; - ros_final = ros + at->cfb * (ros_active - ros); - return(ros_final); - } - -float backfire_ros10_s(fire_struc *hptr, snd_outs *sec) - { + ros_active = at->ros_active; + ros_final = ros + at->cfb * (ros_active - ros); + return (ros_final); +} + +float +backfire_ros10_s(fire_struc* hptr, snd_outs* sec) +{ float hb, bros, lb; lb = sec->lb; - hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); + hb = (lb + sqrt(pow(lb, 2) - 1.0)) / (lb - sqrt(pow(lb, 2) - 1.0)); bros = hptr->ros / hb; - + return bros; - } +} -float crownfractionburn(inputs* data, main_outs* at) { //generar output de cfb +float +crownfractionburn(inputs* data, main_outs* at) +{ // generar output de cfb float a, cbd, ros, ros0, H, wa, i0, cbh, FMC, cfb; - FMC = fmc_scen(data);; //modificar para ingresar manualmente + FMC = fmc_scen(data); + ; // modificar para ingresar manualmente cbh = data->cbh; i0 = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); wa = fm_parameters[data->nftype][0]; - H = fm_parameters[data->nftype][1]; + H = fm_parameters[data->nftype][1]; cbd = data->cbd; ros0 = 60 * i0 / (H * wa); ros = at->rss; - if (cbd != 0) { + if (cbd != 0) + { a = -log(0.1) / (0.9 * (3.0 / cbd - ros0)); - //a=0.23; + // a=0.23; + } + else + { + a = 0.23; } - else { - a=0.23; + cfb = 1 - exp(-a * (ros - ros0)); + if (cfb < 0) + { + cfb = 0; } - cfb=1 - exp(-a * (ros - ros0)); - if (cfb<0){ - cfb=0; - } return cfb; } - -bool checkActive(inputs * data,main_outs* at) //En s&b se usa fm10 +bool +checkActive(inputs* data, main_outs* at) // En s&b se usa fm10 { - float rac, cbd,H,wa,i0,cbh,fmc; + float rac, cbd, H, wa, i0, cbh, fmc; bool active; - //rac = at->ros_active; - fmc = fmc_scen(data);; //modificar para ingresar manualmente + // rac = at->ros_active; + fmc = fmc_scen(data); + ; // modificar para ingresar manualmente cbh = data->cbh; i0 = pow((0.01 * cbh * (460 + 25.9 * fmc)), 1.5); wa = fm_parameters[data->nftype][0]; - H = fm_parameters[data->nftype][1]; + H = fm_parameters[data->nftype][1]; cbd = data->cbd; - rac = 60 * i0 / (H * wa); //rate active crown + rac = 60 * i0 / (H * wa); // rate active crown - active=cbd*rac>=3; + active = cbd * rac >= 3; return active; } - - void calculate_s(inputs *data, fuel_coefs * ptr,arguments *args ,main_outs *at, snd_outs *sec, fire_struc *hptr, fire_struc *fptr,fire_struc *bptr,bool & activeCrown) +void +calculate_s(inputs* data, + fuel_coefs* ptr, + arguments* args, + main_outs* at, + snd_outs* sec, + fire_struc* hptr, + fire_struc* fptr, + fire_struc* bptr, + bool& activeCrown) { - // Hack: Initialize coefficients - initialize_coeff(args->scenario); - - // Aux - float ros, bros, lb, fros; - bool crownFire=false; + // Hack: Initialize coefficients + initialize_coeff(args->scenario); + + // Aux + float ros, bros, lb, fros; + bool crownFire = false; // Populate fuel coefs struct - //ptr->fueltype = data->fueltype; - if (args->verbose){ - std::cout << "Populate fuel types " << std::endl; - std::cout << "NfTypes:" << data->nftype << std::endl; - std::cout << "scen:" << args->scenario << std::endl; - } - ptr->p1 = p_coeff[data->nftype][0]; + // ptr->fueltype = data->fueltype; + if (args->verbose) + { + std::cout << "Populate fuel types " << std::endl; + std::cout << "NfTypes:" << data->nftype << std::endl; + std::cout << "scen:" << args->scenario << std::endl; + } + ptr->p1 = p_coeff[data->nftype][0]; ptr->p2 = p_coeff[data->nftype][1]; ptr->p3 = p_coeff[data->nftype][2]; ptr->q1 = q_coeff[data->nftype][0]; ptr->q2 = q_coeff[data->nftype][1]; ptr->q3 = q_coeff[data->nftype][2]; - ptr->nftype = data->nftype; - + ptr->nftype = data->nftype; + // Step 1: Calculate HROS (surface) at->rss = rate_of_spread_s(data, ptr, at); hptr->rss = at->rss; - + // Step 2: Calculate Length-to-breadth sec->lb = l_to_b(data->ws); - + // Step 3: Calculate BROS (surface) bptr->rss = backfire_ros_s(at, sec); - + // Step 4: Calculate central FROS (surface) fptr->rss = flankfire_ros_s(hptr->rss, bptr->rss, sec->lb); - + // Step 5: Ellipse components at->a = (hptr->rss + bptr->rss) / 2.; - at->b = (hptr->rss + bptr->rss) / (2. * sec->lb); - at->c = (hptr->rss - bptr->rss) / 2.; - + at->b = (hptr->rss + bptr->rss) / (2. * sec->lb); + at->c = (hptr->rss - bptr->rss) / 2.; + // Step 6: Flame Length at->fl = flame_length(data, ptr); - + // Step 7: Flame angle at->angle = angleFL(data, ptr); - - // Step 8: Flame Height + + // Step 8: Flame Height at->fh = flame_height(data, ptr); - - // Step 9: Byram Intensity - at->sfi = byram_intensity(at, ptr); - - // Step 10: Criterion for Crown Fire Initiation (no init if user does not want to include it) - if (args->AllowCROS && data->cbh!=0 && data->cbd!=0) { - if (activeCrown){ - at->ros_active=rate_of_spread10(data,args); - if (!checkActive(data,at)) { - activeCrown=false; - } - } - else{ - crownFire=fire_type(data,at); - if(args->verbose){ - cout << "Checking crown Fire conditions " << crownFire << "\n"; - - } - } - } - else { - crownFire = false; - activeCrown=false; - } - - // If we have Crown fire, update the ROSs - if (crownFire){ - at->ros_active=rate_of_spread10(data,args); - at->cfb = crownfractionburn(data, at); - - hptr->ros = final_rate_of_spread10(data,at); - at->rss=hptr->ros; - bptr->ros = backfire_ros10_s(hptr,sec); - fptr->ros = flankfire_ros_s(hptr->ros, bptr->ros, sec->lb); - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n"; - cout << "bptr->ros = " << bptr->ros << "\n"; - cout << "fptr->ros = " << fptr->ros << "\n"; - } - - at->a = (hptr->ros + bptr->ros) / 2.; - at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); - at->c = (hptr->ros - bptr->rss) / 2; - at->crown = 1; - activeCrown=true; + + // Step 9: Byram Intensity + at->sfi = byram_intensity(at, ptr); + + // Step 10: Criterion for Crown Fire Initiation (no init if user does not + // want to include it) + if (args->AllowCROS && data->cbh != 0 && data->cbd != 0) + { + if (activeCrown) + { + at->ros_active = rate_of_spread10(data, args); + if (!checkActive(data, at)) + { + activeCrown = false; + } + } + else + { + crownFire = fire_type(data, at); + if (args->verbose) + { + cout << "Checking crown Fire conditions " << crownFire << "\n"; + } + } + } + else + { + crownFire = false; + activeCrown = false; } - else if (activeCrown){ - at->cfb = crownfractionburn(data, at); //lo calculamos igual porque lo necesitamos para el output - hptr->ros = at->ros_active; - at->rss=hptr->ros; - bptr->ros = backfire_ros10_s(hptr,sec); - fptr->ros = flankfire_ros_s(hptr->ros, bptr->ros, sec->lb); - - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n"; - cout << "bptr->ros = " << bptr->ros << "\n"; - cout << "fptr->ros = " << fptr->ros << "\n"; - } - - at->a = (hptr->ros + bptr->ros) / 2.; - at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); - at->c = (hptr->ros - bptr->rss) / 2; - at->crown = 1; - //std::cout << "ros_activo: " <ros << std::endl; + // If we have Crown fire, update the ROSs + if (crownFire) + { + at->ros_active = rate_of_spread10(data, args); + at->cfb = crownfractionburn(data, at); + + hptr->ros = final_rate_of_spread10(data, at); + at->rss = hptr->ros; + bptr->ros = backfire_ros10_s(hptr, sec); + fptr->ros = flankfire_ros_s(hptr->ros, bptr->ros, sec->lb); + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } + + at->a = (hptr->ros + bptr->ros) / 2.; + at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); + at->c = (hptr->ros - bptr->rss) / 2; + at->crown = 1; + activeCrown = true; } - - // Otherwise, use the surface values - else{ - at->crown=0; - at->cfb=0; + else if (activeCrown) + { + at->cfb = crownfractionburn(data, + at); // lo calculamos igual porque lo necesitamos para el output + hptr->ros = at->ros_active; + at->rss = hptr->ros; + bptr->ros = backfire_ros10_s(hptr, sec); + fptr->ros = flankfire_ros_s(hptr->ros, bptr->ros, sec->lb); + + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } + + at->a = (hptr->ros + bptr->ros) / 2.; + at->b = (hptr->ros + bptr->ros) / (2. * sec->lb); + at->c = (hptr->ros - bptr->rss) / 2; + at->crown = 1; + // std::cout << "ros_activo: " <ros << std::endl; + } + + // Otherwise, use the surface values + else + { + at->crown = 0; + at->cfb = 0; hptr->ros = hptr->rss; - bptr->ros = bptr->rss; + bptr->ros = bptr->rss; fptr->ros = fptr->rss; - if (args->verbose){ - cout << "hptr->ros = " << hptr->ros << "\n"; - cout << "bptr->ros = " << bptr->ros << "\n"; - cout << "fptr->ros = " << fptr->ros << "\n"; - } - + if (args->verbose) + { + cout << "hptr->ros = " << hptr->ros << "\n"; + cout << "bptr->ros = " << bptr->ros << "\n"; + cout << "fptr->ros = " << fptr->ros << "\n"; + } + } + // if (hptr->ros>100){ + // cout << "hptr->rss = " << hptr->ros << "\n"; + + //} + + if (args->verbose) + { + cout << "--------------- Inputs --------------- \n"; + cout << "ws = " << data->ws << "\n"; + cout << "coef data->cbh = " << data->cbh << "\n"; + cout << "coef ptr->p1 = " << ptr->p1 << "\n"; + cout << "coef ptr->p2 = " << ptr->p2 << "\n"; + cout << "coef ptr->p3 = " << ptr->p3 << "\n"; + cout << "coef ptr->q1 = " << ptr->q1 << "\n"; + cout << "coef ptr->q2 = " << ptr->q2 << "\n"; + cout << "coef ptr->q3 = " << ptr->q3 << "\n"; + cout << "\n"; + + cout << "---------------- Outputs --------------- \n"; + cout << "at->rss = " << at->rss << "\n"; + cout << "hptr->rss = " << hptr->rss << "\n"; + cout << "lb = " << sec->lb << "\n"; + cout << "bptr->rss = " << bptr->rss << "\n"; + cout << "fptr->rss = " << fptr->rss << "\n"; + cout << "axis a = " << at->a << "\n"; + cout << "axis b = " << at->b << "\n"; + cout << "axis c = " << at->c << "\n"; + cout << "fl = " << at->fl << "\n"; + cout << "angle = " << at->angle << "\n"; + cout << "fh = " << at->fh << "\n"; + cout << "Crown Fire = " << crownFire << "\n"; } - //if (hptr->ros>100){ - //cout << "hptr->rss = " << hptr->ros << "\n"; - - //} - - if (args->verbose){ - cout << "--------------- Inputs --------------- \n"; - cout << "ws = " << data->ws << "\n"; - cout << "coef data->cbh = " << data->cbh << "\n"; - cout << "coef ptr->p1 = " << ptr->p1 << "\n"; - cout << "coef ptr->p2 = " << ptr->p2 << "\n"; - cout << "coef ptr->p3 = " << ptr->p3 << "\n"; - cout << "coef ptr->q1 = " << ptr->q1 << "\n"; - cout << "coef ptr->q2 = " << ptr->q2 << "\n"; - cout << "coef ptr->q3 = " << ptr->q3 << "\n"; - cout << "\n"; - - cout << "---------------- Outputs --------------- \n"; - cout << "at->rss = " << at->rss << "\n"; - cout << "hptr->rss = " << hptr->rss << "\n"; - cout << "lb = " << sec->lb << "\n"; - cout << "bptr->rss = " << bptr->rss << "\n"; - cout << "fptr->rss = " << fptr->rss << "\n"; - cout << "axis a = " << at->a << "\n"; - cout << "axis b = " << at->b << "\n"; - cout << "axis c = " << at->c << "\n"; - cout << "fl = " << at->fl << "\n"; - cout << "angle = " << at->angle << "\n"; - cout << "fh = " << at->fh << "\n"; - cout << "Crown Fire = " << crownFire << "\n"; - } } -void determine_destiny_metrics_s(inputs* data, fuel_coefs* ptr,arguments *args, main_outs* metrics) { - // Hack: Initialize coefficients - initialize_coeff(args->scenario); - - // Aux - float ros=0, bros=0, lb=0, fros=0; - bool crownFire = false; - ptr->q1 = q_coeff[data->nftype][0]; - ptr->q2 = q_coeff[data->nftype][1]; - ptr->q3 = q_coeff[data->nftype][2]; - ptr->nftype = data->nftype; - // Step 6: Flame Length - metrics->fl = flame_length(data, ptr); - // Step 9: Byram Intensity - metrics->sfi = byram_intensity(metrics, ptr); - //Set cfb value for no crown fire scenario - metrics->cfb =0; - // Step 10: Criterion for Crown Fire Initiation (no init if user does not want to include it) - if (args->AllowCROS) { +void +determine_destiny_metrics_s(inputs* data, fuel_coefs* ptr, arguments* args, main_outs* metrics) +{ + // Hack: Initialize coefficients + initialize_coeff(args->scenario); + + // Aux + float ros = 0, bros = 0, lb = 0, fros = 0; + bool crownFire = false; + ptr->q1 = q_coeff[data->nftype][0]; + ptr->q2 = q_coeff[data->nftype][1]; + ptr->q3 = q_coeff[data->nftype][2]; + ptr->nftype = data->nftype; + // Step 6: Flame Length + metrics->fl = flame_length(data, ptr); + // Step 9: Byram Intensity + metrics->sfi = byram_intensity(metrics, ptr); + // Set cfb value for no crown fire scenario + metrics->cfb = 0; + // Step 10: Criterion for Crown Fire Initiation (no init if user does not + // want to include it) + if (args->AllowCROS) + { crownFire = fire_type(data, metrics); - if (crownFire){ + if (crownFire) + { metrics->cfb = crownfractionburn(data, metrics); - } - if (args->verbose) { + if (args->verbose) + { cout << "Checking crown Fire conditions " << crownFire << "\n"; } } - else { + else + { crownFire = false; } - - - - metrics->crown = crownFire; + metrics->crown = crownFire; } diff --git a/Cell2Fire/FuelModelSpain.h b/Cell2Fire/FuelModelSpain.h index 5f5bb23f..2aa0f8f6 100644 --- a/Cell2Fire/FuelModelSpain.h +++ b/Cell2Fire/FuelModelSpain.h @@ -1,70 +1,77 @@ #ifndef FUELMODELSPAIN #define FUELMODELSPAIN -#include "ReadArgs.h" #include "Cells.h" +#include "ReadArgs.h" #include #include #include #include -#include #include -#include #include +#include #include /* -* Input, Fire, and output structures + * Input, Fire, and output structures + */ + +/* + Functions */ +// Initialize coefficients +void initialize_coeff(int scenario); - /* - Functions - */ - // Initialize coefficients - void initialize_coeff(int scenario); - - // Calculate flank fire -float flankfire_ros_s(float ros, float bros, float lb) ; +// Calculate flank fire +float flankfire_ros_s(float ros, float bros, float lb); // Calculate rate of spread -float rate_of_spread_s(inputs *data, fuel_coefs *ptr, main_outs *at) ; +float rate_of_spread_s(inputs* data, fuel_coefs* ptr, main_outs* at); // Length-to-Breadth ratio float l_to_b(float ws); // BROS -float backfire_ros_s(main_outs *at, snd_outs *sec) ; +float backfire_ros_s(main_outs* at, snd_outs* sec); // Flame length [m]) -float flame_length(inputs *data, fuel_coefs *ptr); +float flame_length(inputs* data, fuel_coefs* ptr); // Angle of the flame w.r.t. horizontal surface (Putnam's) -float angleFL(inputs *data, fuel_coefs *ptr) ; +float angleFL(inputs* data, fuel_coefs* ptr); -// Transformation from FL to FH using angle -float flame_height(inputs *data, fuel_coefs *ptr) ; +// Transformation from FL to FH using angle +float flame_height(inputs* data, fuel_coefs* ptr); -//byram intensity +// byram intensity float byram_intensity(inputs* data, fuel_coefs* ptr); // Type of fire (Crown = 1, SROS = 0) -bool fire_type(inputs *data, fuel_coefs *ptr) ; +bool fire_type(inputs* data, fuel_coefs* ptr); // CROS adjustements -float rate_of_spread10(inputs *data,arguments *args) ; +float rate_of_spread10(inputs* data, arguments* args); -bool checkActive(inputs * data,main_outs* at); +bool checkActive(inputs* data, main_outs* at); float crownfractionburn(inputs* data, main_outs* at); -float final_rate_of_spread10(inputs *data); -// Back fire with CROS -float backfire_ros10_s(fire_struc *hptr, snd_outs *sec) ; +float final_rate_of_spread10(inputs* data); +// Back fire with CROS +float backfire_ros10_s(fire_struc* hptr, snd_outs* sec); // Slope effect -float slope_effect(inputs * data); - -// Main function to populate spread outputs based on inputs provided from main class -void calculate_s(inputs *data, fuel_coefs * ptr,arguments *args, main_outs *at, snd_outs *sec, fire_struc *hptr, fire_struc *fptr,fire_struc *bptr,bool & activeCrown); - -void determine_destiny_metrics_s(inputs* data, fuel_coefs* ptr,arguments *args, main_outs* at); - +float slope_effect(inputs* data); + +// Main function to populate spread outputs based on inputs provided from main +// class +void calculate_s(inputs* data, + fuel_coefs* ptr, + arguments* args, + main_outs* at, + snd_outs* sec, + fire_struc* hptr, + fire_struc* fptr, + fire_struc* bptr, + bool& activeCrown); + +void determine_destiny_metrics_s(inputs* data, fuel_coefs* ptr, arguments* args, main_outs* at); #endif diff --git a/Cell2Fire/Lightning.cpp b/Cell2Fire/Lightning.cpp index a3ef6238..41cf1cb5 100644 --- a/Cell2Fire/Lightning.cpp +++ b/Cell2Fire/Lightning.cpp @@ -1,15 +1,14 @@ #include "Lightning.h" // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include #include #include @@ -17,36 +16,41 @@ using namespace std; /* - Constructor + Constructor */ -Lightning::Lightning(){} +Lightning::Lightning() {} - -int Lightning::Lambda_Simple_Test(int period) { +int +Lightning::Lambda_Simple_Test(int period) +{ // TODO: fix because RNG is bad int selected_week = std::rand() % 12 + 1; return selected_week; } -bool Lightning::Lambda_NH(int period, bool verbose) { +bool +Lightning::Lambda_NH(int period, bool verbose) +{ double fire_rate = 0.5; double alfa_fact = 0.1; - double poisson_mean = (fire_rate / 2.0) * (2.0 + alfa_fact * ((period * period) - (period - 1) * (period - 1) - 2.0)); - double probsNoFire = std::exp(-1 * poisson_mean); // TODO: why do you round? - - // https://stackoverflow.com/a/9879024 - int random_num = ((double) (std::rand()) ) / (RAND_MAX); + double poisson_mean + = (fire_rate / 2.0) * (2.0 + alfa_fact * ((period * period) - (period - 1) * (period - 1) - 2.0)); + double probsNoFire = std::exp(-1 * poisson_mean); // TODO: why do you round? + + // https://stackoverflow.com/a/9879024 + int random_num = ((double)(std::rand())) / (RAND_MAX); return random_num > probsNoFire; } - -bool Lightning::Lambda_H(int period, bool verbose) { +bool +Lightning::Lambda_H(int period, bool verbose) +{ double poisson_mean = 0.5; - double probsNoFire = std::exp(-1 * poisson_mean); // TODO: why do you round? - - // https://stackoverflow.com/a/9879024 - int random_num = ((double) (std::rand()) ) / (RAND_MAX); + double probsNoFire = std::exp(-1 * poisson_mean); // TODO: why do you round? + + // https://stackoverflow.com/a/9879024 + int random_num = ((double)(std::rand())) / (RAND_MAX); return random_num > probsNoFire; -} \ No newline at end of file +} diff --git a/Cell2Fire/Lightning.h b/Cell2Fire/Lightning.h index f33f956b..2f9f5de0 100644 --- a/Cell2Fire/Lightning.h +++ b/Cell2Fire/Lightning.h @@ -2,25 +2,25 @@ #define LIGHTNING // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include using namespace std; -class Lightning { - public: - // Constructor & Methods - Lightning(); - int Lambda_Simple_Test(int period); - bool Lambda_NH(int period, bool verbose); - bool Lambda_H(int period, bool verbose); +class Lightning +{ + public: + // Constructor & Methods + Lightning(); + int Lambda_Simple_Test(int period); + bool Lambda_NH(int period, bool verbose); + bool Lambda_H(int period, bool verbose); }; #endif diff --git a/Cell2Fire/ReadArgs.cpp b/Cell2Fire/ReadArgs.cpp index a49dcd90..bcd03e78 100644 --- a/Cell2Fire/ReadArgs.cpp +++ b/Cell2Fire/ReadArgs.cpp @@ -1,28 +1,27 @@ // Inclusions #include "ReadArgs.h" -#include +#include +#include #include -#include +#include #include #include -#include -#include - - +#include -inline char separator() +inline char +separator() { #if defined _WIN32 || defined __CYGWIN__ - return '\\'; + return '\\'; #else - return '/'; + return '/'; #endif } - -char* getCmdOption(char ** begin, char ** end, const std::string & option) +char* +getCmdOption(char** begin, char** end, const std::string& option) { - char ** itr = std::find(begin, end, option); + char** itr = std::find(begin, end, option); if (itr != end && ++itr != end) { return *itr; @@ -30,574 +29,669 @@ char* getCmdOption(char ** begin, char ** end, const std::string & option) return 0; } -bool cmdOptionExists(char** begin, char** end, const std::string& option) +bool +cmdOptionExists(char** begin, char** end, const std::string& option) { return std::find(begin, end, option) != end; } -void parseArgs(int argc, char* argv[], arguments* args_ptr) +void +parseArgs(int argc, char* argv[], arguments* args_ptr) { - // Help - if (cmdOptionExists(argv, argv + argc, "-h")) { - printf("-------------------------------------------\n Help manual!!! \n-------------------------------------------\n"); - } - - // Empty default - char empty = '\0'; - - - // Strings - //--input-instance-folder - char* input_folder = getCmdOption(argv, argv + argc, "--input-instance-folder"); - if (input_folder) { - printf("InFolder: %s \n", input_folder); - } - else input_folder = ∅ - - //--output-folder - char* output_folder = getCmdOption(argv, argv + argc, "--output-folder"); - if (output_folder) { - printf("OutFolder: %s \n", output_folder); - } - else output_folder = ∅ - - //--weather - char* input_weather = getCmdOption(argv, argv + argc, "--weather"); - if (input_weather) { - printf("WeatherOpt: %s \n", input_weather); - } - else input_weather = ∅ - - //--FirebreakPlan - char* input_hplan = getCmdOption(argv, argv + argc, "--FirebreakCells"); - if (input_hplan) { - printf("FirebreakCells: %s \n", input_hplan); - } - else input_hplan = ∅ - - // Booleans - bool out_messages = false; - bool out_trajectories = false; - bool no_output = false; - bool verbose_input = false; - bool iplog_input = false; - bool input_ignitions = false; - bool out_grids = false; - bool out_fl=false; - bool out_intensity=false; - bool out_ros=false; - bool out_crown = false; - bool out_crown_consumption=false; - bool out_surf_consumption=false; - bool out_finalgrid = false; - bool prom_tuned = false; - bool out_stats = false; - bool bbo_tuning = false; - bool allow_cros = false; - - //--out-messages - if (cmdOptionExists(argv, argv + argc, "--output-messages")) { - out_messages = true; - printf("OutMessages: %d \n", out_messages); - } - - //--fire-behavior - if (cmdOptionExists(argv, argv + argc, "--out-fl")) { - out_fl = true; - printf("OutFlameLength: %d \n", out_fl); - } - //--fire-behavior - if (cmdOptionExists(argv, argv + argc, "--out-intensity")) { - out_intensity = true; - printf("OutIntensity: %d \n", out_intensity); - } - //--fire-behavior - if (cmdOptionExists(argv, argv + argc, "--out-ros")) { - out_ros = true; - printf("OutROS: %d \n", out_ros); - } - //--fire-behavior - if (cmdOptionExists(argv, argv + argc, "--out-crown")) { - out_crown = true; - printf("OutCrown: %d \n", out_crown); - } - - if (cmdOptionExists(argv, argv + argc, "--out-cfb")) { - out_crown_consumption = true; - printf("OutCrownConsumption: %d \n", out_crown_consumption); - } - - if (cmdOptionExists(argv, argv + argc, "--out-sfb")) { - out_surf_consumption = true; - printf("OutSurfaceConsumption: %d \n", out_surf_consumption); - } - - - //--trajectories - //if (cmdOptionExists(argv, argv + argc, "--trajectories")) { - // out_trajectories = true; - // printf("Trajectories: %d \n", out_trajectories); - //} - - //--no-output - //if (cmdOptionExists(argv, argv + argc, "--no-output")) { - // no_output = true; - // printf("noOutput: %d \n", no_output); - //} - - //--verbose - if (cmdOptionExists(argv, argv + argc, "--verbose")) { - verbose_input = true; - printf("verbose: %d \n", verbose_input); - } - - // --ignitionsLog - if (cmdOptionExists(argv, argv + argc, "--ignitionsLog")) { - iplog_input = true; - printf("Ignition Points Log: %d \n", iplog_input); - } - - //--ignitions - if (cmdOptionExists(argv, argv + argc, "--ignitions")) { - input_ignitions = true; - printf("Ignitions: %d \n", input_ignitions); - } - - //--grids - if (cmdOptionExists(argv, argv + argc, "--grids")) { - out_grids = true; - printf("OutputGrids: %d \n", out_grids); - } - - //--final-grid - if (cmdOptionExists(argv, argv + argc, "--final-grid")) { - out_finalgrid = true; - printf("FinalGrid: %d \n", out_finalgrid); - } - - //--Prom_tuned - //if (cmdOptionExists(argv, argv + argc, "--PromTuned")) { - // prom_tuned = true; - // printf("PromTuned: %d \n", prom_tuned); - //} - - //--statistics - //if (cmdOptionExists(argv, argv + argc, "--statistics")) { - // out_stats = true; - // printf("Statistics: %d \n", out_stats); - //} - - //--bbo - if (cmdOptionExists(argv, argv + argc, "--bbo")) { - bbo_tuning = true; - printf("BBOTuning: %d \n", out_stats); - } - - //--cros - if (cmdOptionExists(argv, argv + argc, "--cros")) { - allow_cros = true; - printf("CrownROS: %d \n", allow_cros); - } - - - // Floats and ints - // defaults - int dsim_years = 1; - int dnsims = 1; - int dweather_period_len = 60; - int dmax_fire_periods = 1000; - int dseed = 123; - int diradius = 0; - int dnthreads = 1; - int dfmc=100; - int dscen=3; - float dROS_Threshold= 0.1; - float dHFI_Threshold= 0.1; - float dCROS_Threshold= 0.5; - //float dCROSAct_Threshold= 1.0; - float dROSCV= 0.; - float dHFactor = 1.0; - float dFFactor = 1.0; - float dBFactor = 1.0; - float dEFactor = 1.0; - float dCBDFactor = 0.0; //spain - //float dCBHFactor = 1.0; - float dCCFFactor = 0.0; //spain - float dROS10Factor = 3.34; //spain - float dinput_PeriodLen= 1.; - - // aux - std::string::size_type sz; - - //--sim-years (float) - char * sim_years = getCmdOption(argv, argv + argc, "--sim-years"); - if (sim_years){ + // Help + if (cmdOptionExists(argv, argv + argc, "-h")) + { + printf("-------------------------------------------\n Help " + "manual!!! \n-------------------------------------------\n"); + } + + // Empty default + char empty = '\0'; + + // Strings + //--input-instance-folder + char* input_folder = getCmdOption(argv, argv + argc, "--input-instance-folder"); + if (input_folder) + { + printf("InFolder: %s \n", input_folder); + } + else + input_folder = ∅ + + //--output-folder + char* output_folder = getCmdOption(argv, argv + argc, "--output-folder"); + if (output_folder) + { + printf("OutFolder: %s \n", output_folder); + } + else + output_folder = ∅ + + //--weather + char* input_weather = getCmdOption(argv, argv + argc, "--weather"); + if (input_weather) + { + printf("WeatherOpt: %s \n", input_weather); + } + else + input_weather = ∅ + + //--FirebreakPlan + char* input_hplan = getCmdOption(argv, argv + argc, "--FirebreakCells"); + if (input_hplan) + { + printf("FirebreakCells: %s \n", input_hplan); + } + else + input_hplan = ∅ + + // Booleans + bool out_messages = false; + bool out_trajectories = false; + bool no_output = false; + bool verbose_input = false; + bool iplog_input = false; + bool input_ignitions = false; + bool out_grids = false; + bool out_fl = false; + bool out_intensity = false; + bool out_ros = false; + bool out_crown = false; + bool out_crown_consumption = false; + bool out_surf_consumption = false; + bool out_finalgrid = false; + bool prom_tuned = false; + bool out_stats = false; + bool bbo_tuning = false; + bool allow_cros = false; + + //--out-messages + if (cmdOptionExists(argv, argv + argc, "--output-messages")) + { + out_messages = true; + printf("OutMessages: %d \n", out_messages); + } + + //--fire-behavior + if (cmdOptionExists(argv, argv + argc, "--out-fl")) + { + out_fl = true; + printf("OutFlameLength: %d \n", out_fl); + } + //--fire-behavior + if (cmdOptionExists(argv, argv + argc, "--out-intensity")) + { + out_intensity = true; + printf("OutIntensity: %d \n", out_intensity); + } + //--fire-behavior + if (cmdOptionExists(argv, argv + argc, "--out-ros")) + { + out_ros = true; + printf("OutROS: %d \n", out_ros); + } + //--fire-behavior + if (cmdOptionExists(argv, argv + argc, "--out-crown")) + { + out_crown = true; + printf("OutCrown: %d \n", out_crown); + } + + if (cmdOptionExists(argv, argv + argc, "--out-cfb")) + { + out_crown_consumption = true; + printf("OutCrownConsumption: %d \n", out_crown_consumption); + } + + if (cmdOptionExists(argv, argv + argc, "--out-sfb")) + { + out_surf_consumption = true; + printf("OutSurfaceConsumption: %d \n", out_surf_consumption); + } + + //--trajectories + // if (cmdOptionExists(argv, argv + argc, "--trajectories")) { + // out_trajectories = true; + // printf("Trajectories: %d \n", out_trajectories); + //} + + //--no-output + // if (cmdOptionExists(argv, argv + argc, "--no-output")) { + // no_output = true; + // printf("noOutput: %d \n", no_output); + //} + + //--verbose + if (cmdOptionExists(argv, argv + argc, "--verbose")) + { + verbose_input = true; + printf("verbose: %d \n", verbose_input); + } + + // --ignitionsLog + if (cmdOptionExists(argv, argv + argc, "--ignitionsLog")) + { + iplog_input = true; + printf("Ignition Points Log: %d \n", iplog_input); + } + + //--ignitions + if (cmdOptionExists(argv, argv + argc, "--ignitions")) + { + input_ignitions = true; + printf("Ignitions: %d \n", input_ignitions); + } + + //--grids + if (cmdOptionExists(argv, argv + argc, "--grids")) + { + out_grids = true; + printf("OutputGrids: %d \n", out_grids); + } + + //--final-grid + if (cmdOptionExists(argv, argv + argc, "--final-grid")) + { + out_finalgrid = true; + printf("FinalGrid: %d \n", out_finalgrid); + } + + //--Prom_tuned + // if (cmdOptionExists(argv, argv + argc, "--PromTuned")) { + // prom_tuned = true; + // printf("PromTuned: %d \n", prom_tuned); + //} + + //--statistics + // if (cmdOptionExists(argv, argv + argc, "--statistics")) { + // out_stats = true; + // printf("Statistics: %d \n", out_stats); + //} + + //--bbo + if (cmdOptionExists(argv, argv + argc, "--bbo")) + { + bbo_tuning = true; + printf("BBOTuning: %d \n", out_stats); + } + + //--cros + if (cmdOptionExists(argv, argv + argc, "--cros")) + { + allow_cros = true; + printf("CrownROS: %d \n", allow_cros); + } + + // Floats and ints + // defaults + int dsim_years = 1; + int dnsims = 1; + int dweather_period_len = 60; + int dmax_fire_periods = 1000; + int dseed = 123; + int diradius = 0; + int dnthreads = 1; + int dfmc = 100; + int dscen = 3; + float dROS_Threshold = 0.1; + float dHFI_Threshold = 0.1; + float dCROS_Threshold = 0.5; + // float dCROSAct_Threshold= 1.0; + float dROSCV = 0.; + float dHFactor = 1.0; + float dFFactor = 1.0; + float dBFactor = 1.0; + float dEFactor = 1.0; + float dCBDFactor = 0.0; // spain + // float dCBHFactor = 1.0; + float dCCFFactor = 0.0; // spain + float dROS10Factor = 3.34; // spain + float dinput_PeriodLen = 1.; + + // aux + std::string::size_type sz; + + //--sim-years (float) + char* sim_years = getCmdOption(argv, argv + argc, "--sim-years"); + if (sim_years) + { printf("TotalYears: %s \n", sim_years); - args_ptr->TotalYears = std::stoi (sim_years ,&sz); + args_ptr->TotalYears = std::stoi(sim_years, &sz); } - else args_ptr->TotalYears = dsim_years; - - //--nsims - char * input_nsims = getCmdOption(argv, argv + argc, "--nsims"); - if (input_nsims){ + else + args_ptr->TotalYears = dsim_years; + + //--nsims + char* input_nsims = getCmdOption(argv, argv + argc, "--nsims"); + if (input_nsims) + { printf("TotalSims: %s \n", input_nsims); - args_ptr->TotalSims = std::stoi (input_nsims ,&sz); - } - else args_ptr->TotalSims = dnsims; - - - //--nsims - char * simulator_option = getCmdOption(argv, argv + argc, "--sim"); - if (simulator_option){ - std::string s=simulator_option; - if (s!="S" && s!="K" && s!="C"){ - printf("%s Simulator Option not recognized or not developed, using S&B as default!!! \n", simulator_option); - args_ptr->Simulator=simulator_option; - } - else{ - printf("Simulator: %s \n", simulator_option); - args_ptr->Simulator = simulator_option; - } - } - else { - printf("No Simulator Option Selected, using S&B as default!!! \n"); - args_ptr->Simulator = "S";} - - - //--Weather-Period-Length - char * weather_period_len = getCmdOption(argv, argv + argc, "--Weather-Period-Length"); - if (weather_period_len){ + args_ptr->TotalSims = std::stoi(input_nsims, &sz); + } + else + args_ptr->TotalSims = dnsims; + + //--nsims + char* simulator_option = getCmdOption(argv, argv + argc, "--sim"); + if (simulator_option) + { + std::string s = simulator_option; + if (s != "S" && s != "K" && s != "C") + { + printf("%s Simulator Option not recognized or not developed, using " + "S&B as default!!! \n", + simulator_option); + args_ptr->Simulator = simulator_option; + } + else + { + printf("Simulator: %s \n", simulator_option); + args_ptr->Simulator = simulator_option; + } + } + else + { + printf("No Simulator Option Selected, using S&B as default!!! \n"); + args_ptr->Simulator = "S"; + } + + //--Weather-Period-Length + char* weather_period_len = getCmdOption(argv, argv + argc, "--Weather-Period-Length"); + if (weather_period_len) + { printf("WeatherPeriodLength: %s \n", weather_period_len); - args_ptr->MinutesPerWP = std::stoi (weather_period_len ,&sz); - } - else args_ptr->MinutesPerWP = dweather_period_len; - - //--nweathers - char * nweathers = getCmdOption(argv, argv + argc, "--nweathers"); - if (nweathers){ - args_ptr->NWeatherFiles = std::stoi (nweathers ,&sz); - } - else{ - //std::cout << "No NWeatherFiles specified " << input_weather << std::endl; - if (std::string(input_weather) == "random") { - //std::cout << "Counting" << std::endl; - std::string input_string = input_folder; - args_ptr->NWeatherFiles = countWeathers(input_string + "/Weathers"); - } - else { - ///std::cout << "No NWeatherFiles specified 1 default" << std::endl; - args_ptr->NWeatherFiles = 1; - } - } - - //--Fire-Period-Length - char * input_PeriodLen = getCmdOption(argv, argv + argc, "--Fire-Period-Length"); - if (input_PeriodLen){ + args_ptr->MinutesPerWP = std::stoi(weather_period_len, &sz); + } + else + args_ptr->MinutesPerWP = dweather_period_len; + + //--nweathers + char* nweathers = getCmdOption(argv, argv + argc, "--nweathers"); + if (nweathers) + { + args_ptr->NWeatherFiles = std::stoi(nweathers, &sz); + } + else + { + // std::cout << "No NWeatherFiles specified " << input_weather << + // std::endl; + if (std::string(input_weather) == "random") + { + // std::cout << "Counting" << std::endl; + std::string input_string = input_folder; + args_ptr->NWeatherFiles = countWeathers(input_string + "/Weathers"); + } + else + { + /// std::cout << "No NWeatherFiles specified 1 default" << std::endl; + args_ptr->NWeatherFiles = 1; + } + } + + //--Fire-Period-Length + char* input_PeriodLen = getCmdOption(argv, argv + argc, "--Fire-Period-Length"); + if (input_PeriodLen) + { printf("FirePeriodLength: %s \n", input_PeriodLen); - if (std::stof (input_PeriodLen ,&sz) <= args_ptr->MinutesPerWP){ - args_ptr->FirePeriodLen = std::stof (input_PeriodLen ,&sz); - } - else args_ptr->FirePeriodLen = args_ptr->MinutesPerWP; - } - else args_ptr->FirePeriodLen = dinput_PeriodLen; - - //--IgnitionRad - char * input_igrad = getCmdOption(argv, argv + argc, "--IgnitionRad"); - if (input_igrad){ + if (std::stof(input_PeriodLen, &sz) <= args_ptr->MinutesPerWP) + { + args_ptr->FirePeriodLen = std::stof(input_PeriodLen, &sz); + } + else + args_ptr->FirePeriodLen = args_ptr->MinutesPerWP; + } + else + args_ptr->FirePeriodLen = dinput_PeriodLen; + + //--IgnitionRad + char* input_igrad = getCmdOption(argv, argv + argc, "--IgnitionRad"); + if (input_igrad) + { printf("IgnitionRadius: %s \n", input_igrad); - args_ptr->IgnitionRadius = std::stoi (input_igrad ,&sz); - } - else args_ptr->IgnitionRadius = diradius; - - - //--fmc - char * input_fmc = getCmdOption(argv, argv + argc, "--fmc"); - if (input_fmc){ + args_ptr->IgnitionRadius = std::stoi(input_igrad, &sz); + } + else + args_ptr->IgnitionRadius = diradius; + + //--fmc + char* input_fmc = getCmdOption(argv, argv + argc, "--fmc"); + if (input_fmc) + { printf("fmc: %s \n", input_fmc); - args_ptr->FMC = std::stoi (input_fmc ,&sz); + args_ptr->FMC = std::stoi(input_fmc, &sz); } - else args_ptr->FMC = dfmc; - - //--scenario - char * input_scenario = getCmdOption(argv, argv + argc, "--scenario"); - if (input_scenario){ + else + args_ptr->FMC = dfmc; + + //--scenario + char* input_scenario = getCmdOption(argv, argv + argc, "--scenario"); + if (input_scenario) + { printf("scenario: %s \n", input_scenario); - args_ptr->scenario = std::stoi (input_scenario ,&sz); - } - else args_ptr->scenario = dscen; - - - //--ROS-Threshold - char * ROS_Threshold = getCmdOption(argv, argv + argc, "--ROS-Threshold"); - if (ROS_Threshold){ + args_ptr->scenario = std::stoi(input_scenario, &sz); + } + else + args_ptr->scenario = dscen; + + //--ROS-Threshold + char* ROS_Threshold = getCmdOption(argv, argv + argc, "--ROS-Threshold"); + if (ROS_Threshold) + { printf("ROSThreshold: %s \n", ROS_Threshold); - args_ptr->ROSThreshold = std::stof (ROS_Threshold ,&sz); + args_ptr->ROSThreshold = std::stof(ROS_Threshold, &sz); } - else args_ptr->ROSThreshold = dROS_Threshold; - - //--CROS-Threshold - char * CROS_Threshold = getCmdOption(argv, argv + argc, "--CROS-Threshold"); - if (CROS_Threshold){ + else + args_ptr->ROSThreshold = dROS_Threshold; + + //--CROS-Threshold + char* CROS_Threshold = getCmdOption(argv, argv + argc, "--CROS-Threshold"); + if (CROS_Threshold) + { printf("CROSThreshold: %s \n", CROS_Threshold); - args_ptr->CROSThreshold = std::stof (CROS_Threshold ,&sz); + args_ptr->CROSThreshold = std::stof(CROS_Threshold, &sz); } - else args_ptr->CROSThreshold = dCROS_Threshold; - - //--HFI-Threshold - char * HFI_Threshold = getCmdOption(argv, argv + argc, "--HFI-Threshold"); - if (HFI_Threshold){ + else + args_ptr->CROSThreshold = dCROS_Threshold; + + //--HFI-Threshold + char* HFI_Threshold = getCmdOption(argv, argv + argc, "--HFI-Threshold"); + if (HFI_Threshold) + { printf("HFIThreshold: %s \n", HFI_Threshold); - args_ptr->HFIThreshold = std::stof (HFI_Threshold ,&sz); + args_ptr->HFIThreshold = std::stof(HFI_Threshold, &sz); } - else args_ptr->HFIThreshold = dHFI_Threshold; - - //--CROSAct-Threshold - char * CROSAct_Threshold = getCmdOption(argv, argv + argc, "--CROSAct-Threshold"); - if (CROSAct_Threshold){ + else + args_ptr->HFIThreshold = dHFI_Threshold; + + //--CROSAct-Threshold + char* CROSAct_Threshold = getCmdOption(argv, argv + argc, "--CROSAct-Threshold"); + if (CROSAct_Threshold) + { printf("CROSActThreshold: %s \n", CROSAct_Threshold); - args_ptr->CROSActThreshold = std::stof (CROSAct_Threshold ,&sz); - } - else args_ptr->CROSThreshold = dCROS_Threshold; - - - //--HFactor - char * H_Factor = getCmdOption(argv, argv + argc, "--HFactor"); - if (H_Factor){ + args_ptr->CROSActThreshold = std::stof(CROSAct_Threshold, &sz); + } + else + args_ptr->CROSThreshold = dCROS_Threshold; + + //--HFactor + char* H_Factor = getCmdOption(argv, argv + argc, "--HFactor"); + if (H_Factor) + { printf("HFactor: %s \n", H_Factor); - args_ptr->HFactor = std::stof (H_Factor ,&sz); + args_ptr->HFactor = std::stof(H_Factor, &sz); } - else args_ptr->HFactor = dHFactor; - - //---FFactor - char * F_Factor = getCmdOption(argv, argv + argc, "--FFactor"); - if (F_Factor){ + else + args_ptr->HFactor = dHFactor; + + //---FFactor + char* F_Factor = getCmdOption(argv, argv + argc, "--FFactor"); + if (F_Factor) + { printf("FFactor: %s \n", F_Factor); - args_ptr->FFactor = std::stof (F_Factor ,&sz); + args_ptr->FFactor = std::stof(F_Factor, &sz); } - else args_ptr->FFactor = dFFactor; - - ///--BFactor - char * B_Factor = getCmdOption(argv, argv + argc, "--BFactor"); - if (B_Factor){ + else + args_ptr->FFactor = dFFactor; + + ///--BFactor + char* B_Factor = getCmdOption(argv, argv + argc, "--BFactor"); + if (B_Factor) + { printf("BFactor: %s \n", B_Factor); - args_ptr->BFactor = std::stof (B_Factor ,&sz); + args_ptr->BFactor = std::stof(B_Factor, &sz); } - else args_ptr->BFactor = dBFactor; - - ///--EFactor - char * E_Factor = getCmdOption(argv, argv + argc, "--EFactor"); - if (E_Factor){ + else + args_ptr->BFactor = dBFactor; + + ///--EFactor + char* E_Factor = getCmdOption(argv, argv + argc, "--EFactor"); + if (E_Factor) + { printf("EFactor: %s \n", E_Factor); - args_ptr->EFactor = std::stof (E_Factor ,&sz); + args_ptr->EFactor = std::stof(E_Factor, &sz); } - else args_ptr->EFactor = dEFactor; - - ///--CBDFactor - char * CBD_Factor = getCmdOption(argv, argv + argc, "--CBDFactor"); - if (CBD_Factor){ + else + args_ptr->EFactor = dEFactor; + + ///--CBDFactor + char* CBD_Factor = getCmdOption(argv, argv + argc, "--CBDFactor"); + if (CBD_Factor) + { printf("CBDFactor: %s \n", CBD_Factor); - args_ptr->CBDFactor = std::stof (CBD_Factor ,&sz); + args_ptr->CBDFactor = std::stof(CBD_Factor, &sz); } - else args_ptr->CBDFactor = dCBDFactor; - - ///--CCFFactor - char * CCF_Factor = getCmdOption(argv, argv + argc, "--CCFFactor"); - if (CCF_Factor){ + else + args_ptr->CBDFactor = dCBDFactor; + + ///--CCFFactor + char* CCF_Factor = getCmdOption(argv, argv + argc, "--CCFFactor"); + if (CCF_Factor) + { printf("CCFFactor: %s \n", CCF_Factor); - args_ptr->CCFFactor = std::stof (CCF_Factor ,&sz); + args_ptr->CCFFactor = std::stof(CCF_Factor, &sz); } - else args_ptr->CCFFactor = dCCFFactor; - - ///--ROS10Factor - char * ROS10_Factor = getCmdOption(argv, argv + argc, "--ROS10Factor"); - if (ROS10_Factor){ + else + args_ptr->CCFFactor = dCCFFactor; + + ///--ROS10Factor + char* ROS10_Factor = getCmdOption(argv, argv + argc, "--ROS10Factor"); + if (ROS10_Factor) + { printf("ROS10Factor: %s \n", ROS10_Factor); - args_ptr->ROS10Factor = std::stof (ROS10_Factor, &sz); + args_ptr->ROS10Factor = std::stof(ROS10_Factor, &sz); } - else args_ptr->ROS10Factor = dROS10Factor; - - //--ROS-CV - char * ROS_CV = getCmdOption(argv, argv + argc, "--ROS-CV"); - if (ROS_CV){ + else + args_ptr->ROS10Factor = dROS10Factor; + + //--ROS-CV + char* ROS_CV = getCmdOption(argv, argv + argc, "--ROS-CV"); + if (ROS_CV) + { printf("ROS-CV: %s \n", ROS_CV); - args_ptr->ROSCV = std::stof (ROS_CV ,&sz); + args_ptr->ROSCV = std::stof(ROS_CV, &sz); } - else args_ptr->ROSCV = dROSCV; - - //--max-fire-periods - char * max_fire_periods = getCmdOption(argv, argv + argc, "--max-fire-periods"); - if (max_fire_periods){ + else + args_ptr->ROSCV = dROSCV; + + //--max-fire-periods + char* max_fire_periods = getCmdOption(argv, argv + argc, "--max-fire-periods"); + if (max_fire_periods) + { printf("MaxFirePeriods: %s \n", max_fire_periods); - args_ptr->MaxFirePeriods = std::stoi (max_fire_periods ,&sz); + args_ptr->MaxFirePeriods = std::stoi(max_fire_periods, &sz); } - else args_ptr->MaxFirePeriods = dmax_fire_periods; - - //--seed (int) - char * seed = getCmdOption(argv, argv + argc, "--seed"); - if (seed){ + else + args_ptr->MaxFirePeriods = dmax_fire_periods; + + //--seed (int) + char* seed = getCmdOption(argv, argv + argc, "--seed"); + if (seed) + { printf("seed: %s \n", seed); - args_ptr->seed = std::stoi (seed ,&sz); - } - else args_ptr->seed = dseed; - - //--nthreads (int) - char* nthreads = getCmdOption(argv, argv + argc, "--nthreads"); - if (nthreads) { - printf("nthreads: %s \n", nthreads); - args_ptr->nthreads = std::stoi(nthreads, &sz); - } - else args_ptr->nthreads = dnthreads; - - // Populate structure - // Strings - if (input_folder == &empty){ - args_ptr->InFolder = ""; - } - else args_ptr->InFolder = input_folder; - - if (!args_ptr->InFolder.empty() && *args_ptr->InFolder.rbegin()!= separator()){ - args_ptr->InFolder+=separator(); - } - - if (output_folder == &empty && input_folder != &empty){ - args_ptr->OutFolder = args_ptr->InFolder + "simOuts"; - } else if(output_folder == &empty && input_folder == &empty){ - args_ptr->OutFolder = "simOuts"; - } else if(output_folder != &empty && input_folder == &empty){ - args_ptr->OutFolder = output_folder; - } else if(output_folder != &empty && input_folder != &empty){ - args_ptr->OutFolder = output_folder; - } - - if (!args_ptr->OutFolder.empty() && *args_ptr->OutFolder.rbegin()!= separator()){ - args_ptr->OutFolder+=separator(); - } - - if (input_weather == &empty){ - args_ptr->WeatherOpt = "rows"; - } - else{ - args_ptr->WeatherOpt = input_weather; - } - - if (input_hplan == &empty){ - args_ptr->HarvestPlan = ""; - } - else args_ptr->HarvestPlan = input_hplan; - - // booleans - args_ptr->OutMessages = out_messages; - args_ptr->OutFl = out_fl; - args_ptr->OutIntensity = out_intensity; - args_ptr->OutRos = out_ros; - args_ptr->OutCrown = out_crown; - args_ptr->OutCrownConsumption = out_crown_consumption; - args_ptr->OutSurfConsumption = out_surf_consumption; - args_ptr->Trajectories = out_trajectories; - args_ptr->NoOutput = no_output; - args_ptr->verbose = verbose_input; - args_ptr->IgnitionsLog = iplog_input; - args_ptr->Ignitions = input_ignitions; - args_ptr->OutputGrids = out_grids; - args_ptr->FinalGrid = out_finalgrid; - args_ptr->PromTuned = prom_tuned; - args_ptr->Stats = out_stats; - args_ptr->BBOTuning = bbo_tuning; - args_ptr->AllowCROS = allow_cros; - + args_ptr->seed = std::stoi(seed, &sz); + } + else + args_ptr->seed = dseed; + + //--nthreads (int) + char* nthreads = getCmdOption(argv, argv + argc, "--nthreads"); + if (nthreads) + { + printf("nthreads: %s \n", nthreads); + args_ptr->nthreads = std::stoi(nthreads, &sz); + } + else + args_ptr->nthreads = dnthreads; + + // Populate structure + // Strings + if (input_folder == &empty) + { + args_ptr->InFolder = ""; + } + else + args_ptr->InFolder = input_folder; + + if (!args_ptr->InFolder.empty() && *args_ptr->InFolder.rbegin() != separator()) + { + args_ptr->InFolder += separator(); + } + + if (output_folder == &empty && input_folder != &empty) + { + args_ptr->OutFolder = args_ptr->InFolder + "simOuts"; + } + else if (output_folder == &empty && input_folder == &empty) + { + args_ptr->OutFolder = "simOuts"; + } + else if (output_folder != &empty && input_folder == &empty) + { + args_ptr->OutFolder = output_folder; + } + else if (output_folder != &empty && input_folder != &empty) + { + args_ptr->OutFolder = output_folder; + } + + if (!args_ptr->OutFolder.empty() && *args_ptr->OutFolder.rbegin() != separator()) + { + args_ptr->OutFolder += separator(); + } + + if (input_weather == &empty) + { + args_ptr->WeatherOpt = "rows"; + } + else + { + args_ptr->WeatherOpt = input_weather; + } + + if (input_hplan == &empty) + { + args_ptr->HarvestPlan = ""; + } + else + args_ptr->HarvestPlan = input_hplan; + + // booleans + args_ptr->OutMessages = out_messages; + args_ptr->OutFl = out_fl; + args_ptr->OutIntensity = out_intensity; + args_ptr->OutRos = out_ros; + args_ptr->OutCrown = out_crown; + args_ptr->OutCrownConsumption = out_crown_consumption; + args_ptr->OutSurfConsumption = out_surf_consumption; + args_ptr->Trajectories = out_trajectories; + args_ptr->NoOutput = no_output; + args_ptr->verbose = verbose_input; + args_ptr->IgnitionsLog = iplog_input; + args_ptr->Ignitions = input_ignitions; + args_ptr->OutputGrids = out_grids; + args_ptr->FinalGrid = out_finalgrid; + args_ptr->PromTuned = prom_tuned; + args_ptr->Stats = out_stats; + args_ptr->BBOTuning = bbo_tuning; + args_ptr->AllowCROS = allow_cros; } +void +printArgs(arguments args) +{ -void printArgs(arguments args){ - - /* - std::cout << "Simulator: "<d_type == DT_REG) { - std::string filename = ent->d_name; - if (filename.substr(0, 7) == "Weather" && filename.substr(filename.size() - 4) == ".csv") { - file_count++; - } - } - } - closedir(dir); - } - else { - std::cout << "Could not open directory" << std::endl; - return -1; - } - - return file_count; +int +countWeathers(const std::string directory_path) +{ + DIR* dir; + struct dirent* ent; + int file_count = 0; + + if ((dir = opendir(directory_path.c_str())) != NULL) + { + while ((ent = readdir(dir)) != NULL) + { + if (ent->d_type == DT_REG) + { + std::string filename = ent->d_name; + if (filename.substr(0, 7) == "Weather" && filename.substr(filename.size() - 4) == ".csv") + { + file_count++; + } + } + } + closedir(dir); + } + else + { + std::cout << "Could not open directory" << std::endl; + return -1; + } + + return file_count; } diff --git a/Cell2Fire/ReadArgs.h b/Cell2Fire/ReadArgs.h index ca7e5b12..aa92b410 100644 --- a/Cell2Fire/ReadArgs.h +++ b/Cell2Fire/ReadArgs.h @@ -1,36 +1,37 @@ #ifndef READARGS #define READARGS -#include +#include #include -#include +#include #include +#include #include #include -#include -#include +#include /* -* Args structure -*/ -typedef struct{ - std::string InFolder, OutFolder, WeatherOpt, HarvestPlan, Simulator; - bool OutMessages, OutFl,OutIntensity,OutRos,OutCrown,OutCrownConsumption,OutSurfConsumption, Trajectories, NoOutput, verbose, IgnitionsLog, Ignitions, OutputGrids, FinalGrid, PromTuned, Stats, BBOTuning, AllowCROS; - 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,scenario; - std::unordered_set HCells, BCells; + * Args structure + */ +typedef struct +{ + std::string InFolder, OutFolder, WeatherOpt, HarvestPlan, Simulator; + bool OutMessages, OutFl, OutIntensity, OutRos, OutCrown, OutCrownConsumption, OutSurfConsumption, Trajectories, + NoOutput, verbose, IgnitionsLog, Ignitions, OutputGrids, FinalGrid, PromTuned, Stats, BBOTuning, AllowCROS; + 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, + scenario; + std::unordered_set HCells, BCells; } arguments; - -char* getCmdOption(char ** begin, char ** end, const std::string & option); +char* getCmdOption(char** begin, char** end, const std::string& option); bool cmdOptionExists(char** begin, char** end, const std::string& option); -void parseArgs(int argc, char * argv[], arguments * args_ptr); +void parseArgs(int argc, char* argv[], arguments* args_ptr); void printArgs(arguments args); int countWeathers(std::string directory_path); - #endif diff --git a/Cell2Fire/ReadCSV.cpp b/Cell2Fire/ReadCSV.cpp index fa110258..9f4a830b 100644 --- a/Cell2Fire/ReadCSV.cpp +++ b/Cell2Fire/ReadCSV.cpp @@ -1,546 +1,688 @@ #include "ReadCSV.h" #include "Cells.h" -#include "ReadArgs.h" #include "DataGenerator.h" +#include "ReadArgs.h" -#include +#include "tiffio.h" +#include +#include #include -#include +#include #include #include -#include #include #include -#include -#include "tiffio.h" - +#include + /* * Constructor */ -CSVReader::CSVReader(std::string filename, std::string delm){ - this->fileName = filename; - this->delimeter = delm; +CSVReader::CSVReader(std::string filename, std::string delm) +{ + this->fileName = filename; + this->delimeter = delm; } - - + /* -* Parses through csv file line by line and returns the data -* in vector of vector of strings. -*/ -std::vector> CSVReader::getData() { - /* - Check wheather fuels.tif or .asc is in InFolder and add corresponding extension - */ - std::string extension; - - if(fileExists(this->fileName + ".tif")){ + * Parses through csv file line by line and returns the data + * in vector of vector of strings. + */ +std::vector> +CSVReader::getData() +{ + /* + Check wheather fuels.tif or .asc is in InFolder and add corresponding + extension + */ + std::string extension; + + if (fileExists(this->fileName + ".tif")) + { extension = ".tif"; - } else if (fileExists(this->fileName + ".asc")) { + } + else if (fileExists(this->fileName + ".asc")) + { extension = ".asc"; } - else { - extension = ""; - } - this->fileName = this->fileName + extension; - std::cout << this->fileName << '\n'; - std::ifstream file(this->fileName); - std::vector> dataList; - std::string line = ""; - // Iterate through each line and split the content using delimeter - - if (this->fileName.substr(this->fileName.find_last_of(".") + 1) == "asc") { - int header = 0; - while (getline(file, line)) { - if (header < 5) { - std::vector vec; - int start = 0; - int end = 0; - while ((start = line.find_first_not_of(this->delimeter, end)) != std::string::npos) { - end = line.find(this->delimeter, start); - vec.push_back(line.substr(start, end - start)); - } - dataList.push_back(vec); - header++; - } - else { - std::vector vec; - boost::algorithm::split(vec, line, boost::is_any_of(this->delimeter)); - dataList.push_back(vec); - } - - } - } - else if (this->fileName.substr(this->fileName.find_last_of(".") + 1) == "tif") - { - TIFF* fuelsDataset = TIFFOpen(this->fileName.c_str(), "r"); - uint32_t nXSize, nYSize; - TIFFGetField(fuelsDataset, TIFFTAG_IMAGEWIDTH, &nXSize); - TIFFGetField(fuelsDataset, TIFFTAG_IMAGELENGTH, &nYSize); - double* modelPixelScale; - uint32_t count; - //TIFFGetField(tiff, 33424, &count, &data); - TIFFGetField(fuelsDataset, 33550, &count, &modelPixelScale); - // Gets cell size - double cellSizeX {modelPixelScale[0]}; - double cellSizeY {modelPixelScale[1]}; - const double epsilon = std::numeric_limits::epsilon(); - tsize_t scan_size = TIFFRasterScanlineSize(fuelsDataset); - int n_bits = (scan_size / nXSize) * 8; - if (fabs(cellSizeX - cellSizeY) > epsilon) { - throw std::runtime_error("Error: Cells are not square in: '" + fileName + "'"); - } - double *positions; - TIFFGetField(fuelsDataset, 33922, &count, &positions); - double xllcorner {positions[3]}; - double yllcorner {positions[4]}; - std::vector vec; - vec.push_back("ncols"); - vec.push_back(std::to_string(nXSize)); - dataList.push_back(vec); - std::vector vec2; - vec2.push_back("nrows"); - vec2.push_back(std::to_string(nYSize)); - dataList.push_back(vec2); - std::vector vec3; - vec3.push_back("xllcorner"); - vec3.push_back(std::to_string(int (xllcorner))); - dataList.push_back(vec3); - std::vector vec4; - vec4.push_back("yllcorner"); - vec4.push_back(std::to_string(int (yllcorner))); - dataList.push_back(vec4); - std::vector vec5; - vec5.push_back("cellsize"); - vec5.push_back(std::to_string(cellSizeX)); - dataList.push_back(vec5); - void *buf; - if (n_bits == 64){ - buf = (double*)_TIFFmalloc(nXSize * sizeof(double)); - } - else if (n_bits == 32) { - buf = (int32_t*)_TIFFmalloc(nXSize * sizeof(int32_t)); - } - else { - throw std::runtime_error("Error: file type is not supported: '" + fileName + "'"); - } - if (!buf) { - TIFFClose(fuelsDataset); - throw std::runtime_error("Could not allocate memory"); - } - // For each row - for (int i = 0; i < nYSize; i++) { - std::vector vec_rows; - // Read pixel values for the current row - if (TIFFReadScanline(fuelsDataset, buf, i) != 1) { - _TIFFfree(buf); - TIFFClose(fuelsDataset); - throw std::runtime_error("Read error on row " + std::to_string(i)); - } - // For each column - std::string token; - for (int j = 0; j < nXSize; j++) { - // Access the pixel value at position (i, j) - if (n_bits == 64){ - token = std::to_string(static_cast( ((double *) buf)[j])); - } - else { - token = std::to_string(static_cast( ((int32_t *) buf)[j])); - } - vec_rows.push_back(token); - } - dataList.push_back(vec_rows); - } - } - - else { - while (getline(file, line)) { - std::vector vec; - boost::algorithm::split(vec, line, boost::is_any_of(this->delimeter)); - dataList.push_back(vec); - } - } - - - // Close the File - file.close(); - - return dataList; -} + else + { + extension = ""; + } + this->fileName = this->fileName + extension; + std::cout << this->fileName << '\n'; + std::ifstream file(this->fileName); + std::vector> dataList; + std::string line = ""; + // Iterate through each line and split the content using delimeter + + if (this->fileName.substr(this->fileName.find_last_of(".") + 1) == "asc") + { + int header = 0; + while (getline(file, line)) + { + if (header < 5) + { + std::vector vec; + int start = 0; + int end = 0; + while ((start = line.find_first_not_of(this->delimeter, end)) != std::string::npos) + { + end = line.find(this->delimeter, start); + vec.push_back(line.substr(start, end - start)); + } + dataList.push_back(vec); + header++; + } + else + { + std::vector vec; + boost::algorithm::split(vec, line, boost::is_any_of(this->delimeter)); + dataList.push_back(vec); + } + } + } + else if (this->fileName.substr(this->fileName.find_last_of(".") + 1) == "tif") + { + TIFF* fuelsDataset = TIFFOpen(this->fileName.c_str(), "r"); + uint32_t nXSize, nYSize; + TIFFGetField(fuelsDataset, TIFFTAG_IMAGEWIDTH, &nXSize); + TIFFGetField(fuelsDataset, TIFFTAG_IMAGELENGTH, &nYSize); + double* modelPixelScale; + uint32_t count; + // TIFFGetField(tiff, 33424, &count, &data); + TIFFGetField(fuelsDataset, 33550, &count, &modelPixelScale); + // Gets cell size + double cellSizeX{ modelPixelScale[0] }; + double cellSizeY{ modelPixelScale[1] }; + const double epsilon = std::numeric_limits::epsilon(); + tsize_t scan_size = TIFFRasterScanlineSize(fuelsDataset); + int n_bits = (scan_size / nXSize) * 8; + if (fabs(cellSizeX - cellSizeY) > epsilon) + { + throw std::runtime_error("Error: Cells are not square in: '" + fileName + "'"); + } + double* positions; + TIFFGetField(fuelsDataset, 33922, &count, &positions); + double xllcorner{ positions[3] }; + double yllcorner{ positions[4] }; + std::vector vec; + vec.push_back("ncols"); + vec.push_back(std::to_string(nXSize)); + dataList.push_back(vec); + std::vector vec2; + vec2.push_back("nrows"); + vec2.push_back(std::to_string(nYSize)); + dataList.push_back(vec2); + std::vector vec3; + vec3.push_back("xllcorner"); + vec3.push_back(std::to_string(int(xllcorner))); + dataList.push_back(vec3); + std::vector vec4; + vec4.push_back("yllcorner"); + vec4.push_back(std::to_string(int(yllcorner))); + dataList.push_back(vec4); + std::vector vec5; + vec5.push_back("cellsize"); + vec5.push_back(std::to_string(cellSizeX)); + dataList.push_back(vec5); + void* buf; + if (n_bits == 64) + { + buf = (double*)_TIFFmalloc(nXSize * sizeof(double)); + } + else if (n_bits == 32) + { + buf = (int32_t*)_TIFFmalloc(nXSize * sizeof(int32_t)); + } + else + { + throw std::runtime_error("Error: file type is not supported: '" + fileName + "'"); + } + if (!buf) + { + TIFFClose(fuelsDataset); + throw std::runtime_error("Could not allocate memory"); + } + // For each row + for (int i = 0; i < nYSize; i++) + { + std::vector vec_rows; + // Read pixel values for the current row + if (TIFFReadScanline(fuelsDataset, buf, i) != 1) + { + _TIFFfree(buf); + TIFFClose(fuelsDataset); + throw std::runtime_error("Read error on row " + std::to_string(i)); + } + // For each column + std::string token; + for (int j = 0; j < nXSize; j++) + { + // Access the pixel value at position (i, j) + if (n_bits == 64) + { + token = std::to_string(static_cast(((double*)buf)[j])); + } + else + { + token = std::to_string(static_cast(((int32_t*)buf)[j])); + } + vec_rows.push_back(token); + } + dataList.push_back(vec_rows); + } + } + else + { + while (getline(file, line)) + { + std::vector vec; + boost::algorithm::split(vec, line, boost::is_any_of(this->delimeter)); + dataList.push_back(vec); + } + } -/* -* Prints data to screen inside the DF obtained from the CSV file -*/ -void CSVReader::printData(std::vector> & DF){ - // Print the content of row by row on screen - for(std::vector vec : DF) - { - for(std::string data : vec) - { - if(data.length() >0) std::cout << " " << data << " "; - else std::cout << " " << "NaN" << " "; - } - std::cout<> & DF,arguments* args_ptr,int NCells){ - int i; - - // Floats - float cur, elev, ws, waz, saz, cbd, cbh, ccf, ps, lat,lon,ffmc,bui,gfl; - - // Integers - int nftype,FMC, jd,jd_min,pc,pdf,time,pattern; - - // CChar - const char * faux; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i=1; i <= NCells; i++){ - //printf("Populating DF for cell %d\n", i); - - faux = DF[i][0].append(" ").c_str(); - - if (DF[i][3].compare("") == 0) elev = 0; - else elev = std::stof (DF[i][3] ,&sz); - - if (DF[i][4].compare("") == 0) ws = 0; - else ws = std::stof (DF[i][4], &sz); - - if (DF[i][5].compare("") == 0) waz = 0; - else waz = std::stoi (DF[i][5] ,&sz) + 180.;// + 2*90; // CHECK!!!! - if (waz >= 360) waz = waz - 360; - - if (DF[i][6].compare("") == 0) ps = 0; - else ps = std::stof (DF[i][6] ,&sz); - - if (DF[i][7].compare("") == 0) saz = 0; - else saz = std::stof (DF[i][7] ,&sz); - - if (DF[i][8].compare("") == 0) cur = 0; - else cur = std::stof (DF[i][8] ,&sz); - - if (DF[i][9].compare("") == 0) cbd = 0; - else cbd = std::stof (DF[i][9], &sz); - - if (DF[i][10].compare("") == 0) cbh = 0; - else cbh = std::stof (DF[i][10], &sz); - - if (DF[i][11].compare("") == 0) ccf = 0; - else ccf = std::stof (DF[i][11], &sz); - - if (DF[i][12].compare("") == 0) nftype = 0; - else nftype = std::stoi (DF[i][12], &sz); - - if (DF[i][13].compare("") == 0) FMC = args_ptr->FMC; - else FMC = std::stoi (DF[i][13], &sz); - - //DF[i][14] stores probability - - if (DF[i][15].compare("") == 0) jd = 0; - else jd = std::stoi (DF[i][15] ,&sz); - - if (DF[i][16].compare("") == 0) jd_min = 0; - else jd_min = std::stoi (DF[i][16] ,&sz); - - if (DF[i][17].compare("") == 0) pc = 0; - else pc = std::stoi (DF[i][17] ,&sz); - - if (DF[i][18].compare("") == 0) pdf = 0; - else pdf = std::stoi (DF[i][18] ,&sz); - - if (DF[i][19].compare("") == 0) time = 0; - else time = std::stoi (DF[i][19] ,&sz); - - if (DF[i][1].compare("") == 0) lat = 0; - else lat = std::stof (DF[i][1], &sz); - - if (DF[i][2].compare("") == 0) lon = 0; - else lon = std::stof (DF[i][2], &sz); - - if (DF[i][20].compare("") == 0) ffmc = 0; - else ffmc = std::stof (DF[i][20], &sz); - - if (DF[i][21].compare("") == 0) bui = 0; - else bui = std::stof (DF[i][21], &sz); - - if (DF[i][22].compare("") == 0) gfl = 0; - else gfl = std::stof (DF[i][22], &sz); - - if (DF[i][23].compare("") == 0) pattern = 0; - else pattern = 1;// std::stoi (DF[i][18], &sz); - - // Set values - strncpy(df_ptr->fueltype, faux, 4); - df_ptr->elev=elev; df_ptr->ws=ws; df_ptr->waz=waz; - df_ptr->ps=ps; df_ptr->saz=saz; df_ptr->cur=cur; - df_ptr->cbd=cbd;df_ptr->cbh=cbh; df_ptr->ccf=ccf; - df_ptr->nftype=nftype;df_ptr->FMC=FMC;df_ptr->jd=jd; - df_ptr->jd_min=jd_min;df_ptr->pc=pc;df_ptr->pdf=pdf; - df_ptr->time=time;df_ptr->lat=lat;df_ptr->lon=lon; - df_ptr->ffmc=ffmc;df_ptr->bui=bui;df_ptr->gfl=gfl; - df_ptr->pattern=pattern; - - // Next pointer - df_ptr++; - } + * Prints data to screen inside the DF obtained from the CSV file + */ +void +CSVReader::printData(std::vector>& DF) +{ + // Print the content of row by row on screen + for (std::vector vec : DF) + { + for (std::string data : vec) + { + if (data.length() > 0) + std::cout << " " << data << " "; + else + std::cout << " " + << "NaN" + << " "; + } + std::cout << std::endl; + } } - /* -* Populates vector of size NCells with type number based on lookup table (Spain version) -*/ -void CSVReader::parseNDF(std::vector &NFTypes, std::vector> & DF, int NCells){ - int i; - - // Ints - int FType; - - // CChar - const char * faux; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i=1; i <= NCells; i++){ - //printf("Populating DF for cell %d\n", i); - if (DF[i][12].compare("") == 0) FType = 0; - else FType = std::stoi (DF[i][12], &sz); - - // Set values - NFTypes.push_back(FType); - - } + * Populates the df input objects based on the DF csv file for each row/cell + * (spanish version) + */ +void +CSVReader::parseDF(inputs* df_ptr, std::vector>& DF, arguments* args_ptr, int NCells) +{ + int i; + + // Floats + float cur, elev, ws, waz, saz, cbd, cbh, ccf, ps, lat, lon, ffmc, bui, gfl; + + // Integers + int nftype, FMC, jd, jd_min, pc, pdf, time, pattern; + + // CChar + const char* faux; + std::string::size_type sz; // alias of size_t + + // Loop over cells (populating per row) + for (i = 1; i <= NCells; i++) + { + // printf("Populating DF for cell %d\n", i); + + faux = DF[i][0].append(" ").c_str(); + + if (DF[i][3].compare("") == 0) + elev = 0; + else + elev = std::stof(DF[i][3], &sz); + + if (DF[i][4].compare("") == 0) + ws = 0; + else + ws = std::stof(DF[i][4], &sz); + + if (DF[i][5].compare("") == 0) + waz = 0; + else + waz = std::stoi(DF[i][5], &sz) + 180.; // + 2*90; // CHECK!!!! + if (waz >= 360) + waz = waz - 360; + + if (DF[i][6].compare("") == 0) + ps = 0; + else + ps = std::stof(DF[i][6], &sz); + + if (DF[i][7].compare("") == 0) + saz = 0; + else + saz = std::stof(DF[i][7], &sz); + + if (DF[i][8].compare("") == 0) + cur = 0; + else + cur = std::stof(DF[i][8], &sz); + + if (DF[i][9].compare("") == 0) + cbd = 0; + else + cbd = std::stof(DF[i][9], &sz); + + if (DF[i][10].compare("") == 0) + cbh = 0; + else + cbh = std::stof(DF[i][10], &sz); + + if (DF[i][11].compare("") == 0) + ccf = 0; + else + ccf = std::stof(DF[i][11], &sz); + + if (DF[i][12].compare("") == 0) + nftype = 0; + else + nftype = std::stoi(DF[i][12], &sz); + + if (DF[i][13].compare("") == 0) + FMC = args_ptr->FMC; + else + FMC = std::stoi(DF[i][13], &sz); + + // DF[i][14] stores probability + + if (DF[i][15].compare("") == 0) + jd = 0; + else + jd = std::stoi(DF[i][15], &sz); + + if (DF[i][16].compare("") == 0) + jd_min = 0; + else + jd_min = std::stoi(DF[i][16], &sz); + + if (DF[i][17].compare("") == 0) + pc = 0; + else + pc = std::stoi(DF[i][17], &sz); + + if (DF[i][18].compare("") == 0) + pdf = 0; + else + pdf = std::stoi(DF[i][18], &sz); + + if (DF[i][19].compare("") == 0) + time = 0; + else + time = std::stoi(DF[i][19], &sz); + + if (DF[i][1].compare("") == 0) + lat = 0; + else + lat = std::stof(DF[i][1], &sz); + + if (DF[i][2].compare("") == 0) + lon = 0; + else + lon = std::stof(DF[i][2], &sz); + + if (DF[i][20].compare("") == 0) + ffmc = 0; + else + ffmc = std::stof(DF[i][20], &sz); + + if (DF[i][21].compare("") == 0) + bui = 0; + else + bui = std::stof(DF[i][21], &sz); + + if (DF[i][22].compare("") == 0) + gfl = 0; + else + gfl = std::stof(DF[i][22], &sz); + + if (DF[i][23].compare("") == 0) + pattern = 0; + else + pattern = 1; // std::stoi (DF[i][18], &sz); + + // Set values + strncpy(df_ptr->fueltype, faux, 4); + df_ptr->elev = elev; + df_ptr->ws = ws; + df_ptr->waz = waz; + df_ptr->ps = ps; + df_ptr->saz = saz; + df_ptr->cur = cur; + df_ptr->cbd = cbd; + df_ptr->cbh = cbh; + df_ptr->ccf = ccf; + df_ptr->nftype = nftype; + df_ptr->FMC = FMC; + df_ptr->jd = jd; + df_ptr->jd_min = jd_min; + df_ptr->pc = pc; + df_ptr->pdf = pdf; + df_ptr->time = time; + df_ptr->lat = lat; + df_ptr->lon = lon; + df_ptr->ffmc = ffmc; + df_ptr->bui = bui; + df_ptr->gfl = gfl; + df_ptr->pattern = pattern; + + // Next pointer + df_ptr++; + } } - - /* -* Populates vector of size NCells with type number based on lookup table (Spain version) -*/ -void CSVReader::parsePROB(std::vector& probabilities, std::vector>& DF, int NCells) { - int i; - - // Ints - float Prob; - - // CChar - const char* faux; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i = 1; i <= NCells; i++) { - //printf("Populating DF for cell %d\n", i); - if (DF[i][14].compare("") == 0) Prob = 1; - else Prob = std::stof(DF[i][14], &sz); - - - // Set values - probabilities[i-1]=Prob; - //probabilities.push_back(Prob); - - } + * Populates vector of size NCells with type number based on lookup table + * (Spain version) + */ +void +CSVReader::parseNDF(std::vector& NFTypes, std::vector>& DF, int NCells) +{ + int i; + + // Ints + int FType; + + // CChar + const char* faux; + std::string::size_type sz; // alias of size_t + + // Loop over cells (populating per row) + for (i = 1; i <= NCells; i++) + { + // printf("Populating DF for cell %d\n", i); + if (DF[i][12].compare("") == 0) + FType = 0; + else + FType = std::stoi(DF[i][12], &sz); + + // Set values + NFTypes.push_back(FType); + } } +/* + * Populates vector of size NCells with type number based on lookup table + * (Spain version) + */ +void +CSVReader::parsePROB(std::vector& probabilities, std::vector>& DF, int NCells) +{ + int i; + + // Ints + float Prob; + + // CChar + const char* faux; + std::string::size_type sz; // alias of size_t + + // Loop over cells (populating per row) + for (i = 1; i <= NCells; i++) + { + // printf("Populating DF for cell %d\n", i); + if (DF[i][14].compare("") == 0) + Prob = 1; + else + Prob = std::stof(DF[i][14], &sz); + + // Set values + probabilities[i - 1] = Prob; + // probabilities.push_back(Prob); + } +} /* -* Populate Weather DF Spain -*/ -void CSVReader::parseWeatherDF(weatherDF * wdf_ptr,arguments* args_ptr, std::vector> & DF, int WPeriods){ - int i; - - //Strings - std::string::size_type sz; // alias of size_t - - //Floats - float ws, waz, tmp=27, rh=40; - float apcp=0,ffmc=0,dmc=0,dc=0,isi=0,bui=0,fwi=0; - - - - // Loop over cells (populating per row) - for (i=1; i <= WPeriods; i++){ - if (DF[i][3].compare("") == 0) waz = 0; - else {waz = std::stoi (DF[i][3] ,&sz); //+ 180/2; // DEBUGGING THE ANGLE - if (waz >= 360){ - waz = waz - 360; - } - } - - if (DF[i][2].compare("") == 0) ws = 0; - else ws = std::stof (DF[i][2], &sz); - - if (args_ptr->Simulator=="K"){ - if (DF[i][4].compare("") == 0) tmp = 0; - else tmp = std::stof(DF[i][4], &sz); - - if (DF[i][5].compare("") == 0) rh = 0; - else rh = std::stof(DF[i][5], &sz); - - } - else if (args_ptr->Simulator=="C"){ - - if (DF[i][6].compare("") == 0) waz = 0; - else {waz = std::stoi (DF[i][6] ,&sz); //+ 180/2; // DEBUGGING THE ANGLE - if (waz >= 360){ - waz = waz - 360; - } - } - if (DF[i][2].compare("") == 0) apcp = 0; - else apcp = std::stof (DF[i][2], &sz); - - if (DF[i][3].compare("") == 0) tmp = 0; - else tmp = std::stof (DF[i][3], &sz); - - if (DF[i][4].compare("") == 0) rh = 0; - else rh = std::stof (DF[i][4], &sz); - - if (DF[i][5].compare("") == 0) ws = 0; - else ws = std::stof (DF[i][5], &sz); - - if (DF[i][7].compare("") == 0) ffmc = 0; - else ffmc = std::stof (DF[i][7], &sz); - - if (DF[i][8].compare("") == 0) dmc = 0; - else dmc = std::stof (DF[i][8], &sz); - - if (DF[i][9].compare("") == 0) dc = 0; - else dc = std::stof (DF[i][9], &sz); - - if (DF[i][10].compare("") == 0) isi = 0; - else isi = std::stof (DF[i][10], &sz); - - if (DF[i][11].compare("") == 0) bui = 0; - else bui = std::stof (DF[i][11], &sz); - - if (DF[i][12].compare("") == 0) fwi = 0; - else fwi = std::stof (DF[i][12], &sz); - } - - - - // Set values - wdf_ptr->ws=ws; wdf_ptr->waz=waz; - wdf_ptr->tmp = tmp; wdf_ptr->rh = rh; - wdf_ptr->apcp=apcp; wdf_ptr->ffmc=ffmc; - wdf_ptr->dmc=dmc; wdf_ptr->dc=dc; - wdf_ptr->isi=isi;wdf_ptr->bui=bui; - wdf_ptr->fwi=fwi; - // Next pointer - wdf_ptr++; - } - + * Populate Weather DF Spain + */ +void +CSVReader::parseWeatherDF(weatherDF* wdf_ptr, + arguments* args_ptr, + std::vector>& DF, + int WPeriods) +{ + int i; + + // Strings + std::string::size_type sz; // alias of size_t + + // Floats + float ws, waz, tmp = 27, rh = 40; + float apcp = 0, ffmc = 0, dmc = 0, dc = 0, isi = 0, bui = 0, fwi = 0; + + // Loop over cells (populating per row) + for (i = 1; i <= WPeriods; i++) + { + if (DF[i][3].compare("") == 0) + waz = 0; + else + { + waz = std::stoi(DF[i][3], &sz); //+ 180/2; // DEBUGGING THE ANGLE + if (waz >= 360) + { + waz = waz - 360; + } + } + + if (DF[i][2].compare("") == 0) + ws = 0; + else + ws = std::stof(DF[i][2], &sz); + + if (args_ptr->Simulator == "K") + { + if (DF[i][4].compare("") == 0) + tmp = 0; + else + tmp = std::stof(DF[i][4], &sz); + + if (DF[i][5].compare("") == 0) + rh = 0; + else + rh = std::stof(DF[i][5], &sz); + } + else if (args_ptr->Simulator == "C") + { + + if (DF[i][6].compare("") == 0) + waz = 0; + else + { + waz = std::stoi(DF[i][6], + &sz); //+ 180/2; // DEBUGGING THE ANGLE + if (waz >= 360) + { + waz = waz - 360; + } + } + if (DF[i][2].compare("") == 0) + apcp = 0; + else + apcp = std::stof(DF[i][2], &sz); + + if (DF[i][3].compare("") == 0) + tmp = 0; + else + tmp = std::stof(DF[i][3], &sz); + + if (DF[i][4].compare("") == 0) + rh = 0; + else + rh = std::stof(DF[i][4], &sz); + + if (DF[i][5].compare("") == 0) + ws = 0; + else + ws = std::stof(DF[i][5], &sz); + + if (DF[i][7].compare("") == 0) + ffmc = 0; + else + ffmc = std::stof(DF[i][7], &sz); + + if (DF[i][8].compare("") == 0) + dmc = 0; + else + dmc = std::stof(DF[i][8], &sz); + + if (DF[i][9].compare("") == 0) + dc = 0; + else + dc = std::stof(DF[i][9], &sz); + + if (DF[i][10].compare("") == 0) + isi = 0; + else + isi = std::stof(DF[i][10], &sz); + + if (DF[i][11].compare("") == 0) + bui = 0; + else + bui = std::stof(DF[i][11], &sz); + + if (DF[i][12].compare("") == 0) + fwi = 0; + else + fwi = std::stof(DF[i][12], &sz); + } + + // Set values + wdf_ptr->ws = ws; + wdf_ptr->waz = waz; + wdf_ptr->tmp = tmp; + wdf_ptr->rh = rh; + wdf_ptr->apcp = apcp; + wdf_ptr->ffmc = ffmc; + wdf_ptr->dmc = dmc; + wdf_ptr->dc = dc; + wdf_ptr->isi = isi; + wdf_ptr->bui = bui; + wdf_ptr->fwi = fwi; + // Next pointer + wdf_ptr++; + } } +/* + * Populate IgnitionDF + */ +void +CSVReader::parseIgnitionDF(std::vector& ig, std::vector>& DF, int IgPeriods) +{ + // Integers + int i, igcell; + std::string::size_type sz; // alias of size_t + // Loop over cells (populating per row) + for (i = 1; i <= IgPeriods; i++) + { + // DEBUGprintf("Populating Ignition points: %d\n", i); + igcell = std::stoi(DF[i][1], &sz); -/* -* Populate IgnitionDF -*/ -void CSVReader::parseIgnitionDF(std::vector & ig, std::vector> & DF, int IgPeriods){ - // Integers - int i, igcell; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i=1; i <= IgPeriods; i++){ - //DEBUGprintf("Populating Ignition points: %d\n", i); - igcell = std::stoi(DF[i][1], &sz); - - // Set values - ig[i-1]= igcell; - - // Next pointer - //ig_ptr++; - } - - -} + // Set values + ig[i - 1] = igcell; + // Next pointer + // ig_ptr++; + } +} /* -* Populate HarvestedDF -*/ -void CSVReader::parseHarvestedDF(std::unordered_map> & hc, std::vector> & DF, int HPeriods){ - // Integers - int i, j, hcell; - std::vector toHarvestCells; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i=1; i <= HPeriods; i++){ - // Clean the vector before the new year - toHarvestCells.clear(); - - // Loop over years of the simulation - for(j=1; j < DF[i].size(); j++){ - hcell = std::stoi(DF[i][j], &sz); - - // Set values - toHarvestCells.push_back(hcell); - } - - // Populate unordered set - hc.insert(std::make_pair(i, toHarvestCells)); - - } - - + * Populate HarvestedDF + */ +void +CSVReader::parseHarvestedDF(std::unordered_map>& hc, + std::vector>& DF, + int HPeriods) +{ + // Integers + int i, j, hcell; + std::vector toHarvestCells; + std::string::size_type sz; // alias of size_t + + // Loop over cells (populating per row) + for (i = 1; i <= HPeriods; i++) + { + // Clean the vector before the new year + toHarvestCells.clear(); + + // Loop over years of the simulation + for (j = 1; j < DF[i].size(); j++) + { + hcell = std::stoi(DF[i][j], &sz); + + // Set values + toHarvestCells.push_back(hcell); + } + + // Populate unordered set + hc.insert(std::make_pair(i, toHarvestCells)); + } } - /* -* Populate BBO Tuning factors -*/ -void CSVReader::parseBBODF(std::unordered_map> & bbo, std::vector> & DF, int NFTypes){ - // Integers - int i, j, ftype; - int ffactors = 4; - std::vector bboFactors; - std::string::size_type sz; // alias of size_t - - // Loop over cells (populating per row) - for (i=1; i <= NFTypes; i++){ - // Clean the vector before the fuels - bboFactors.clear(); - - //DEBUGprintf("Populating Ignition points: %d\n", i); - ftype = std::stoi(DF[i][0], &sz); - - for (j=1; j <= ffactors; j++){ - bboFactors.push_back(std::stof(DF[i][j], &sz)); - } - - //Set values - bbo.insert(std::make_pair(ftype, bboFactors)); - } - - + * Populate BBO Tuning factors + */ +void +CSVReader::parseBBODF(std::unordered_map>& bbo, + std::vector>& DF, + int NFTypes) +{ + // Integers + int i, j, ftype; + int ffactors = 4; + std::vector bboFactors; + std::string::size_type sz; // alias of size_t + + // Loop over cells (populating per row) + for (i = 1; i <= NFTypes; i++) + { + // Clean the vector before the fuels + bboFactors.clear(); + + // DEBUGprintf("Populating Ignition points: %d\n", i); + ftype = std::stoi(DF[i][0], &sz); + + for (j = 1; j <= ffactors; j++) + { + bboFactors.push_back(std::stof(DF[i][j], &sz)); + } + + // Set values + bbo.insert(std::make_pair(ftype, bboFactors)); + } } - -void CSVReader::parseForestDF(forestDF * frt_ptr, std::vector> & DF){ - // Ints - int cellside, rows, cols; - int i, j; - double xllcorner, yllcorner; - //std::string xllcorner; - std::string::size_type sz; // alias of size_t - std::unordered_map Aux; - std::vector Aux2; - cols = std::stoi(DF[0][1], &sz); - rows = std::stoi(DF[1][1], &sz); - - // Others - //std::vector> adjCells; //Change this to a function for memory improvement - std::vector> coordCells; - - std::string North = "N"; +void +CSVReader::parseForestDF(forestDF* frt_ptr, std::vector>& DF) +{ + // Ints + int cellside, rows, cols; + int i, j; + double xllcorner, yllcorner; + // std::string xllcorner; + std::string::size_type sz; // alias of size_t + std::unordered_map Aux; + std::vector Aux2; + cols = std::stoi(DF[0][1], &sz); + rows = std::stoi(DF[1][1], &sz); + + // Others + // std::vector> adjCells; //Change this + // to a function for memory improvement + std::vector> coordCells; + + std::string North = "N"; std::string South = "S"; std::string East = "E"; std::string West = "W"; @@ -548,79 +690,92 @@ void CSVReader::parseForestDF(forestDF * frt_ptr, std::vector(); - Aux2.push_back(c); - Aux2.push_back(rows-r-1); - coordCells.push_back(Aux2); - //printf("i,j = %d,%d\n", r,c); - //std::cout << "x: " << coordCells[c + r*(cols)][0] << " y: " << coordCells[c + r*(cols)][1] << std::endl; - - /* Adjacents */ - // if we have rows (not a forest = line) - } - } - // Set values - frt_ptr->cellside = cellside; - frt_ptr->rows = rows; - frt_ptr->cols = cols; - frt_ptr->coordCells = coordCells; - //frt_ptr->adjCells = adjCells; - frt_ptr->xllcorner = xllcorner; - frt_ptr->yllcorner = yllcorner; - - + // Maybe parse only for avail cells + // Filling DF + // DEBUGprintf("Populating Forest DF\n"); + + xllcorner = std::stod(DF[2][1], &sz); + yllcorner = std::stod(DF[3][1], &sz); + cellside = std::stoi(DF[4][1], &sz); + + // DEBUGprintf("cols: %d, rows: %d, cellside: %d\n", cols, rows, + // cellside); + + // CoordCells and Adjacents + int n = 1; + int r, c; + // std::cout << "CoordCells Debug" << std::endl; + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { + + /* CoordCells */ + Aux2 = std::vector(); + Aux2.push_back(c); + Aux2.push_back(rows - r - 1); + coordCells.push_back(Aux2); + // printf("i,j = %d,%d\n", r,c); + // std::cout << "x: " << coordCells[c + r*(cols)][0] << " y: " << + // coordCells[c + r*(cols)][1] << std::endl; + + /* Adjacents */ + // if we have rows (not a forest = line) + } + } + // Set values + frt_ptr->cellside = cellside; + frt_ptr->rows = rows; + frt_ptr->cols = cols; + frt_ptr->coordCells = coordCells; + // frt_ptr->adjCells = adjCells; + frt_ptr->xllcorner = xllcorner; + frt_ptr->yllcorner = yllcorner; } - -void CSVReader::printDF(inputs df){ - std::cout << df.fueltype; std::cout << " "; - std::cout << " " << df.elev; std::cout << " " << df.ws; std::cout << " " << df.waz; - std::cout << " " << df.ps; std::cout << " " << df.saz; std::cout << " " << df.cur; - std::cout << " " << df.cbd; std::cout << " " << df.cbh; std::cout << " " << df.ccf; std::cout << " " << df.FMC << std::endl; +void +CSVReader::printDF(inputs df) +{ + std::cout << df.fueltype; + std::cout << " "; + std::cout << " " << df.elev; + std::cout << " " << df.ws; + std::cout << " " << df.waz; + std::cout << " " << df.ps; + std::cout << " " << df.saz; + std::cout << " " << df.cur; + std::cout << " " << df.cbd; + std::cout << " " << df.cbh; + std::cout << " " << df.ccf; + std::cout << " " << df.FMC << std::endl; } - -void CSVReader::printWeatherDF(weatherDF wdf){ - std::cout << " " << wdf.ws; std::cout << " " << wdf.waz; +void +CSVReader::printWeatherDF(weatherDF wdf) +{ + std::cout << " " << wdf.ws; + std::cout << " " << wdf.waz; } /* int main() { - // Creating an object of CSVWriter - CSVReader reader("example.csv"); - - // Get the data from CSV File - std::vector > dataList = reader.getData(); - - // Print the content of row by row on screen - for(std::vector vec : dataList) - { - for(std::string data : vec) - { - std::cout< > dataList = reader.getData(); + + // Print the content of row by row on screen + for(std::vector vec : dataList) + { + for(std::string data : vec) + { + std::cout< +#include "tiffio.h" +#include +#include #include -#include +#include #include #include -#include -#include #include #include -#include "tiffio.h" - - +#include - /* -* Forest structure -*/ +/* + * Forest structure + */ typedef struct - { int cellside, rows, cols; - double xllcorner, yllcorner; - //std::vector> adjCells; - std::vector> coordCells; - } forestDF; +{ + int cellside, rows, cols; + double xllcorner, yllcorner; + // std::vector> adjCells; + std::vector> coordCells; +} forestDF; - /* * A class to read data from a csv file. */ -class CSVReader{ -public: - // inmutable - std::string fileName; - std::string delimeter; - - // Constructor - CSVReader(std::string filename, std::string delm = ","); - - // Function to fetch data from a CSV File - std::vector> getData(); - - //Print data to console (Debug) - void printData(std::vector> & DF); - - //Populate DF (Spanish version) - void parseDF(inputs * df_ptr, std::vector> & DF, arguments* args_ptr,int NCells); - - // Populate NFtypes (Spanish version) - void parseNDF(std::vector & NFTypes, std::vector> & DF, int NCells); - - // Populate Probabilities - void parsePROB(std::vector& probabilities, std::vector>& DF, int NCells); - - //Populate Weather DF (Spanish version) - void parseWeatherDF(weatherDF * wt_ptr,arguments*args_ptr, std::vector> & DF, int WPeriods); - - // Populate Ignition Points - void parseIgnitionDF(std::vector & ig, std::vector> & DF, int IgPeriods); - - // Populates ForestDF - void parseForestDF(forestDF * frt_ptr, std::vector> & DF); - - // Populate Harvested Cells - void parseHarvestedDF(std::unordered_map> & hc, std::vector> & DF, int HPeriods); - - // Populate BBO Factors - void parseBBODF(std::unordered_map> & bbo, std::vector> & DF, int NFTypes); - - // Prints individual cell info - void printDF(inputs df); - - // Prints individual weather row info - void printWeatherDF(weatherDF wdf); +class CSVReader +{ + public: + // inmutable + std::string fileName; + std::string delimeter; + + // Constructor + CSVReader(std::string filename, std::string delm = ","); + + // Function to fetch data from a CSV File + std::vector> getData(); + + // Print data to console (Debug) + void printData(std::vector>& DF); + + // Populate DF (Spanish version) + void parseDF(inputs* df_ptr, std::vector>& DF, arguments* args_ptr, int NCells); + + // Populate NFtypes (Spanish version) + void parseNDF(std::vector& NFTypes, std::vector>& DF, int NCells); + + // Populate Probabilities + void parsePROB(std::vector& probabilities, std::vector>& DF, int NCells); + + // Populate Weather DF (Spanish version) + void + parseWeatherDF(weatherDF* wt_ptr, arguments* args_ptr, std::vector>& DF, int WPeriods); + + // Populate Ignition Points + void parseIgnitionDF(std::vector& ig, std::vector>& DF, int IgPeriods); + + // Populates ForestDF + void parseForestDF(forestDF* frt_ptr, std::vector>& DF); + + // Populate Harvested Cells + void parseHarvestedDF(std::unordered_map>& hc, + std::vector>& DF, + int HPeriods); + + // Populate BBO Factors + void parseBBODF(std::unordered_map>& bbo, + std::vector>& DF, + int NFTypes); + + // Prints individual cell info + void printDF(inputs df); + + // Prints individual weather row info + void printWeatherDF(weatherDF wdf); }; - + #endif diff --git a/Cell2Fire/Spotting.cpp b/Cell2Fire/Spotting.cpp index 8a1bb7d5..53d558f7 100644 --- a/Cell2Fire/Spotting.cpp +++ b/Cell2Fire/Spotting.cpp @@ -1,30 +1,39 @@ // Class inclusions #include "Spotting.h" -#include "Cells.h" +#include "Cells.h" // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include using namespace std; -std::vector Spotting(std::unordered_map & Cells_Obj, std::vector> & coordCells, - std::unordered_set & AvailSet, double WSD, double WSC, - std::unordered_map spottingParams, bool verbose) { - - // TODO data structures should be passed by reference +std::vector +Spotting(std::unordered_map& Cells_Obj, + std::vector>& coordCells, + std::unordered_set& AvailSet, + double WSD, + double WSC, + std::unordered_map spottingParams, + bool verbose) +{ + + // TODO data structures should be passed by reference // TODO - std::unordered_map> Angles = std::unordered_map>(); - std::unordered_map> Distances = std::unordered_map>(); - std::unordered_map> SpotProb = std::unordered_map>(); - - if (spottingParams["SPOTANGLE"] * spottingParams["SPOT0PROB"] * spottingParams["SPOT10TIME"] * WSC == 0) { + std::unordered_map> Angles + = std::unordered_map>(); + std::unordered_map> Distances + = std::unordered_map>(); + std::unordered_map> SpotProb + = std::unordered_map>(); + + if (spottingParams["SPOTANGLE"] * spottingParams["SPOT0PROB"] * spottingParams["SPOT10TIME"] * WSC == 0) + { return vector(); } @@ -43,69 +52,82 @@ std::vector Spotting(std::unordered_map & Cells_Obj, std::vect if (WB > 360) WWindowB -= 360; - if (verbose) { - std::cout<< "Wind Direction:" << WSD << std::endl; + if (verbose) + { + std::cout << "Wind Direction:" << WSD << std::endl; std::cout << "Wind Speed:" << WSC << std::endl; std::cout << "Spotting Wind Windows: [" << WA << ", " << WB << "]" << std::endl; } // TODO: maybe true debugging /* - std::cout << "debug obj keys size " << Cells_Obj.size(); + std::cout << "debug obj keys size " << Cells_Obj.size(); std::cout << "debug AvailSet size " << AvailSet.size(); std::cout << "debug CoordCells size " << CoordCells.size(); - */ + */ - for (auto & _c1 : Cells_Obj) { + for (auto& _c1 : Cells_Obj) + { int c1 = 0; Angles[c1] = std::unordered_map(); Distances[c1] = std::unordered_map(); - for (auto & c2 : AvailSet){ - - if (c1 == c2) { + for (auto& c2 : AvailSet) + { + + if (c1 == c2) + { // CP: None = -1 Angles[c1][c2] = -1; Distances[c1][c2] = -1; - } else { + } + else + { int a = coordCells[c1][0] - coordCells[c2 - 1][0]; int b = coordCells[c1][1] - coordCells[c2 - 1][1]; - if (a == 0) { - if (b >= 0) + if (a == 0) + { + if (b >= 0) Angles[c1][c2] = 270; - else{ + else + { Angles[c1][c2] = 90; - Distances[c1][c2] = std::abs(b); - } + Distances[c1][c2] = std::abs(b); + } } - if (b == 0) { - if (a >= 0) + if (b == 0) + { + if (a >= 0) Angles[c1][c2] = 180; - else{ + else + { Angles[c1][c2] = 0; - Distances[c1][c2] = std::abs(a); - } + Distances[c1][c2] = std::abs(a); + } + } + + if (a != 0 && b != 0) + { + double radToDeg = 180 / M_PI; + double angle = std::atan(b * 1.0 / a) * radToDeg; + double distance = std::sqrt(a * a + b * b); + + if (a > 0) + angle += 180; + if (a < 0 && b > 0) + { + angle += 360; + Angles[c1][c2] = angle; + Distances[c1][c2] = distance; + } } - - if (a != 0 && b != 0) { - double radToDeg = 180 / M_PI; - double angle = std::atan(b * 1.0 / a) * radToDeg; - double distance = std::sqrt(a * a + b * b); - - if (a > 0) - angle += 180; - if (a < 0 && b > 0){ - angle += 360; - Angles[c1][c2] = angle; - Distances[c1][c2] = distance; - } - } - } + } } } - if (verbose) { - std::cout<< "Angles size: " << Angles.size() << std::endl; - std::cout<< "Distances size: " << Distances.size() << std::endl; + if (verbose) + { + std::cout << "Angles size: " << Angles.size() << std::endl; + std::cout << "Distances size: " << Distances.size() << std::endl; } // TODO: fix these later @@ -114,30 +136,38 @@ std::vector Spotting(std::unordered_map & Cells_Obj, std::vect double tilde_d = spottingParams["SPOT10TIME"] * WSC / cellsize; double alpha = std::log(.1) / tilde_d + std::log(beta) / tilde_d; - for (auto & _c1 : Cells_Obj) { + for (auto& _c1 : Cells_Obj) + { int c1 = _c1.first; SpotProb[c1] = std::unordered_map(); - for (auto & c2 : AvailSet) { + for (auto& c2 : AvailSet) + { // TODO: can't be None - if (Angles[c1][c2] == -1) { + if (Angles[c1][c2] == -1) + { SpotProb[c1][c2] = 0; - } else { + } + else + { SpotProb[c1][c2] = beta * std::exp(-1 * Distances[c1][c2] * alpha); double WA_t = WA; double WB_t = WB; // TODO the logic here is a shitshow - if (WA_t >= 0 && WB_t >= 0 && WA_t < 360 && WTolerance < 180) { + if (WA_t >= 0 && WB_t >= 0 && WA_t < 360 && WTolerance < 180) + { if (WB_t >= 360) WB_t -= 360; - if (!(Angles[c1][c2] <= WB_t && Angles[c1][c2] >= WA_t)) + if (!(Angles[c1][c2] <= WB_t && Angles[c1][c2] >= WA_t)) SpotProb[c1][c2] = 0; } WA_t = WA; WB_t = WB; - - if (WA_t < 0 && WB_t >= 0 && WB_t < 360 && WTolerance < 180) { - if (!(Angles[c1][c2] <= WB_t || Angles[c1][c2] >= WA_t + 360)) { + + if (WA_t < 0 && WB_t >= 0 && WB_t < 360 && WTolerance < 180) + { + if (!(Angles[c1][c2] <= WB_t || Angles[c1][c2] >= WA_t + 360)) + { SpotProb[c1][c2] = 0; } } @@ -145,32 +175,39 @@ std::vector Spotting(std::unordered_map & Cells_Obj, std::vect } } - if (verbose) { + if (verbose) + { std::cout << "Probabilities size: " << SpotProb.size() << std::endl; } - - // TODO: CHECK THIS FINAL STEP!!!!!! NOT COMPILING DUE TO C2 out of scope - // MODIFYING!!!! got rid of msg_list out of scope, got rid of c2 problem, BUT CHECK!!!!!!!!!! - // COMPILER THROWS ERROR: - - /* - In file included from SpottingFBP.h:4:0, - from SpottingFBP.cpp:2: -CellsFBP.h:57:9: note: candidate: CellsFBP::CellsFBP(int, double, std::vector, double, int, std::__cxx11::string, double, double, int, std::unordered_map, std::vector >&, std::vector, int, bool) - CellsFBP(int _id, double _area, std::vector _coord, double _age, - - */ + // TODO: CHECK THIS FINAL STEP!!!!!! NOT COMPILING DUE TO C2 out of scope + // MODIFYING!!!! got rid of msg_list out of scope, got rid of c2 problem, + // BUT CHECK!!!!!!!!!! COMPILER THROWS ERROR: + + /* + In file included from SpottingFBP.h:4:0, + from SpottingFBP.cpp:2: + CellsFBP.h:57:9: note: candidate: CellsFBP::CellsFBP(int, double, + std::vector, double, int, std::__cxx11::string, double, double, int, + std::unordered_map, std::vector >&, + std::vector, int, bool) CellsFBP(int _id, double _area, + std::vector _coord, double _age, + + */ std::vector msg_list = vector(); - - for (auto & _c1 : SpotProb) { + + for (auto& _c1 : SpotProb) + { int c1 = _c1.first; - for (auto & _c2 : SpotProb[c1]) { - int c2 = _c2.first; - double random = 1.0 * std::rand() / RAND_MAX; - if (SpotProb[c1][c2] > 0 && SpotProb[c1][c2] < random) { - if (verbose) { - std::cout << "Spotting msg from " << c1 + 1 << " to " << c2; + for (auto& _c2 : SpotProb[c1]) + { + int c2 = _c2.first; + double random = 1.0 * std::rand() / RAND_MAX; + if (SpotProb[c1][c2] > 0 && SpotProb[c1][c2] < random) + { + if (verbose) + { + std::cout << "Spotting msg from " << c1 + 1 << " to " << c2; } msg_list.push_back(c2); } diff --git a/Cell2Fire/Spotting.h b/Cell2Fire/Spotting.h index 63840d06..cd2495eb 100644 --- a/Cell2Fire/Spotting.h +++ b/Cell2Fire/Spotting.h @@ -1,24 +1,26 @@ #ifndef SPOTTING #define SPOTTING -#include "Cells.h" +#include "Cells.h" // Include libraries -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include +#include using namespace std; -std::vector Spotting(std::unordered_map & Cells_Obj, - std::vector> & coordCells, - std::unordered_set & AvailSet, double WSD, double WSC, - std::unordered_map spottingParams, bool verbose); +std::vector Spotting(std::unordered_map& Cells_Obj, + std::vector>& coordCells, + std::unordered_set& AvailSet, + double WSD, + double WSC, + std::unordered_map spottingParams, + bool verbose); #endif diff --git a/Cell2Fire/WriteCSV.cpp b/Cell2Fire/WriteCSV.cpp index 0c64862d..4535c7d8 100644 --- a/Cell2Fire/WriteCSV.cpp +++ b/Cell2Fire/WriteCSV.cpp @@ -1,313 +1,328 @@ #include "WriteCSV.h" +#include +#include #include -#include #include -#include +#include #include +#include #include -#include #include #include -#include -#include - +#include #if defined _WIN32 || defined __CYGWIN__ -#include -#include #include #include +#include +#include #endif - - /* * Constructur */ -CSVWriter::CSVWriter(std::string filename, std::string delm){ - this->fileName = filename; - this->delimeter = delm; - this->linesCount = 0; +CSVWriter::CSVWriter(std::string filename, std::string delm) +{ + this->fileName = filename; + this->delimeter = delm; + this->linesCount = 0; } - - + /* -* Prints iterator into a row of a csv file -*/ -template -void CSVWriter::addDatainRow(T first, T last){ - std::fstream file; - // Open the file in truncate mode if first line else in Append Mode - file.open(this->fileName, std::ios::out | (this->linesCount ? std::ios::app : std::ios::trunc)); - - // Iterate over the range and add each element to file seperated by delimeter. - for (; first != last; ) - { - file << *first; - if (++first != last) - file << this->delimeter; - } - file << "\n"; - this->linesCount++; - - // Close the file - file.close(); + * Prints iterator into a row of a csv file + */ +template +void +CSVWriter::addDatainRow(T first, T last) +{ + std::fstream file; + // Open the file in truncate mode if first line else in Append Mode + file.open(this->fileName, std::ios::out | (this->linesCount ? std::ios::app : std::ios::trunc)); + + // Iterate over the range and add each element to file seperated by + // delimeter. + for (; first != last;) + { + file << *first; + if (++first != last) + file << this->delimeter; + } + file << "\n"; + this->linesCount++; + + // Close the file + file.close(); } - -void CSVWriter::asciiHeader(int rows, int cols, double xllcorner, double yllcorner, int cellside) { - std::fstream file; - // Open the file in truncate mode if first line else in Append Mode - file.open(this->fileName, std::ios::out | (this->linesCount ? std::ios::app : std::ios::trunc)); - //first line: coles - file << "ncols"; - file << this->delimeter; - file << cols; - file << "\n"; - //second line: rows - file << "nrows"; - file << this->delimeter; - file << rows; - file << "\n"; - //third line: xllcorner - file << "xllcorner"; - file << this->delimeter; - file << xllcorner; - file << "\n"; - //fourth line: yllcorner - file << "yllcorner"; - file << this->delimeter; - file << yllcorner; - file << "\n"; - //cellsize - file << "cellsize"; - file << this->delimeter; - file << cellside; - file << "\n"; - //NODATA_value - file << "NODATA_value"; - file << this->delimeter; - file << -9999; - file << "\n"; - this->linesCount++; - // Close the file - file.close(); +void +CSVWriter::asciiHeader(int rows, int cols, double xllcorner, double yllcorner, int cellside) +{ + std::fstream file; + // Open the file in truncate mode if first line else in Append Mode + file.open(this->fileName, std::ios::out | (this->linesCount ? std::ios::app : std::ios::trunc)); + // first line: coles + file << "ncols"; + file << this->delimeter; + file << cols; + file << "\n"; + // second line: rows + file << "nrows"; + file << this->delimeter; + file << rows; + file << "\n"; + // third line: xllcorner + file << "xllcorner"; + file << this->delimeter; + file << xllcorner; + file << "\n"; + // fourth line: yllcorner + file << "yllcorner"; + file << this->delimeter; + file << yllcorner; + file << "\n"; + // cellsize + file << "cellsize"; + file << this->delimeter; + file << cellside; + file << "\n"; + // NODATA_value + file << "NODATA_value"; + file << this->delimeter; + file << -9999; + file << "\n"; + this->linesCount++; + // Close the file + file.close(); } /* -* Creates CSV -*/ -void CSVWriter::printCSV(int rows, int cols, std::vector statusCells) + * Creates CSV + */ +void +CSVWriter::printCSV(int rows, int cols, std::vector statusCells) { - // Create a rowVector for printing - std::vector rowVector; - - // Adding vector to CSV File - int r, c; - - // Printing rows (output) - for (r=0; r::const_iterator first = statusCells.begin() + c+r*cols; - std::vector::const_iterator last = statusCells.begin() + c+r*cols +cols; - std::vector rowVector(first, last); - - this->addDatainRow(rowVector.begin(), rowVector.end()); - c+=cols; - } - } - + // Create a rowVector for printing + std::vector rowVector; + + // Adding vector to CSV File + int r, c; + + // Printing rows (output) + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { + + std::vector::const_iterator first = statusCells.begin() + c + r * cols; + std::vector::const_iterator last = statusCells.begin() + c + r * cols + cols; + std::vector rowVector(first, last); + + this->addDatainRow(rowVector.begin(), rowVector.end()); + c += cols; + } + } } - /* -* Creates CSVDouble -*/ -void CSVWriter::printCSVDouble(int rows, int cols, std::vector network) + * Creates CSVDouble + */ +void +CSVWriter::printCSVDouble(int rows, int cols, std::vector network) { - // Create a rowVector for printing - std::vector rowVector; - - // Adding vector to CSV File - int r, c; - bool out; - out = false; - - // Printing rows (output) - for (r=0; r < rows; r++){ - - for (c=0; c < cols; c++){ - if (network[c+r*cols] < 1 || std::ceil(network[c+r*cols]) != network[c+r*cols]){ - out = true; - break; - } - - std::vector::const_iterator first = network.begin() + c+r*cols; - std::vector::const_iterator last = network.begin() + c+r*cols +cols; - std::vector rowVector(first, last); - - this->addDatainRow(rowVector.begin(), rowVector.end()); - c+=cols; - } - - if (out) { - break; - } - } - + // Create a rowVector for printing + std::vector rowVector; + + // Adding vector to CSV File + int r, c; + bool out; + out = false; + + // Printing rows (output) + for (r = 0; r < rows; r++) + { + + for (c = 0; c < cols; c++) + { + if (network[c + r * cols] < 1 || std::ceil(network[c + r * cols]) != network[c + r * cols]) + { + out = true; + break; + } + + std::vector::const_iterator first = network.begin() + c + r * cols; + std::vector::const_iterator last = network.begin() + c + r * cols + cols; + std::vector rowVector(first, last); + + this->addDatainRow(rowVector.begin(), rowVector.end()); + c += cols; + } + + if (out) + { + break; + } + } } - - // Ofstream version to save faster -void CSVWriter::printCSVDouble_V2(int rows, int cols, std::vector network) { - bool outs = false; - std::ofstream ofs(this->fileName, std::ofstream::out); - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { - if (network[c + r * cols] < 1 || network[c + r * cols + 1] < 1 || std::ceil(network[c + r * cols]) != network[c + r * cols]) { - outs = true; - break; - } - ofs << (int)network[c + r * cols] << this->delimeter << (int)network[c + r * cols + 1] << this->delimeter << (int)network[c + r * cols + 2] << this->delimeter << network[c + r * cols + 3] << "\n"; - c += cols; - } - - if (outs) { - break; - } - } - // Close file - ofs.close(); - +void +CSVWriter::printCSVDouble_V2(int rows, int cols, std::vector network) +{ + bool outs = false; + std::ofstream ofs(this->fileName, std::ofstream::out); + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + if (network[c + r * cols] < 1 || network[c + r * cols + 1] < 1 + || std::ceil(network[c + r * cols]) != network[c + r * cols]) + { + outs = true; + break; + } + ofs << (int)network[c + r * cols] << this->delimeter << (int)network[c + r * cols + 1] << this->delimeter + << (int)network[c + r * cols + 2] << this->delimeter << network[c + r * cols + 3] << "\n"; + c += cols; + } + + if (outs) + { + break; + } + } + // Close file + ofs.close(); } - - -void CSVWriter::printASCII(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells) +void +CSVWriter::printASCII( + int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells) { - // Create a rowVector for printing - std::vector rowVector; + // Create a rowVector for printing + std::vector rowVector; - // Adding vector to CSV File - int r, c; - // Add header to ascii file + // Adding vector to CSV File + int r, c; + // Add header to ascii file - this->asciiHeader(rows, cols, xllcorner, yllcorner, cellside); + this->asciiHeader(rows, cols, xllcorner, yllcorner, cellside); - // Printing rows (output) - for (r = 0; r < rows; r++) { - for (c = 0; c < cols; c++) { + // Printing rows (output) + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { - std::vector::const_iterator first = statusCells.begin() + c + r * cols; - std::vector::const_iterator last = statusCells.begin() + c + r * cols + cols; - std::vector rowVector(first, last); - - this->addDatainRow(rowVector.begin(), rowVector.end()); - c += cols; - } - } + std::vector::const_iterator first = statusCells.begin() + c + r * cols; + std::vector::const_iterator last = statusCells.begin() + c + r * cols + cols; + std::vector rowVector(first, last); + this->addDatainRow(rowVector.begin(), rowVector.end()); + c += cols; + } + } } -void CSVWriter::printASCIIInt(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells) +void +CSVWriter::printASCIIInt( + int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells) { - // Create a rowVector for printing - std::vector rowVector; - - // Adding vector to CSV File - int r, c; - // Add header to ascii file + // Create a rowVector for printing + std::vector rowVector; - this->asciiHeader(rows, cols, xllcorner, yllcorner, cellside); + // Adding vector to CSV File + int r, c; + // Add header to ascii file - // Printing rows (output) - for (r = 0; r < rows; r++) { - for (c = 0; c < cols; c++) { + this->asciiHeader(rows, cols, xllcorner, yllcorner, cellside); - std::vector::const_iterator first = statusCells.begin() + c + r * cols; - std::vector::const_iterator last = statusCells.begin() + c + r * cols + cols; - std::vector rowVector(first, last); + // Printing rows (output) + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { - this->addDatainRow(rowVector.begin(), rowVector.end()); - c += cols; - } - } + std::vector::const_iterator first = statusCells.begin() + c + r * cols; + std::vector::const_iterator last = statusCells.begin() + c + r * cols + cols; + std::vector rowVector(first, last); + this->addDatainRow(rowVector.begin(), rowVector.end()); + c += cols; + } + } } - - -void CSVWriter::printWeather(std::vector weatherHistory) +void +CSVWriter::printWeather(std::vector weatherHistory) { - std::ofstream ofs(this->fileName, std::ofstream::out); - int i; - - for (i = 0; i < weatherHistory.size(); i++) - { - ofs << weatherHistory[i] << "\n"; - } - // Close file - ofs.close(); + std::ofstream ofs(this->fileName, std::ofstream::out); + int i; + + for (i = 0; i < weatherHistory.size(); i++) + { + ofs << weatherHistory[i] << "\n"; + } + // Close file + ofs.close(); } -void CSVWriter::printIgnitions(std::unordered_map ignitionsHistory) +void +CSVWriter::printIgnitions(std::unordered_map ignitionsHistory) { - std::ofstream ofs(fileName, std::ofstream::out); - int i; + std::ofstream ofs(fileName, std::ofstream::out); + int i; - // Print column titles - ofs << "sim,point\n"; + // Print column titles + ofs << "sim,point\n"; - // Iterate through the map and print key-value pairs - for (i = 1; i < ignitionsHistory.size()+1; i++) { - ofs << i << "," << ignitionsHistory[i] << "\n"; - //ofs << i << "," << ignitionsHistory[i-1] << "\n"; - } + // Iterate through the map and print key-value pairs + for (i = 1; i < ignitionsHistory.size() + 1; i++) + { + ofs << i << "," << ignitionsHistory[i] << "\n"; + // ofs << i << "," << ignitionsHistory[i-1] << "\n"; + } - // Close file - ofs.close(); + // Close file + ofs.close(); } -void CSVWriter::printCSV_V2(int rows, int cols, std::vector statusCells) +void +CSVWriter::printCSV_V2(int rows, int cols, std::vector statusCells) { - std::ofstream ofs(this->fileName, std::ofstream::out); - std::string toOut; - int r,c,i; - - for (r = 0; r < rows; r++) - { - for (c = 0; c < cols; c++) - { - std::string toOut; - for (i = 0; i < cols; i ++){ - toOut += std::to_string(statusCells[c+r*cols + i]) + this->delimeter; - } - ofs << toOut << "\n"; - c+=cols; - } - } - // Close file - ofs.close(); + std::ofstream ofs(this->fileName, std::ofstream::out); + std::string toOut; + int r, c, i; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { + std::string toOut; + for (i = 0; i < cols; i++) + { + toOut += std::to_string(statusCells[c + r * cols + i]) + this->delimeter; + } + ofs << toOut << "\n"; + c += cols; + } + } + // Close file + ofs.close(); } - - -void CSVWriter::MakeDir(std::string pathPlot) { - // Default folder simOuts - const char * Dir; - #if defined _WIN32 || defined __CYGWIN__ - Dir = pathPlot.c_str(); - int ret = _mkdir(Dir); - #else - std::string inst="mkdir -p "; - pathPlot=inst+pathPlot; - Dir = pathPlot.c_str(); - int ret = system(Dir); - #endif - +void +CSVWriter::MakeDir(std::string pathPlot) +{ + // Default folder simOuts + const char* Dir; +#if defined _WIN32 || defined __CYGWIN__ + Dir = pathPlot.c_str(); + int ret = _mkdir(Dir); +#else + std::string inst = "mkdir -p "; + pathPlot = inst + pathPlot; + Dir = pathPlot.c_str(); + int ret = system(Dir); +#endif } diff --git a/Cell2Fire/WriteCSV.h b/Cell2Fire/WriteCSV.h index bd58be17..ea20f493 100644 --- a/Cell2Fire/WriteCSV.h +++ b/Cell2Fire/WriteCSV.h @@ -1,49 +1,52 @@ #ifndef WRITECSV #define WRITECSV +#include +#include #include -#include #include -#include +#include #include +#include #include -#include -#include #include #include -#include +#include - /* +/* * A class to read data from a csv file. */ -class CSVWriter{ -public: - // inmutable - std::string fileName; - std::string delimeter; - - // mutable - int linesCount; - - // Constructor - CSVWriter(std::string filename, std::string delm = ","); - - // Function to write data (row) to a CSV File - template - void addDatainRow(T first, T last); - - // Function to write the entire file - void printCSV(int rows, int cols, std::vector statusCells); - void printCSVDouble(int rows, int cols, std::vector network); - void printCSVDouble_V2(int rows, int cols, std::vector network); - void printASCII(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells); - void printASCIIInt(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells); - void asciiHeader(int rows, int cols, double xllcorner, double yllcorner, int cellside); - void printWeather(std::vector weatherHistory); - void printIgnitions(std::unordered_map ignitionsHistory); - void printCSV_V2(int rows, int cols, std::vector statusCells); - // Function to create a directory - void MakeDir(std::string pathPlot); +class CSVWriter +{ + public: + // inmutable + std::string fileName; + std::string delimeter; + + // mutable + int linesCount; + + // Constructor + CSVWriter(std::string filename, std::string delm = ","); + + // Function to write data (row) to a CSV File + template + void addDatainRow(T first, T last); + + // Function to write the entire file + void printCSV(int rows, int cols, std::vector statusCells); + void printCSVDouble(int rows, int cols, std::vector network); + void printCSVDouble_V2(int rows, int cols, std::vector network); + void + printASCII(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells); + void + printASCIIInt(int rows, int cols, double xllcorner, double yllcorner, int cellside, std::vector statusCells); + void asciiHeader(int rows, int cols, double xllcorner, double yllcorner, int cellside); + void printWeather(std::vector weatherHistory); + void printIgnitions(std::unordered_map ignitionsHistory); + void printCSV_V2(int rows, int cols, std::vector statusCells); + // Function to create a directory + void MakeDir(std::string pathPlot); }; - + #endif