Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ SET(SOURCE
src/behave/randfuel.cpp
src/behave/randthread.cpp
src/behave/safety.cpp
src/behave/safeSeparationDistanceCalculator.cpp
src/behave/slopeTool.cpp
src/behave/species_master_table.cpp
src/behave/spot.cpp
Expand Down Expand Up @@ -122,6 +123,7 @@ SET(HEADERS
src/behave/randfuel.h
src/behave/randthread.h
src/behave/safety.h
src/behave/safeSeparationDistanceCalculator.h
src/behave/slopeTool.h
src/behave/species_master_table.h
src/behave/spot.h
Expand Down
172 changes: 172 additions & 0 deletions src/behave/safeSeparationDistanceCalculator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#include "safeSeparationDistanceCalculator.h"

const std::unordered_map<std::tuple<SpeedClass::SpeedClassEnum, BurningCondition::BurningConditionEnum, SlopeClass::SlopeClassEnum>, double, TupleHash> SafeSeparationDistanceCalculator::deltaLookup = {
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Flat}, 1.0},
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Moderate}, 1.0},
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Steep}, 2.0},

// Moderate Burning Conditions
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Flat}, 1.0},
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Moderate}, 1.0},
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Steep}, 2.0},

// Extreme Burning Conditions
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Flat}, 1.0},
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Moderate}, 2.0},
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Steep}, 3.0},

/// Moderate Wind Speed
// Light Burning Conditions
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Flat}, 1.5},
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Moderate}, 3.0},
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Steep}, 4.0},

// Moderate Burning Conditions
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Flat}, 2.0},
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Moderate}, 4.0},
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Steep}, 5.0},

// Extreme Burning Conditions
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Flat}, 2.5},
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Moderate}, 5.0},
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Steep}, 5.0},

/// High Wind Speed
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Flat}, 3.0},
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Moderate}, 4.0},
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Steep}, 6.0},

// Moderate Burning Conditions
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Flat}, 3.0},
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Moderate}, 5.0},
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Steep}, 7.0},

// Extreme Burning Conditions
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Flat}, 4.0},
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Moderate}, 5.0},
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Steep}, 10.0},
};

SafeSeparationDistanceCalculator::SafeSeparationDistanceCalculator()
{
burningCondition_ = BurningCondition::Low;
slopeClass_ = SlopeClass::Flat;
speedClass_ = SpeedClass::Light;
vegetationHeight_ = 0.0;
safeSeparationDistance_ = 0.0;
safetyZoneSize_ = 0.0;
}

SafeSeparationDistanceCalculator::~SafeSeparationDistanceCalculator() {
}

SafeSeparationDistanceCalculator::SafeSeparationDistanceCalculator(const SafeSeparationDistanceCalculator& rhs)
{
memberwiseCopyAssignment(rhs);
}

SafeSeparationDistanceCalculator& SafeSeparationDistanceCalculator::operator=(const SafeSeparationDistanceCalculator& rhs)
{
if (this != &rhs)
{
memberwiseCopyAssignment(rhs);
}
return *this;
}

// Calculate

void SafeSeparationDistanceCalculator::calculate() {
double vegetationHeight = LengthUnits::fromBaseUnits(vegetationHeight_, LengthUnits::Feet);

double delta = SafeSeparationDistanceCalculator::getValue(speedClass_, burningCondition_, slopeClass_);

// Perform calculation using delta
double safeSeparationDistance = 8.0 * vegetationHeight * delta;
double safetyZoneSize = M_PI * pow(safeSeparationDistance, 2.0);

safeSeparationDistance_ = LengthUnits::toBaseUnits(safeSeparationDistance, LengthUnits::Feet);
safetyZoneSize_ = AreaUnits::toBaseUnits(safetyZoneSize, AreaUnits::Acres);
}

// Getters
BurningCondition::BurningConditionEnum SafeSeparationDistanceCalculator::getBurningCondition() {
return burningCondition_;
}

SlopeClass::SlopeClassEnum SafeSeparationDistanceCalculator::getSlopeClass() {
return slopeClass_;
}

SpeedClass::SpeedClassEnum SafeSeparationDistanceCalculator::getSpeedClass() {
return speedClass_;
}

SafetyCondition::SafetyConditionEnum SafeSeparationDistanceCalculator::getSafetyCondition() {
if (slopeClass_ == SlopeClass::Flat) {
if (speedClass_ == SpeedClass::High) {
return SafetyCondition::Moderate;
} else {
return SafetyCondition::Low;
}
} else if (slopeClass_ == SlopeClass::Moderate) {
if (speedClass_ == SpeedClass::Light) {
return SafetyCondition::Low;
} else if (speedClass_ == SpeedClass::Moderate) {
return SafetyCondition::Moderate;
} else {
return SafetyCondition::Extreme;
}
} else /* Steep Slope */ {
if (speedClass_ == SpeedClass::Light) {
if (burningCondition_ == BurningCondition::Extreme) {
return SafetyCondition::Moderate;
} else {
return SafetyCondition::Low;
}
} else if (speedClass_ == SpeedClass::Moderate) {
return SafetyCondition::Moderate;
} else {
return SafetyCondition::Extreme;
}
}
}

