From 7464ab211ff779519466bbd5cfacda18ea61264f Mon Sep 17 00:00:00 2001 From: mati Date: Mon, 27 Jan 2025 13:16:06 -0300 Subject: [PATCH 1/9] Read CBD and CBH from raster layers in Kitral --- Cell2Fire/FuelModelKitral.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cell2Fire/FuelModelKitral.cpp b/Cell2Fire/FuelModelKitral.cpp index f5be47e9..23b3d9ff 100644 --- a/Cell2Fire/FuelModelKitral.cpp +++ b/Cell2Fire/FuelModelKitral.cpp @@ -775,8 +775,8 @@ active_rate_of_spreadPL04(inputs* data, { 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; } From 79b26b8023a516662ad0535c4267bd7df6fb3d34 Mon Sep 17 00:00:00 2001 From: mati Date: Wed, 29 Jan 2025 15:12:55 -0300 Subject: [PATCH 2/9] Read CBD and CBH raster layers in Kitral --- Cell2Fire/FuelModelKitral.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Cell2Fire/FuelModelKitral.cpp b/Cell2Fire/FuelModelKitral.cpp index 23b3d9ff..e970c85e 100644 --- a/Cell2Fire/FuelModelKitral.cpp +++ b/Cell2Fire/FuelModelKitral.cpp @@ -797,7 +797,6 @@ checkActive(inputs* data, main_outs* at, int FMC) // En KITRAL SE USA PL04 float ros_critical, cbd, H, wa, i0, cbh; bool active; cbh = data->cbh; - i0 = pow((0.01 * cbh * (460 + 25.9 * FMC)), 1.5); H = hs[data->nftype][0]; wa = fls_david[data->nftype][0]; From d696c396b157fbc46785c1383b3a2fdb8e661694 Mon Sep 17 00:00:00 2001 From: mati Date: Tue, 28 Jan 2025 16:28:07 -0300 Subject: [PATCH 3/9] Calculate crown intensity and flamen length in kitral --- Cell2Fire/Cell2Fire.cpp | 12 ++++++------ Cell2Fire/Cells.cpp | 2 +- Cell2Fire/FuelModelKitral.h | 6 ++++++ Cell2Fire/FuelModelSpain.h | 5 +++++ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Cell2Fire/Cell2Fire.cpp b/Cell2Fire/Cell2Fire.cpp index 6ad8d633..7a90f4f7 100644 --- a/Cell2Fire/Cell2Fire.cpp +++ b/Cell2Fire/Cell2Fire.cpp @@ -692,7 +692,7 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1) this->surfaceIntensityFolder = Cell2Fire::createOutputFolder("SurfaceIntensity"); } // Crown Byram Intensity Folder - if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->crownIntensityFolder = Cell2Fire::createOutputFolder("CrownIntensity"); } @@ -702,12 +702,12 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1) this->surfaceFlameLengthFolder = Cell2Fire::createOutputFolder("SurfaceFlameLength"); } // Crown Flame Length Folder - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->crownFlameLengthFolder = Cell2Fire::createOutputFolder("CrownFlameLength"); } // max Flame Length Folder - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->maxFlameLengthFolder = Cell2Fire::createOutputFolder("MaxFlameLength"); } @@ -1954,7 +1954,7 @@ Cell2Fire::Results() } // Crown Intensity - if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->crownIntensityFolder = this->args.OutFolder + "CrownIntensity" + separator(); std::string intensityName; @@ -1990,7 +1990,7 @@ Cell2Fire::Results() } // Crown Flame length - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->crownFlameLengthFolder = this->args.OutFolder + "CrownFlameLength" + separator(); std::string fileName; @@ -2008,7 +2008,7 @@ Cell2Fire::Results() } // Max Flame length - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) { this->maxFlameLengthFolder = this->args.OutFolder + "MaxFlameLength" + separator(); std::string fileName; diff --git a/Cell2Fire/Cells.cpp b/Cell2Fire/Cells.cpp index d58d8ae7..6720f41b 100644 --- a/Cell2Fire/Cells.cpp +++ b/Cell2Fire/Cells.cpp @@ -677,7 +677,7 @@ Cells::manageFire(int period, surfFraction[nb] = metrics.sfc; SurfaceFlameLengths[this->realId - 1] = mainstruct.fl; SurfaceFlameLengths[nb - 1] = metrics.fl; - if ((args->AllowCROS) && (args->Simulator == "S")) + if ((args->AllowCROS) && (args->Simulator != "C")) { float comp_zero = 0; MaxFlameLengths[this->realId - 1] diff --git a/Cell2Fire/FuelModelKitral.h b/Cell2Fire/FuelModelKitral.h index 4eead707..4e99191b 100644 --- a/Cell2Fire/FuelModelKitral.h +++ b/Cell2Fire/FuelModelKitral.h @@ -32,6 +32,9 @@ float backfire_ros_k(main_outs* at, snd_outs* sec); // Flame length [m]) float flame_length(inputs* data, main_outs* at); +// Crown Flame length [m]) +float crown_flame_length_k(float intensity); + // Angle of the flame w.r.t. horizontal surface (Putnam's) float angleFL(inputs* data, main_outs* at); @@ -41,6 +44,9 @@ float flame_height(inputs* data, main_outs* at); // byram intensity float byram_intensity(inputs* data, main_outs* at); +// crown byram intensity +float crown_byram_intensity_k(main_outs* at, inputs* data); + // Type of fire (Crown = 1, SROS = 0) bool fire_type(inputs* data, main_outs* atr, int FMC); // Active crown diff --git a/Cell2Fire/FuelModelSpain.h b/Cell2Fire/FuelModelSpain.h index 2aa0f8f6..98c9daef 100644 --- a/Cell2Fire/FuelModelSpain.h +++ b/Cell2Fire/FuelModelSpain.h @@ -35,6 +35,8 @@ float backfire_ros_s(main_outs* at, snd_outs* sec); // Flame length [m]) float flame_length(inputs* data, fuel_coefs* ptr); +// Crown Flame length [m]) +float crown_flame_length(float intensity); // Angle of the flame w.r.t. horizontal surface (Putnam's) float angleFL(inputs* data, fuel_coefs* ptr); @@ -45,6 +47,9 @@ float flame_height(inputs* data, fuel_coefs* ptr); // byram intensity float byram_intensity(inputs* data, fuel_coefs* ptr); +// crown byram intensity +float crown_byram_intensity(main_outs* at, inputs* data); + // Type of fire (Crown = 1, SROS = 0) bool fire_type(inputs* data, fuel_coefs* ptr); From dc276f0007b5cfe532f9b96c4e2568cfcf889769 Mon Sep 17 00:00:00 2001 From: mati Date: Wed, 29 Jan 2025 15:22:11 -0300 Subject: [PATCH 4/9] Revert flame length changes --- Cell2Fire/Cell2Fire.cpp | 12 ++++++------ Cell2Fire/Cells.cpp | 2 +- Cell2Fire/FuelModelKitral.h | 6 ------ Cell2Fire/FuelModelSpain.h | 5 ----- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Cell2Fire/Cell2Fire.cpp b/Cell2Fire/Cell2Fire.cpp index 7a90f4f7..6ad8d633 100644 --- a/Cell2Fire/Cell2Fire.cpp +++ b/Cell2Fire/Cell2Fire.cpp @@ -692,7 +692,7 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1) this->surfaceIntensityFolder = Cell2Fire::createOutputFolder("SurfaceIntensity"); } // Crown Byram Intensity Folder - if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->crownIntensityFolder = Cell2Fire::createOutputFolder("CrownIntensity"); } @@ -702,12 +702,12 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1) this->surfaceFlameLengthFolder = Cell2Fire::createOutputFolder("SurfaceFlameLength"); } // Crown Flame Length Folder - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->crownFlameLengthFolder = Cell2Fire::createOutputFolder("CrownFlameLength"); } // max Flame Length Folder - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->maxFlameLengthFolder = Cell2Fire::createOutputFolder("MaxFlameLength"); } @@ -1954,7 +1954,7 @@ Cell2Fire::Results() } // Crown Intensity - if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->crownIntensityFolder = this->args.OutFolder + "CrownIntensity" + separator(); std::string intensityName; @@ -1990,7 +1990,7 @@ Cell2Fire::Results() } // Crown Flame length - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->crownFlameLengthFolder = this->args.OutFolder + "CrownFlameLength" + separator(); std::string fileName; @@ -2008,7 +2008,7 @@ Cell2Fire::Results() } // Max Flame length - if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C")) + if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S")) { this->maxFlameLengthFolder = this->args.OutFolder + "MaxFlameLength" + separator(); std::string fileName; diff --git a/Cell2Fire/Cells.cpp b/Cell2Fire/Cells.cpp index 6720f41b..d58d8ae7 100644 --- a/Cell2Fire/Cells.cpp +++ b/Cell2Fire/Cells.cpp @@ -677,7 +677,7 @@ Cells::manageFire(int period, surfFraction[nb] = metrics.sfc; SurfaceFlameLengths[this->realId - 1] = mainstruct.fl; SurfaceFlameLengths[nb - 1] = metrics.fl; - if ((args->AllowCROS) && (args->Simulator != "C")) + if ((args->AllowCROS) && (args->Simulator == "S")) { float comp_zero = 0; MaxFlameLengths[this->realId - 1] diff --git a/Cell2Fire/FuelModelKitral.h b/Cell2Fire/FuelModelKitral.h index 4e99191b..4eead707 100644 --- a/Cell2Fire/FuelModelKitral.h +++ b/Cell2Fire/FuelModelKitral.h @@ -32,9 +32,6 @@ float backfire_ros_k(main_outs* at, snd_outs* sec); // Flame length [m]) float flame_length(inputs* data, main_outs* at); -// Crown Flame length [m]) -float crown_flame_length_k(float intensity); - // Angle of the flame w.r.t. horizontal surface (Putnam's) float angleFL(inputs* data, main_outs* at); @@ -44,9 +41,6 @@ float flame_height(inputs* data, main_outs* at); // byram intensity float byram_intensity(inputs* data, main_outs* at); -// crown byram intensity -float crown_byram_intensity_k(main_outs* at, inputs* data); - // Type of fire (Crown = 1, SROS = 0) bool fire_type(inputs* data, main_outs* atr, int FMC); // Active crown diff --git a/Cell2Fire/FuelModelSpain.h b/Cell2Fire/FuelModelSpain.h index 98c9daef..2aa0f8f6 100644 --- a/Cell2Fire/FuelModelSpain.h +++ b/Cell2Fire/FuelModelSpain.h @@ -35,8 +35,6 @@ float backfire_ros_s(main_outs* at, snd_outs* sec); // Flame length [m]) float flame_length(inputs* data, fuel_coefs* ptr); -// Crown Flame length [m]) -float crown_flame_length(float intensity); // Angle of the flame w.r.t. horizontal surface (Putnam's) float angleFL(inputs* data, fuel_coefs* ptr); @@ -47,9 +45,6 @@ float flame_height(inputs* data, fuel_coefs* ptr); // byram intensity float byram_intensity(inputs* data, fuel_coefs* ptr); -// crown byram intensity -float crown_byram_intensity(main_outs* at, inputs* data); - // Type of fire (Crown = 1, SROS = 0) bool fire_type(inputs* data, fuel_coefs* ptr); From af3e5c569929f90f3eec159b4b083c409b88428d Mon Sep 17 00:00:00 2001 From: mati Date: Fri, 31 Jan 2025 15:55:11 -0300 Subject: [PATCH 5/9] [Fix] Use nodata value when cbd or cbh are empty --- Cell2Fire/ReadCSV.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cell2Fire/ReadCSV.cpp b/Cell2Fire/ReadCSV.cpp index 001f8d65..37d365be 100644 --- a/Cell2Fire/ReadCSV.cpp +++ b/Cell2Fire/ReadCSV.cpp @@ -28,7 +28,7 @@ CSVReader::CSVReader(std::string filename, std::string delm) /** * @brief Reads and parses data from a CSV, ASCII or TIFF file into a 2D vector. - * + * * Checks for the existence of the input file with either a `.tif` or `.asc` extension * and processes it accordingly. * If the file is in CSV format, it is read line by line and split using From 8dc23bc5d0aa50d9e5478da381af960db0830a30 Mon Sep 17 00:00:00 2001 From: mati Date: Wed, 12 Mar 2025 12:03:12 -0300 Subject: [PATCH 6/9] [fix] cbd has to be greater than 0 in order to be used --- Cell2Fire/FuelModelKitral.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cell2Fire/FuelModelKitral.cpp b/Cell2Fire/FuelModelKitral.cpp index e970c85e..12bff6c1 100644 --- a/Cell2Fire/FuelModelKitral.cpp +++ b/Cell2Fire/FuelModelKitral.cpp @@ -775,8 +775,8 @@ active_rate_of_spreadPL04(inputs* data, { 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; } From 147a0020c966a7e6275506a53e2ae558add57aa0 Mon Sep 17 00:00:00 2001 From: mati Date: Wed, 12 Mar 2025 12:03:34 -0300 Subject: [PATCH 7/9] [test] test crown fraction burn using cbd layer --- test/unit_tests/test_kitral.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit_tests/test_kitral.cpp b/test/unit_tests/test_kitral.cpp index f68d54b2..ad4ebe27 100644 --- a/test/unit_tests/test_kitral.cpp +++ b/test/unit_tests/test_kitral.cpp @@ -46,7 +46,7 @@ class NativeFuelFixture // Initialize fuel_coefs test_coefs->nftype = 16; test_coefs->fmc = 0.000979; - test_coefs->cbh = 0; + test_coefs->cbh = 13.8; test_coefs->fl = 3.544; test_coefs->h = 19045; @@ -278,9 +278,9 @@ TEST_CASE_METHOD(NativeFuelFixture, "Test crown fraction burn", "[crownfractionb int FMC = 100; // Default value in ReadArgs.cpp test_data->cbd = 0.15; test_outs->rss = 8; - REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.524, 0.001)); + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.841, 0.001)); test_outs->rss = 15; - REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.835, 0.001)); + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.968, 0.001)); test_outs->rss = 30; REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.982, 0.001)); } From d735f6eac012a7800584c0f2fce6a25f8a346174 Mon Sep 17 00:00:00 2001 From: mati Date: Mon, 17 Mar 2025 15:21:13 -0300 Subject: [PATCH 8/9] [test] Unit test for fm PL03 --- Cell2Fire/FuelModelKitral.h | 3 + test/unit_tests/test_kitral.cpp | 396 ++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) diff --git a/Cell2Fire/FuelModelKitral.h b/Cell2Fire/FuelModelKitral.h index 4eead707..a179ffe4 100644 --- a/Cell2Fire/FuelModelKitral.h +++ b/Cell2Fire/FuelModelKitral.h @@ -17,6 +17,9 @@ // Initialize coefficients void setup_const(); +// Initialized raster data +void setup_crown_const(inputs* data); + // Calculate flank fire float flankfire_ros_k(float ros, float bros, float lb); diff --git a/test/unit_tests/test_kitral.cpp b/test/unit_tests/test_kitral.cpp index ad4ebe27..eb8d63e9 100644 --- a/test/unit_tests/test_kitral.cpp +++ b/test/unit_tests/test_kitral.cpp @@ -78,6 +78,9 @@ class NativeFuelFixture test_outs->crown = 0; test_outs->jd_min = 0; test_outs->jd = 0; + + setup_crown_const(test_data); + } }; @@ -350,3 +353,396 @@ TEST_CASE_METHOD(NativeFuelFixture, "Test backfire ros in crown fire changes wit hptr->ros = 16; REQUIRE_THAT(backfire_ros10_k(hptr, sec), WithinAbs(8.122, 0.001)); } + + +TEST_CASE_METHOD(NativeFuelFixture, "Test fire type changes with intensity", "[fire_type]") +{ + int FMC = 100; + test_data->cbh = 7.5; + test_outs->sfi = 3200; + REQUIRE(fire_type(test_data, test_outs, FMC) == false); + test_outs->sfi = 4030; + REQUIRE(fire_type(test_data, test_outs, FMC) == true); + test_outs->sfi = 40420; + REQUIRE(fire_type(test_data, test_outs, FMC) == true); +} + + +TEST_CASE_METHOD(NativeFuelFixture, "Test fire type changes with CBH", "[fire_type]") +{ + int FMC = 100; + test_data->cbh = 7.5; + test_outs->sfi = 3200; + REQUIRE(fire_type(test_data, test_outs, FMC) == false); + test_data->cbh = 5.5; + REQUIRE(fire_type(test_data, test_outs, FMC) == true); +} + + +class PlantationFuelFixture +{ +public: + inputs* test_data; + fuel_coefs* test_coefs; + main_outs* test_outs; + +public: + PlantationFuelFixture() + { + setup_const(); + test_data = new inputs(); + test_coefs = new fuel_coefs(); + test_outs = new main_outs(); + + strcpy(test_data->fueltype, "PL03"); + test_data->nftype = 21; + test_data->ws = 10; + test_data->waz = 45; + test_data->tmp = 27; + test_data->rh = 40; + test_data->elev = 82.7; + test_data->cbh = 11.05; + test_data->cbd = 0.218; + test_data->tree_height = 33; + + // Initialize fuel_coefs + test_coefs->nftype = 21; + test_coefs->fmc = 0.002481; + test_coefs->cbh = 11.05; + test_coefs->fl = 3.333; + test_coefs->h = 20376; + + test_outs->hffmc = 0; + test_outs->sfc = 0; + test_outs->csi = 0; + test_outs->fl = 0; + test_outs->fh = 0; + test_outs->a = 0; + test_outs->b = 0; + test_outs->c = 0; + test_outs->rss = 0; + test_outs->angle = 0; + test_outs->ros_active = 0; + test_outs->cfb = 0; + test_outs->se = 0; + test_outs->rso = 0; + test_outs->fmc = 0; + test_outs->sfi = 0; + test_outs->isi = 0; + test_outs->be = 0; + test_outs->sf = 0; + test_outs->raz = 0; + test_outs->wsv = 0; + test_outs->ff = 0; + test_outs->crown_intensity = 0; + test_outs->crown_flame_length = 0; + test_outs->max_flame_length; + test_outs->crown = 0; + test_outs->jd_min = 0; + test_outs->jd = 0; + + setup_crown_const(test_data); + + } + +}; + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Rate of spread changes with slope", "[rate_of_spread_k]") +{ + test_outs->se = 1; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(4.020, 0.001)); + test_outs->se = 0.5; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(3.708, 0.001)); + test_outs->se = 1.5; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(4.332, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Rate of spread changes with wind", "[rate_of_spread_k]") +{ + test_outs->se = 1.2; + test_data->ws = 10; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(4.145, 0.001)); + test_data->ws = 50; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(8.426, 0.001)); + test_data->ws = 100; + rate_of_spread_k(test_data, test_coefs, test_outs); + REQUIRE_THAT(test_outs->rss, WithinAbs(9.245, 0.001)); +} + +//TODO: test reaction to temperature, humidity + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test length to breadth", "[l_to_b]") +{ + REQUIRE_THAT(l_to_b(10, test_coefs), WithinAbs(1.058, 0.001)); + REQUIRE_THAT(l_to_b(100, test_coefs), WithinAbs(17.225, 0.001)); + //REQUIRE_THROWS(l_to_b(-1, test_coefs)); + // This should throw exception in the future +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test backfire ros", "[backfire_ros_k]") +{ + auto sec = new snd_outs(); + sec->lb = 1.058; + test_outs->rss = 8; + REQUIRE_THAT(backfire_ros_k(test_outs, sec), WithinAbs(4.061, 0.001)); + sec->lb = 17.225; + REQUIRE_THAT(backfire_ros_k(test_outs, sec), WithinAbs(0.006, 0.001)); + sec->lb = 17.225; + test_outs->rss = 15; + REQUIRE_THAT(backfire_ros_k(test_outs, sec), WithinAbs(0.0126, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test flankfire ros", "[flankfire_ros_k]") +{ + REQUIRE_THAT(flankfire_ros_k(8, 4, 1.058), WithinAbs(5.671, 0.001)); + REQUIRE_THAT(flankfire_ros_k(15, 0.126, 17.225), WithinAbs(0.439, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test byram intensity", "[byram_intensity]") +{ + test_outs->rss = 15; + REQUIRE_THAT(byram_intensity(test_data, test_outs), WithinAbs(16978.310, 0.001)); + test_outs->rss = 5.6; + REQUIRE_THAT(byram_intensity(test_data, test_outs), WithinAbs(6338.569, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test surface flame length", "[flame_length]") +{ + test_outs->sfi = 16873.87; + REQUIRE_THAT(flame_length(test_data, test_outs), WithinAbs(6.82, 0.001)); + test_outs->sfi = 6299.58; + REQUIRE_THAT(flame_length(test_data, test_outs), WithinAbs(4.334, 0.001)); + test_outs->sfi = 40420; + REQUIRE_THAT(flame_length(test_data, test_outs), WithinAbs(10.193, 0.001)); +} + + +TEST_CASE_METHOD(PlantationFuelFixture, "PL PL Test flame angle", "[angleFL]") +{ + test_data->ws = 10; + test_outs->fl = 6.82; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(1.127, 0.001)); + test_outs->fl = 4.334; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(1.033, 0.001)); + test_outs->fl = 10.193; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(1.2, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test flame angle changes with wind", "[angleFL]") +{ + test_data->ws = 100; + test_outs->fl = 6.82; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(0.207, 0.001)); + test_outs->fl = 4.334; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(0.166, 0.001)); + test_outs->fl = 10.193; + REQUIRE_THAT(angleFL(test_data, test_outs), WithinAbs(0.251, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test flame height", "[flame_height]") +{ + test_data->ws = 10; + test_outs->fl = 6.82; + REQUIRE_THAT(flame_height(test_data, test_outs), WithinAbs(6.160, 0.001)); + test_outs->fl = 4.334; + REQUIRE_THAT(flame_height(test_data, test_outs), WithinAbs(3.723, 0.001)); + test_outs->fl = 10.193; + REQUIRE_THAT(flame_height(test_data, test_outs), WithinAbs(9.501, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test flame height changes with wind", "[flame_height]") +{ + test_data->ws = 100; + test_outs->fl = 6.82; + float fl_100 = flame_height(test_data, test_outs); + REQUIRE_THAT(fl_100, WithinAbs(1.405, 0.001)); + test_data->ws = 50; + float fl_50 = flame_height(test_data, test_outs); + REQUIRE_THAT(fl_50, WithinAbs(2.647, 0.001)); + REQUIRE(fl_50 > fl_100); +} + + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Active rate of spread changes with slope", "[active_rate_of_spreadPL04]") +{ + test_data->ws = 20; + test_data->tmp = 27; + test_data->rh = 40; + test_outs->se = 1; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(9.977, 0.001)); + test_outs->se = 0.5; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(9.101, 0.001)); + test_outs->se = 1.8; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(11.378, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Active rate of spread changes with wind", "[active_rate_of_spreadPL04]") +{ + test_outs->se = 1.3; + test_data->tmp = 27; + test_data->rh = 40; + test_data->ws = 10; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(7.496, 0.001)); + test_data->ws = 50; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(16.951, 0.001)); + test_data->ws = 100; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(22.445, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, + "PL Active rate of spread changes with temperature", + "[active_rate_of_spreadPL04]") +{ + test_data->ws = 20; + test_data->rh = 40; + test_outs->se = 1.2; + test_data->tmp = -10; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(9.521, 0.001)); + test_data->tmp = 0; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(9.728, 0.001)); + test_data->tmp = 10; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(9.943, 0.001)); + test_data->tmp = 20; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(10.166, 0.001)); + test_data->tmp = 30; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(10.397, 0.001)); + test_data->tmp = 40; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(10.637, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Active rate of spread changes with humidity", "[active_rate_of_spreadPL04]") +{ + test_data->ws = 20; + test_data->tmp = 26; + test_outs->se = 1.2; + test_data->rh = 5; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(115.518, 0.001)); + test_data->rh = 25; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(36.817, 0.001)); + test_data->rh = 45; + REQUIRE_THAT(active_rate_of_spreadPL04(test_data, test_outs), WithinAbs(7.823, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test check for active fire", "[checkActive]") +{ + int FMC = 100; // Default value in ReadArgs.cpp + REQUIRE(checkActive(test_data, test_outs, FMC)==false); + //TODO: use real cbd and cbh values +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test crown fraction burn", "[crownfractionburn]") +{ + int FMC = 100; // Default value in ReadArgs.cpp + test_outs->rss = 8; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.542, 0.001)); + test_outs->rss = 15; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.947, 0.001)); + test_outs->rss = 30; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.999, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test crown fraction burn changes with CBD", "[crownfractionburn]") +{ + int FMC = 100; // Default value in ReadArgs.cpp + test_outs->rss = 8; + test_data->cbd = 0.15; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.359, 0.001)); + test_data->cbd = 0.3; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.760, 0.001)); + test_data->cbd = -9999; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.441, 0.001)); + test_data->cbd = 0; + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.441, 0.001)); +} + + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test final ros changes with ros", "[final_rate_of_spreadPL04]") +{ + test_outs->rss = 4; + test_outs->ros_active = 10.3; + test_outs->cfb = 0.89; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(9.607, 0.001)); + test_outs->rss = 8; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(10.047, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test final ros changes with ros active", "[final_rate_of_spreadPL04]") +{ + test_outs->rss = 4; + test_outs->ros_active = 10.3; + test_outs->cfb = 0.89; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(9.607, 0.001)); + test_outs->ros_active = 14; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(12.9, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test final ros changes with cfb", "[final_rate_of_spreadPL04]") +{ + test_outs->rss = 4; + test_outs->ros_active = 10.3; + test_outs->cfb = 0.89; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(9.607, 0.001)); + test_outs->cfb = 0.99; + REQUIRE_THAT(final_rate_of_spreadPL04(test_outs), WithinAbs(10.237, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test backfire ros in crown fire changes with lb", "[backfire_ros10_k]") +{ + auto sec = new snd_outs(); + auto hptr = new fire_struc(); + sec->lb = 1.058; + hptr->ros = 8; + REQUIRE_THAT(backfire_ros10_k(hptr, sec), WithinAbs(4.061, 0.001)); + sec->lb = 17.225; + REQUIRE_THAT(backfire_ros10_k(hptr, sec), WithinAbs(0.006, 0.001)); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test backfire ros in crown fire changes with ros", "[backfire_ros10_k]") +{ + auto sec = new snd_outs(); + auto hptr = new fire_struc(); + sec->lb = 1.058; + hptr->ros = 8; + REQUIRE_THAT(backfire_ros10_k(hptr, sec), WithinAbs(4.061, 0.001)); + hptr->ros = 16; + REQUIRE_THAT(backfire_ros10_k(hptr, sec), WithinAbs(8.122, 0.001)); +} + + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test fire type changes with intensity", "[fire_type]") +{ + int FMC = 100; + test_outs->sfi = 3200; + REQUIRE(fire_type(test_data, test_outs, FMC) == false); + test_outs->sfi = 4030; + REQUIRE(fire_type(test_data, test_outs, FMC) == false); + test_outs->sfi = 40420; + REQUIRE(fire_type(test_data, test_outs, FMC) == true); +} + + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test fire type changes with CBH", "[fire_type]") +{ + int FMC = 100; + test_outs->sfi = 3200; + REQUIRE(fire_type(test_data, test_outs, FMC) == false); + test_data->cbh = 5.5; + REQUIRE(fire_type(test_data, test_outs, FMC) == true); +} + +TEST_CASE_METHOD(PlantationFuelFixture, "PL Test setup canopy constants", "[setup_crown_const]") +{ + test_data->cbh = -9999; + test_data->cbd = 0.01; + setup_crown_const((test_data)); + REQUIRE_THAT(test_data->cbh, WithinAbs(11.05, 0.001)); + REQUIRE_THAT(test_data->cbd, WithinAbs(0.01, 0.001)); + test_data->cbd = -9999; + setup_crown_const(test_data); + REQUIRE_THAT(test_data->cbd, WithinAbs(0.218, 0.001)); +} \ No newline at end of file From b8347d8d96c0dbf1b569a94033ea9ccbc2655b7b Mon Sep 17 00:00:00 2001 From: mati Date: Fri, 2 May 2025 17:58:51 -0400 Subject: [PATCH 9/9] Update crown fraction burn results --- test/unit_tests/test_kitral.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit_tests/test_kitral.cpp b/test/unit_tests/test_kitral.cpp index eb8d63e9..fc91b73b 100644 --- a/test/unit_tests/test_kitral.cpp +++ b/test/unit_tests/test_kitral.cpp @@ -281,9 +281,9 @@ TEST_CASE_METHOD(NativeFuelFixture, "Test crown fraction burn", "[crownfractionb int FMC = 100; // Default value in ReadArgs.cpp test_data->cbd = 0.15; test_outs->rss = 8; - REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.841, 0.001)); + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.524, 0.001)); test_outs->rss = 15; - REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.968, 0.001)); + REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.835, 0.001)); test_outs->rss = 30; REQUIRE_THAT(crownfractionburn(test_data, test_outs, FMC), WithinAbs(0.982, 0.001)); }