Skip to content

Commit 63e1b41

Browse files
authored
Merge pull request #55 from firelab/rj-BHP1-1247-ssd-calc
[BHP1-1247] Add Safe Separation Distance Calculator
2 parents a34f51a + df6e0ae commit 63e1b41

3 files changed

Lines changed: 267 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ SET(SOURCE
8282
src/behave/randthread.cpp
8383
src/behave/relativeHumidity.cpp
8484
src/behave/safety.cpp
85+
src/behave/safeSeparationDistanceCalculator.cpp
8586
src/behave/slopeTool.cpp
8687
src/behave/species_master_table.cpp
8788
src/behave/spot.cpp
@@ -124,6 +125,7 @@ SET(HEADERS
124125
src/behave/randthread.h
125126
src/behave/relativeHumidity.h
126127
src/behave/safety.h
128+
src/behave/safeSeparationDistanceCalculator.h
127129
src/behave/slopeTool.h
128130
src/behave/species_master_table.h
129131
src/behave/spot.h
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#include "safeSeparationDistanceCalculator.h"
2+
3+
const std::unordered_map<std::tuple<SpeedClass::SpeedClassEnum, BurningCondition::BurningConditionEnum, SlopeClass::SlopeClassEnum>, double, TupleHash> SafeSeparationDistanceCalculator::deltaLookup = {
4+
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Flat}, 1.0},
5+
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Moderate}, 1.0},
6+
{{SpeedClass::Light, BurningCondition::Low, SlopeClass::Steep}, 2.0},
7+
8+
// Moderate Burning Conditions
9+
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Flat}, 1.0},
10+
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Moderate}, 1.0},
11+
{{SpeedClass::Light, BurningCondition::Moderate, SlopeClass::Steep}, 2.0},
12+
13+
// Extreme Burning Conditions
14+
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Flat}, 1.0},
15+
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Moderate}, 2.0},
16+
{{SpeedClass::Light, BurningCondition::Extreme, SlopeClass::Steep}, 3.0},
17+
18+
/// Moderate Wind Speed
19+
// Light Burning Conditions
20+
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Flat}, 1.5},
21+
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Moderate}, 3.0},
22+
{{SpeedClass::Moderate, BurningCondition::Low, SlopeClass::Steep}, 4.0},
23+
24+
// Moderate Burning Conditions
25+
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Flat}, 2.0},
26+
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Moderate}, 4.0},
27+
{{SpeedClass::Moderate, BurningCondition::Moderate, SlopeClass::Steep}, 5.0},
28+
29+
// Extreme Burning Conditions
30+
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Flat}, 2.5},
31+
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Moderate}, 5.0},
32+
{{SpeedClass::Moderate, BurningCondition::Extreme, SlopeClass::Steep}, 5.0},
33+
34+
/// High Wind Speed
35+
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Flat}, 3.0},
36+
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Moderate}, 4.0},
37+
{{SpeedClass::High, BurningCondition::Low, SlopeClass::Steep}, 6.0},
38+
39+
// Moderate Burning Conditions
40+
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Flat}, 3.0},
41+
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Moderate}, 5.0},
42+
{{SpeedClass::High, BurningCondition::Moderate, SlopeClass::Steep}, 7.0},
43+
44+
// Extreme Burning Conditions
45+
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Flat}, 4.0},
46+
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Moderate}, 5.0},
47+
{{SpeedClass::High, BurningCondition::Extreme, SlopeClass::Steep}, 10.0},
48+
};
49+
50+
SafeSeparationDistanceCalculator::SafeSeparationDistanceCalculator()
51+
{
52+
burningCondition_ = BurningCondition::Low;
53+
slopeClass_ = SlopeClass::Flat;
54+
speedClass_ = SpeedClass::Light;
55+
vegetationHeight_ = 0.0;
56+
safeSeparationDistance_ = 0.0;
57+
safetyZoneSize_ = 0.0;
58+
}
59+
60+
SafeSeparationDistanceCalculator::~SafeSeparationDistanceCalculator() {
61+
}
62+
63+
SafeSeparationDistanceCalculator::SafeSeparationDistanceCalculator(const SafeSeparationDistanceCalculator& rhs)
64+
{
65+
memberwiseCopyAssignment(rhs);
66+
}
67+
68+
SafeSeparationDistanceCalculator& SafeSeparationDistanceCalculator::operator=(const SafeSeparationDistanceCalculator& rhs)
69+
{
70+
if (this != &rhs)
71+
{
72+
memberwiseCopyAssignment(rhs);
73+
}
74+
return *this;
75+
}
76+
77+
// Calculate
78+
79+
void SafeSeparationDistanceCalculator::calculate() {
80+
double vegetationHeight = LengthUnits::fromBaseUnits(vegetationHeight_, LengthUnits::Feet);
81+
82+
double delta = SafeSeparationDistanceCalculator::getValue(speedClass_, burningCondition_, slopeClass_);
83+
84+
// Perform calculation using delta
85+
double safeSeparationDistance = 8.0 * vegetationHeight * delta;
86+
double safetyZoneSize = M_PI * pow(safeSeparationDistance, 2.0);
87+
88+
safeSeparationDistance_ = LengthUnits::toBaseUnits(safeSeparationDistance, LengthUnits::Feet);
89+
safetyZoneSize_ = AreaUnits::toBaseUnits(safetyZoneSize, AreaUnits::Acres);
90+
}
91+
92+
// Getters
93+
BurningCondition::BurningConditionEnum SafeSeparationDistanceCalculator::getBurningCondition() {
94+
return burningCondition_;
95+
}
96+
97+
SlopeClass::SlopeClassEnum SafeSeparationDistanceCalculator::getSlopeClass() {
98+
return slopeClass_;
99+
}
100+
101+
SpeedClass::SpeedClassEnum SafeSeparationDistanceCalculator::getSpeedClass() {
102+
return speedClass_;
103+
}
104+
105+
SafetyCondition::SafetyConditionEnum SafeSeparationDistanceCalculator::getSafetyCondition() {
106+
if (slopeClass_ == SlopeClass::Flat) {
107+
if (speedClass_ == SpeedClass::High) {
108+
return SafetyCondition::Moderate;
109+
} else {
110+
return SafetyCondition::Low;
111+
}
112+
} else if (slopeClass_ == SlopeClass::Moderate) {
113+
if (speedClass_ == SpeedClass::Light) {
114+
return SafetyCondition::Low;
115+
} else if (speedClass_ == SpeedClass::Moderate) {
116+
return SafetyCondition::Moderate;
117+
} else {
118+
return SafetyCondition::Extreme;
119+
}
120+
} else /* Steep Slope */ {
121+
if (speedClass_ == SpeedClass::Light) {
122+
if (burningCondition_ == BurningCondition::Extreme) {
123+
return SafetyCondition::Moderate;
124+
} else {
125+
return SafetyCondition::Low;
126+
}
127+
} else if (speedClass_ == SpeedClass::Moderate) {
128+
return SafetyCondition::Moderate;
129+
} else {
130+
return SafetyCondition::Extreme;
131+
}
132+
}
133+
}
134+
135+
double SafeSeparationDistanceCalculator::getVegetationHeight(LengthUnits::LengthUnitsEnum lengthUnits) {
136+
return LengthUnits::fromBaseUnits(vegetationHeight_, lengthUnits);
137+
}
138+
139+
double SafeSeparationDistanceCalculator::getSafeSeparationDistance(LengthUnits::LengthUnitsEnum lengthUnits) {
140+
return LengthUnits::fromBaseUnits(safeSeparationDistance_, lengthUnits);
141+
}
142+
143+
double SafeSeparationDistanceCalculator::getSafetyZoneSize(AreaUnits::AreaUnitsEnum areaUnits) {
144+
return AreaUnits::fromBaseUnits(safetyZoneSize_, areaUnits);
145+
}
146+
147+
// Setters
148+
void SafeSeparationDistanceCalculator::setBurningCondition(BurningCondition::BurningConditionEnum condition) {
149+
burningCondition_ = condition;
150+
}
151+
152+
void SafeSeparationDistanceCalculator::setSlopeClass(SlopeClass::SlopeClassEnum slope) {
153+
slopeClass_ = slope;
154+
}
155+
156+
void SafeSeparationDistanceCalculator::setSpeedClass(SpeedClass::SpeedClassEnum speed) {
157+
speedClass_ = speed;
158+
}
159+
160+
void SafeSeparationDistanceCalculator::setVegetationHeight(double vegetationHeight, LengthUnits::LengthUnitsEnum lengthUnits) {
161+
vegetationHeight_ = LengthUnits::toBaseUnits(vegetationHeight, lengthUnits);
162+
}
163+
164+
void SafeSeparationDistanceCalculator::memberwiseCopyAssignment(const SafeSeparationDistanceCalculator& rhs)
165+
{
166+
burningCondition_ = rhs.burningCondition_;
167+
slopeClass_ = rhs.slopeClass_;
168+
speedClass_ = rhs.speedClass_;
169+
vegetationHeight_ = rhs.vegetationHeight_;
170+
safeSeparationDistance_ = rhs.safeSeparationDistance_;
171+
safetyZoneSize_ = rhs.safetyZoneSize_;
172+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#pragma once
2+
#include <math.h>
3+
#include <unordered_map>
4+
#include <tuple>
5+
#include "behaveUnits.h"
6+
7+
struct BurningCondition {
8+
enum BurningConditionEnum {
9+
Low,
10+
Moderate,
11+
Extreme
12+
};
13+
};
14+
15+
struct SlopeClass {
16+
enum SlopeClassEnum {
17+
Flat,
18+
Moderate,
19+
Steep
20+
};
21+
};
22+
23+
struct SpeedClass {
24+
enum SpeedClassEnum {
25+
Light,
26+
Moderate,
27+
High
28+
};
29+
};
30+
31+
struct SafetyCondition {
32+
enum SafetyConditionEnum {
33+
Low,
34+
Moderate,
35+
Extreme
36+
};
37+
};
38+
39+
struct TupleHash {
40+
template <typename T1, typename T2, typename T3>
41+
std::size_t operator()(const std::tuple<T1, T2, T3>& t) const {
42+
auto hash1 = std::hash<T1>{}(std::get<0>(t));
43+
auto hash2 = std::hash<T2>{}(std::get<1>(t));
44+
auto hash3 = std::hash<T3>{}(std::get<2>(t));
45+
return hash1 ^ (hash2 << 1) ^ (hash3 << 2); // Combine the hash values
46+
}
47+
};
48+
49+
class SafeSeparationDistanceCalculator {
50+
public:
51+
SafeSeparationDistanceCalculator();
52+
~SafeSeparationDistanceCalculator();
53+
SafeSeparationDistanceCalculator(const SafeSeparationDistanceCalculator& rhs);
54+
SafeSeparationDistanceCalculator& operator=(const SafeSeparationDistanceCalculator& rhs);
55+
56+
// calculate
57+
void calculate();
58+
59+
// Getters
60+
BurningCondition::BurningConditionEnum getBurningCondition();
61+
SlopeClass::SlopeClassEnum getSlopeClass();
62+
SpeedClass::SpeedClassEnum getSpeedClass();
63+
SafetyCondition::SafetyConditionEnum getSafetyCondition();
64+
double getVegetationHeight(LengthUnits::LengthUnitsEnum lengthUnits);
65+
double getSafeSeparationDistance(LengthUnits::LengthUnitsEnum lengthUnits);
66+
double getSafetyZoneSize(AreaUnits::AreaUnitsEnum areaUnits);
67+
68+
// Setters
69+
void setBurningCondition(BurningCondition::BurningConditionEnum condition);
70+
void setSlopeClass(SlopeClass::SlopeClassEnum slope);
71+
void setSpeedClass(SpeedClass::SpeedClassEnum speed);
72+
void setVegetationHeight(double height, LengthUnits::LengthUnitsEnum lengthUnits);
73+
74+
protected:
75+
void memberwiseCopyAssignment(const SafeSeparationDistanceCalculator& rhs);
76+
static double getValue(SpeedClass::SpeedClassEnum speed, BurningCondition::BurningConditionEnum burning, SlopeClass::SlopeClassEnum slope) {
77+
auto key = std::make_tuple(speed, burning, slope);
78+
auto it = deltaLookup.find(key);
79+
if (it != deltaLookup.end()) {
80+
return it->second;
81+
}
82+
return 0.0;
83+
}
84+
85+
BurningCondition::BurningConditionEnum burningCondition_;
86+
SlopeClass::SlopeClassEnum slopeClass_;
87+
SpeedClass::SpeedClassEnum speedClass_;
88+
double vegetationHeight_;
89+
double safeSeparationDistance_;
90+
double safetyZoneSize_;
91+
92+
static const std::unordered_map<std::tuple<SpeedClass::SpeedClassEnum, BurningCondition::BurningConditionEnum, SlopeClass::SlopeClassEnum>, double, TupleHash> deltaLookup;
93+
};

0 commit comments

Comments
 (0)