double SafeSeparationDistanceCalculator::getVegetationHeight(LengthUnits::LengthUnitsEnum lengthUnits) {
return LengthUnits::fromBaseUnits(vegetationHeight_, lengthUnits);
}

double SafeSeparationDistanceCalculator::getSafeSeparationDistance(LengthUnits::LengthUnitsEnum lengthUnits) {
return LengthUnits::fromBaseUnits(safeSeparationDistance_, lengthUnits);
}

double SafeSeparationDistanceCalculator::getSafetyZoneSize(AreaUnits::AreaUnitsEnum areaUnits) {
return AreaUnits::fromBaseUnits(safetyZoneSize_, areaUnits);
}

// Setters
void SafeSeparationDistanceCalculator::setBurningCondition(BurningCondition::BurningConditionEnum condition) {
burningCondition_ = condition;
}

void SafeSeparationDistanceCalculator::setSlopeClass(SlopeClass::SlopeClassEnum slope) {
slopeClass_ = slope;
}

void SafeSeparationDistanceCalculator::setSpeedClass(SpeedClass::SpeedClassEnum speed) {
speedClass_ = speed;
}

void SafeSeparationDistanceCalculator::setVegetationHeight(double vegetationHeight, LengthUnits::LengthUnitsEnum lengthUnits) {
vegetationHeight_ = LengthUnits::toBaseUnits(vegetationHeight, lengthUnits);
}

void SafeSeparationDistanceCalculator::memberwiseCopyAssignment(const SafeSeparationDistanceCalculator& rhs)
{
burningCondition_ = rhs.burningCondition_;
slopeClass_ = rhs.slopeClass_;
speedClass_ = rhs.speedClass_;
vegetationHeight_ = rhs.vegetationHeight_;
safeSeparationDistance_ = rhs.safeSeparationDistance_;
safetyZoneSize_ = rhs.safetyZoneSize_;
}
93 changes: 93 additions & 0 deletions src/behave/safeSeparationDistanceCalculator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#pragma once
#include <math.h>
#include <unordered_map>
#include <tuple>
#include "behaveUnits.h"

struct BurningCondition {
enum BurningConditionEnum {
Low,
Moderate,
Extreme
};
};

struct SlopeClass {
enum SlopeClassEnum {
Flat,
Moderate,
Steep
};
};

struct SpeedClass {
enum SpeedClassEnum {
Light,
Moderate,
High
};
};

struct SafetyCondition {
enum SafetyConditionEnum {
Low,
Moderate,
Extreme
};
};

struct TupleHash {
template <typename T1, typename T2, typename T3>
std::size_t operator()(const std::tuple<T1, T2, T3>& t) const {
auto hash1 = std::hash<T1>{}(std::get<0>(t));
auto hash2 = std::hash<T2>{}(std::get<1>(t));
auto hash3 = std::hash<T3>{}(std::get<2>(t));
return hash1 ^ (hash2 << 1) ^ (hash3 << 2); // Combine the hash values
}
};

class SafeSeparationDistanceCalculator {
public:
SafeSeparationDistanceCalculator();
~SafeSeparationDistanceCalculator();
SafeSeparationDistanceCalculator(const SafeSeparationDistanceCalculator& rhs);
SafeSeparationDistanceCalculator& operator=(const SafeSeparationDistanceCalculator& rhs);

// calculate
void calculate();

// Getters
BurningCondition::BurningConditionEnum getBurningCondition();
SlopeClass::SlopeClassEnum getSlopeClass();
SpeedClass::SpeedClassEnum getSpeedClass();
SafetyCondition::SafetyConditionEnum getSafetyCondition();
double getVegetationHeight(LengthUnits::LengthUnitsEnum lengthUnits);
double getSafeSeparationDistance(LengthUnits::LengthUnitsEnum lengthUnits);
double getSafetyZoneSize(AreaUnits::AreaUnitsEnum areaUnits);

// Setters
void setBurningCondition(BurningCondition::BurningConditionEnum condition);
void setSlopeClass(SlopeClass::SlopeClassEnum slope);
void setSpeedClass(SpeedClass::SpeedClassEnum speed);
void setVegetationHeight(double height, LengthUnits::LengthUnitsEnum lengthUnits);

protected:
void memberwiseCopyAssignment(const SafeSeparationDistanceCalculator& rhs);
static double getValue(SpeedClass::SpeedClassEnum speed, BurningCondition::BurningConditionEnum burning, SlopeClass::SlopeClassEnum slope) {
auto key = std::make_tuple(speed, burning, slope);
auto it = deltaLookup.find(key);
if (it != deltaLookup.end()) {
return it->second;
}
return 0.0;
}

BurningCondition::BurningConditionEnum burningCondition_;
SlopeClass::SlopeClassEnum slopeClass_;
SpeedClass::SpeedClassEnum speedClass_;
double vegetationHeight_;
double safeSeparationDistance_;
double safetyZoneSize_;

static const std::unordered_map<std::tuple<SpeedClass::SpeedClassEnum, BurningCondition::BurningConditionEnum, SlopeClass::SlopeClassEnum>, double, TupleHash> deltaLookup;
};