diff --git a/src/fuel_rod.cpp b/src/fuel_rod.cpp index b1ed5be..07b1320 100644 --- a/src/fuel_rod.cpp +++ b/src/fuel_rod.cpp @@ -22,6 +22,11 @@ void fuel_rod::update(double secs) temperature += fuel.extract_energy() / fuel.get_mass(); } +void fuel_rod::add_neutrons(double amount) +{ + fuel.add_slow_neutrons(amount); +} + double fuel_rod::extract_free_neutrons() { double v = neutrons_free; @@ -50,7 +55,7 @@ void fuel_rod::display(std::ostream& o) const { o << "Temperature: " << temperature << "\n"; o << "Reactivity: " << reactivity << "\n"; + o << "Fuel: " << fuel.get_fuel() << " / " << fuel.get_mass() << "\n"; o << "Neutrons:\n Absorbed: " << neutrons_absorbed << "\n Free: " << neutrons_free << "\n"; - o << fuel; } diff --git a/src/fuel_rod.hpp b/src/fuel_rod.hpp index e70ecf6..8e6055b 100644 --- a/src/fuel_rod.hpp +++ b/src/fuel_rod.hpp @@ -24,6 +24,7 @@ public: void update(double secs); void set_reactivity(double amount); + void add_neutrons(double amount); void add_heat(double amount); constexpr double get_temperature() const { return temperature; } diff --git a/src/main.cpp b/src/main.cpp index 0c49a35..d50bbf3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,66 @@ #include "reactor.hpp" -#include - +#include #include +#include + +void draw_text(int x, int y, const char* str) +{ + for(int i = 0;; i++) + { + const char* start = str; + char c = (str++)[0]; + + while(c != '\n' && c != '\0') + { + c = (str++)[0]; + } + + mvaddnstr(x + i, y, start, (size_t)(str - start)); + + if(c == '\0') return; + } +} + +void draw_box(int x, int y, int h, int w) +{ + mvaddch(x, y, '+'); + + for(int i = 0; i < w - 2; i++) + { + addch('-'); + } + + addch('+'); + + for(int i = 0; i < h - 2; i++) + { + mvaddch(x + i + 1, y, '|'); + mvaddch(x + i + 1, y + w - 1, '|'); + } + + mvaddch(x + h - 1, y, '+'); + + for(int i = 0; i < w - 2; i++) + { + addch('-'); + } + + addch('+'); +} int main() { + initscr(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + curs_set(0); + sim::reactor reactor(5, {100, 200}); -// react.set_reactivity(0); - for(;;) { for(int i = 0; i < 1e3; i++) @@ -18,7 +68,26 @@ int main() reactor.update(1e-3); } - std::cout << "\n\nShow:\n\n" << reactor << "\n"; + erase(); + draw_text(1, 0, "Reactor Core:"); + + const int X = 3, Y = 4; + const int W = 32, H = 8; + + for(int x = 0; x < reactor.get_size(); x++) + for(int y = 0; y < reactor.get_size(); y++) + { + std::stringstream ss; + reactor.display(ss, x, y); + + int px = X + (H - 1) * y; + int py = Y + (W - 1) * x; + + draw_text(px + 1, py + 2, ss.str().c_str()); + draw_box(px, py, H, W); + } + + refresh(); } return 0; diff --git a/src/reactor.cpp b/src/reactor.cpp index defff28..ad28291 100644 --- a/src/reactor.cpp +++ b/src/reactor.cpp @@ -2,59 +2,46 @@ #include "reactor.hpp" #include +#include using namespace sim; reactor::reactor(int size, fuel_rod fr) { this->size = size; + rods.resize(size * size, fr); - for(int y = 0; y < size; y++) - for(int x = 0; x < size; x++) - { - rods.push_back({fr, x, y}); - } + rods[2].set_reactivity(1); } -static const double HEAT_K = 1.0/2.0; +static const double HEAT_K = 1.0/64.0; void reactor::update(double secs) { - update_count++; - - static const int C[8][2] = { - {0, -1}, - {0, 1}, - {-1, 0}, - {1, 0}, - {0, -1}, - {0, 1}, - {-1, 0}, - {1, 0} - }; - - const int C_OFF = update_count % 4; - double heat_add[rods.size()] = {0}; - - for(rod_t& r : rods) + for(int y = 0; y < size; y++) + for(int x = 0; x < size; x++) { - r.fr.update(secs); + fuel_rod& fr = rods[get_id(x, y)]; + fr.update(secs); - for(int i = 0; i < 4; i++) + const int id_os[] = { + get_id(x - 1, y), + get_id(x, y - 1), + get_id(x + 1, y), + get_id(x, y + 1) + }; + + const double neutrons = fr.extract_free_neutrons(); + + for(const int id_o : id_os) { - const auto [cx, cy] = C[C_OFF + i]; - int id_o = get_id(r.x + cx, r.y + cy); - if(id_o == -1) continue; - rod_t& r_o = rods[id_o]; - heat_add[id_o] += r.fr.extract_heat(HEAT_K, r_o.fr.get_temperature()); - } - } - for(int i = 0; i < rods.size(); i++) - { - rods[i].fr.add_heat(heat_add[i]); + fuel_rod& fr_o = rods[id_o]; + fr_o.add_heat(fr.extract_heat(HEAT_K * secs, fr_o.get_temperature())); + fr_o.add_neutrons(neutrons / 4); + } } } @@ -64,22 +51,8 @@ int reactor::get_id(int x, int y) const return y * size + x; } -void reactor::display(std::ostream& o) const +void reactor::display(std::ostream& o, int x, int y) const { - for(int y = -1; y <= size; y++) - { - for(int x = -1; x <= size; x++) - { - int id = get_id(x, y); - - o << "\t"; - - if(id == -1) continue; - - o << rods[id].fr.get_temperature(); - } - - o << "\n"; - } + o << rods[get_id(x, y)]; } diff --git a/src/reactor.hpp b/src/reactor.hpp index a1998e6..3fa7673 100644 --- a/src/reactor.hpp +++ b/src/reactor.hpp @@ -10,33 +10,21 @@ namespace sim class reactor { - struct rod_t - { - fuel_rod fr; - int x, y; - - rod_t(fuel_rod fr, int x, int y) : fr(fr) {} - }; - - std::vector rods; + std::vector rods; int size; long update_count = 0; int get_id(int x, int y) const; - void display(std::ostream& o) const; public: reactor(int radius, fuel_rod fr); void update(double secs); + void display(std::ostream& o, int x, int y) const; - friend std::ostream& operator<<(std::ostream& o, reactor& r) - { - r.display(o); - return o; - } + constexpr int get_size() const { return size; } }; } diff --git a/src/sample.cpp b/src/sample.cpp index 52e32a0..3757651 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -38,24 +38,27 @@ void sample::update(double secs) // absorb neutrons double volume = get_volume(); - double neutrons = (slow_neutrons + NEUTRON_BG * secs) * (fuel / volume); + double neutrons = slow_neutrons + NEUTRON_BG * secs; + double neutrons_fuel = neutrons * (fuel / volume); + double neutrons_iodine = neutrons * (i_135 / volume); + double neutrons_xenon = neutrons * ((xe_135 * Xe_135_M) / volume); slow_neutrons = 0; - // deal with this edge case - if(neutrons > fuel) - { - slow_neutrons = neutrons - fuel; - neutrons = fuel; - } + // deal with these edge cases + if(neutrons_fuel > fuel) neutrons_fuel = fuel; + if(neutrons_xenon > xe_135) neutrons_xenon = xe_135; + if(neutrons_iodine > i_135) neutrons_iodine = i_135; // simulate fuel use - fuel -= neutrons; - energy += neutrons; - fast_neutrons += neutrons * 3; - waste.add_fissile(neutrons * 2); + fuel -= neutrons_fuel; + energy += neutrons_fuel; + fast_neutrons += neutrons_fuel * 3; + waste.add_fissile(neutrons_fuel * 2); - // add the poison - te_135 += neutrons; + // do the poison + te_135 += neutrons_fuel * (1.0 / 8.0); + xe_135 -= neutrons_xenon; + i_135 -= neutrons_iodine; } double sample::get_volume() const @@ -63,11 +66,6 @@ double sample::get_volume() const return mass + xe_135 * Xe_135_M; } -double sample::get_mass() const -{ - return mass; -} - double sample::extract_energy() { double v = energy; diff --git a/src/sample.hpp b/src/sample.hpp index e97d2b5..3a190e4 100644 --- a/src/sample.hpp +++ b/src/sample.hpp @@ -33,8 +33,10 @@ public: double extract_fast_neutrons(); void add_slow_neutrons(double a); + constexpr double get_fuel() const { return fuel; } + constexpr double get_mass() const { return mass; } + double get_volume() const; - double get_mass() const; friend std::ostream& operator<<(std::ostream& o, const sample& s) {