reactor display

This commit is contained in:
Jay Robson 2024-01-13 21:54:21 +11:00
parent 44acbf1c58
commit f026f2f2d4
7 changed files with 127 additions and 91 deletions

View File

@ -22,6 +22,11 @@ void fuel_rod::update(double secs)
temperature += fuel.extract_energy() / fuel.get_mass(); 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 fuel_rod::extract_free_neutrons()
{ {
double v = neutrons_free; double v = neutrons_free;
@ -50,7 +55,7 @@ void fuel_rod::display(std::ostream& o) const
{ {
o << "Temperature: " << temperature << "\n"; o << "Temperature: " << temperature << "\n";
o << "Reactivity: " << reactivity << "\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 << "Neutrons:\n Absorbed: " << neutrons_absorbed << "\n Free: " << neutrons_free << "\n";
o << fuel;
} }

View File

@ -24,6 +24,7 @@ public:
void update(double secs); void update(double secs);
void set_reactivity(double amount); void set_reactivity(double amount);
void add_neutrons(double amount);
void add_heat(double amount); void add_heat(double amount);
constexpr double get_temperature() const { return temperature; } constexpr double get_temperature() const { return temperature; }

View File

@ -1,15 +1,65 @@
#include "reactor.hpp" #include "reactor.hpp"
#include <iostream> #include <sstream>
#include <unistd.h> #include <unistd.h>
#include <curses.h>
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() int main()
{ {
sim::reactor reactor(5, {100, 200}); initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
curs_set(0);
// react.set_reactivity(0); sim::reactor reactor(5, {100, 200});
for(;;) for(;;)
{ {
@ -18,7 +68,26 @@ int main()
reactor.update(1e-3); 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; return 0;

View File

@ -2,59 +2,46 @@
#include "reactor.hpp" #include "reactor.hpp"
#include <iostream> #include <iostream>
#include <iomanip>
using namespace sim; using namespace sim;
reactor::reactor(int size, fuel_rod fr) reactor::reactor(int size, fuel_rod fr)
{ {
this->size = size; this->size = size;
rods.resize(size * size, fr);
for(int y = 0; y < size; y++) rods[2].set_reactivity(1);
for(int x = 0; x < size; x++)
{
rods.push_back({fr, x, y});
}
} }
static const double HEAT_K = 1.0/2.0; static const double HEAT_K = 1.0/64.0;
void reactor::update(double secs) void reactor::update(double secs)
{ {
update_count++; for(int y = 0; y < size; y++)
for(int x = 0; x < size; x++)
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)
{ {
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; 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++) fuel_rod& fr_o = rods[id_o];
{ fr_o.add_heat(fr.extract_heat(HEAT_K * secs, fr_o.get_temperature()));
rods[i].fr.add_heat(heat_add[i]); fr_o.add_neutrons(neutrons / 4);
}
} }
} }
@ -64,22 +51,8 @@ int reactor::get_id(int x, int y) const
return y * size + x; 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++) o << rods[get_id(x, 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";
}
} }

View File

@ -10,33 +10,21 @@ namespace sim
class reactor class reactor
{ {
struct rod_t std::vector<fuel_rod> rods;
{
fuel_rod fr;
int x, y;
rod_t(fuel_rod fr, int x, int y) : fr(fr) {}
};
std::vector<rod_t> rods;
int size; int size;
long update_count = 0; long update_count = 0;
int get_id(int x, int y) const; int get_id(int x, int y) const;
void display(std::ostream& o) const;
public: public:
reactor(int radius, fuel_rod fr); reactor(int radius, fuel_rod fr);
void update(double secs); void update(double secs);
void display(std::ostream& o, int x, int y) const;
friend std::ostream& operator<<(std::ostream& o, reactor& r) constexpr int get_size() const { return size; }
{
r.display(o);
return o;
}
}; };
} }

View File

@ -38,24 +38,27 @@ void sample::update(double secs)
// absorb neutrons // absorb neutrons
double volume = get_volume(); 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; slow_neutrons = 0;
// deal with this edge case // deal with these edge cases
if(neutrons > fuel) if(neutrons_fuel > fuel) neutrons_fuel = fuel;
{ if(neutrons_xenon > xe_135) neutrons_xenon = xe_135;
slow_neutrons = neutrons - fuel; if(neutrons_iodine > i_135) neutrons_iodine = i_135;
neutrons = fuel;
}
// simulate fuel use // simulate fuel use
fuel -= neutrons; fuel -= neutrons_fuel;
energy += neutrons; energy += neutrons_fuel;
fast_neutrons += neutrons * 3; fast_neutrons += neutrons_fuel * 3;
waste.add_fissile(neutrons * 2); waste.add_fissile(neutrons_fuel * 2);
// add the poison // do the poison
te_135 += neutrons; te_135 += neutrons_fuel * (1.0 / 8.0);
xe_135 -= neutrons_xenon;
i_135 -= neutrons_iodine;
} }
double sample::get_volume() const double sample::get_volume() const
@ -63,11 +66,6 @@ double sample::get_volume() const
return mass + xe_135 * Xe_135_M; return mass + xe_135 * Xe_135_M;
} }
double sample::get_mass() const
{
return mass;
}
double sample::extract_energy() double sample::extract_energy()
{ {
double v = energy; double v = energy;

View File

@ -33,8 +33,10 @@ public:
double extract_fast_neutrons(); double extract_fast_neutrons();
void add_slow_neutrons(double a); 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_volume() const;
double get_mass() const;
friend std::ostream& operator<<(std::ostream& o, const sample& s) friend std::ostream& operator<<(std::ostream& o, const sample& s)
{ {