This commit is contained in:
Jay Robson 2024-02-20 18:02:34 +11:00
parent 43db2f812f
commit 105681fd2a
15 changed files with 278 additions and 225 deletions

View File

@ -6,8 +6,8 @@
using namespace Sim::Coolant; using namespace Sim::Coolant;
CondenserSecondary::CondenserSecondary(Condenser* primary, Evaporator* source, double volume) : CondenserSecondary::CondenserSecondary(Condenser* primary, Evaporator* source) :
primary(primary), source(source), FluidHolder(primary->fluid, volume, 0) primary(primary), source(source), FluidHolder(primary->fluid, 1, 0)
{ {
} }

View File

@ -15,7 +15,7 @@ class CondenserSecondary : public FluidHolder
public: public:
CondenserSecondary(Condenser* primary, Evaporator* source, double volume); CondenserSecondary(Condenser* primary, Evaporator* source);
virtual double add_heat(double m, double t) { return source->add_heat(m, t); } virtual double add_heat(double m, double t) { return source->add_heat(m, t); }
virtual double extract_fluid(double amount) { return source->extract_fluid(amount); } virtual double extract_fluid(double amount) { return source->extract_fluid(amount); }

60
src/coolant/loop.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "loop.hpp"
using namespace Sim::Coolant;
Loop::Loop(Reactor::Coolant::Vessel* vessel, Evaporator* evaporator, Electric::Grid* grid) :
condenser(WATER, 6, 4, 3e6, 30000),
turbine(&condenser),
generator(&turbine, grid, 6, 3, 2e6),
condenser_secondary(&condenser, evaporator),
turbine_inlet_valve(vessel, &turbine, 0, 0.5),
turbine_bypass_valve(vessel, &condenser, 0, 0.5),
primary_pump(&condenser, vessel, 1e5, 1, 1e5, 0.1, 10, Pump::mode_t::SRC, 35000),
secondary_pump(evaporator, &condenser_secondary, 1e5, 1, 1e4, 0.1, 1, Pump::mode_t::NONE, 0)
{
}
Loop::Loop(const Json::Value& node, Reactor::Coolant::Vessel* vessel, Evaporator* evaporator, Electric::Grid* grid) :
condenser(node["condenser"]),
turbine(&condenser),
generator(node["generator"], &turbine, grid),
condenser_secondary(&condenser, evaporator),
turbine_inlet_valve(node["valve"]["inlet"], vessel, &turbine),
turbine_bypass_valve(node["valve"]["bypass"], vessel, &condenser),
primary_pump(node["pump"]["primary"], &condenser, vessel),
secondary_pump(node["pump"]["secondary"], evaporator, &condenser_secondary)
{
}
void Loop::update(double dt)
{
turbine_inlet_valve.update(dt);
turbine_bypass_valve.update(dt);
condenser.update(dt);
turbine.update(dt);
generator.update(dt);
primary_pump.update(dt);
secondary_pump.update(dt);
condenser_secondary.update(dt);
}
Loop::operator Json::Value() const
{
Json::Value node;
node["generator"] = generator;
node["condenser"] = condenser;
node["pump"]["primary"] = primary_pump;
node["pump"]["secondary"] = secondary_pump;
node["valve"]["inlet"] = turbine_inlet_valve;
node["valve"]["bypass"] = turbine_bypass_valve;
return node;
}

45
src/coolant/loop.hpp Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#include "pump.hpp"
#include "valve.hpp"
#include "condenser.hpp"
#include "condenser_secondary.hpp"
#include "evaporator.hpp"
#include "sink.hpp"
#include "fluid.hpp"
#include "../reactor/coolant/vessel.hpp"
#include "../electric/turbine.hpp"
#include "../electric/generator.hpp"
#include "../electric/grid.hpp"
#include <json/json.h>
namespace Sim::Coolant
{
class Loop
{
public:
Coolant::Condenser condenser;
Coolant::CondenserSecondary condenser_secondary;
Electric::Turbine turbine;
Electric::Generator generator;
Coolant::Pump primary_pump;
Coolant::Pump secondary_pump;
Coolant::Valve turbine_bypass_valve;
Coolant::Valve turbine_inlet_valve;
Loop(Reactor::Coolant::Vessel* vessel, Evaporator* evaporator, Electric::Grid* grid);
Loop(const Json::Value& node, Reactor::Coolant::Vessel* vessel, Evaporator* evaporator, Electric::Grid* grid);
Loop(const Loop& o) = delete;
Loop(Loop&& o) = delete;
operator Json::Value() const;
void update(double dt);
};
};

View File

@ -29,19 +29,19 @@ static void cb_keypress(GLFWwindow* win, int key, int sc, int action, int mods)
switch(key) switch(key)
{ {
case GLFW_KEY_1: case GLFW_KEY_1:
Sim::System::active.speed = 1; // 1 s/s Sim::System::active->speed = 1; // 1 s/s
break; break;
case GLFW_KEY_2: case GLFW_KEY_2:
Sim::System::active.speed = 10; // 10 s/s Sim::System::active->speed = 10; // 10 s/s
break; break;
case GLFW_KEY_3: case GLFW_KEY_3:
Sim::System::active.speed = 60; // 1 min/s Sim::System::active->speed = 60; // 1 min/s
break; break;
case GLFW_KEY_4: case GLFW_KEY_4:
Sim::System::active.speed = 600; // 10 min/s Sim::System::active->speed = 600; // 10 min/s
break; break;
case GLFW_KEY_5: case GLFW_KEY_5:
Sim::System::active.speed = 3600; // 1 h/s Sim::System::active->speed = 3600; // 1 h/s
break; break;
case GLFW_KEY_O: case GLFW_KEY_O:
Sim::System::save(); Sim::System::save();

View File

@ -15,15 +15,16 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
using namespace Sim;
using namespace Sim::Graphics; using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor; using namespace Sim::Graphics::Monitor;
using namespace Sim::Util::Streams; using namespace Sim::Util::Streams;
static void set_all(bool state) static void set_all(bool state)
{ {
for(int i = 0; i < Sim::System::active.reactor->rods.size(); i++) for(int i = 0; i < System::active->reactor.rods.size(); i++)
{ {
Sim::Reactor::Rod* r = Sim::System::active.reactor->rods[i].get(); Reactor::Rod* r = System::active->reactor.rods[i].get();
if(r->should_select()) if(r->should_select())
{ {
@ -48,7 +49,7 @@ struct CoreMonitor : public Focus::FocusType
return; return;
} }
Sim::System& sys = Sim::System::active; Sim::System& sys = *System::active;
switch(key) switch(key)
{ {
@ -56,25 +57,25 @@ struct CoreMonitor : public Focus::FocusType
set_all(true); set_all(true);
break; break;
case GLFW_KEY_KP_8: case GLFW_KEY_KP_8:
sys.reactor->move_cursor(-sys.reactor->height); sys.reactor.move_cursor(-sys.reactor.height);
break; break;
case GLFW_KEY_KP_9: case GLFW_KEY_KP_9:
set_all(false); set_all(false);
break; break;
case GLFW_KEY_KP_4: case GLFW_KEY_KP_4:
sys.reactor->move_cursor(-1); sys.reactor.move_cursor(-1);
break; break;
case GLFW_KEY_KP_5: case GLFW_KEY_KP_5:
sys.reactor->toggle_selected(); sys.reactor.toggle_selected();
break; break;
case GLFW_KEY_KP_6: case GLFW_KEY_KP_6:
sys.reactor->move_cursor(1); sys.reactor.move_cursor(1);
break; break;
case GLFW_KEY_KP_1: case GLFW_KEY_KP_1:
sys.reactor->reset_rod_speed(); sys.reactor.reset_rod_speed();
break; break;
case GLFW_KEY_KP_2: case GLFW_KEY_KP_2:
sys.reactor->move_cursor(sys.reactor->height); sys.reactor.move_cursor(sys.reactor.height);
break; break;
default: default:
return; return;
@ -95,13 +96,13 @@ struct CoreJoystick : public Focus::FocusType
virtual void on_cursor_pos(double x, double y) virtual void on_cursor_pos(double x, double y)
{ {
Sim::System::active.reactor->add_rod_speed(y * 1e-6); System::active->reactor.add_rod_speed(y * 1e-6);
parent->is_dirty = true; parent->is_dirty = true;
} }
virtual ~CoreJoystick() virtual ~CoreJoystick()
{ {
Sim::System::active.reactor->reset_rod_speed(); System::active->reactor.reset_rod_speed();
} }
virtual void on_mouse_button(int button, int action, int mods) virtual void on_mouse_button(int button, int action, int mods)
@ -165,7 +166,7 @@ static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
void Core::update(double dt) void Core::update(double dt)
{ {
Sim::System& sys = Sim::System::active; Sim::System& sys = *System::active;
if(m_monitor.check_focus()) { if(m_monitor.check_focus()) {
Focus::set(std::make_unique<CoreMonitor>(this)); Focus::set(std::make_unique<CoreMonitor>(this));
@ -174,7 +175,7 @@ void Core::update(double dt)
Focus::set(std::make_unique<CoreJoystick>(this)); Focus::set(std::make_unique<CoreJoystick>(this));
} }
if(m_scram.check_focus()) { if(m_scram.check_focus()) {
sys.reactor->scram(); sys.reactor.scram();
is_dirty = true; is_dirty = true;
} }
if(m_buttons[0].check_focus()) { if(m_buttons[0].check_focus()) {
@ -182,7 +183,7 @@ void Core::update(double dt)
is_dirty = true; is_dirty = true;
} }
if(m_buttons[1].check_focus()) { if(m_buttons[1].check_focus()) {
sys.reactor->move_cursor(-sys.reactor->height); sys.reactor.move_cursor(-sys.reactor.height);
is_dirty = true; is_dirty = true;
} }
if(m_buttons[2].check_focus()) { if(m_buttons[2].check_focus()) {
@ -190,23 +191,23 @@ void Core::update(double dt)
is_dirty = true; is_dirty = true;
} }
if(m_buttons[3].check_focus()) { if(m_buttons[3].check_focus()) {
sys.reactor->move_cursor(-1); sys.reactor.move_cursor(-1);
is_dirty = true; is_dirty = true;
} }
if(m_buttons[4].check_focus()) { if(m_buttons[4].check_focus()) {
sys.reactor->toggle_selected(); sys.reactor.toggle_selected();
is_dirty = true; is_dirty = true;
} }
if(m_buttons[5].check_focus()) { if(m_buttons[5].check_focus()) {
sys.reactor->move_cursor(1); sys.reactor.move_cursor(1);
is_dirty = true; is_dirty = true;
} }
if(m_buttons[6].check_focus()) { if(m_buttons[6].check_focus()) {
sys.reactor->reset_rod_speed(); sys.reactor.reset_rod_speed();
is_dirty = true; is_dirty = true;
} }
if(m_buttons[7].check_focus()) { if(m_buttons[7].check_focus()) {
sys.reactor->move_cursor(sys.reactor->height); sys.reactor.move_cursor(sys.reactor.height);
is_dirty = true; is_dirty = true;
} }
@ -228,23 +229,23 @@ void Core::update(double dt)
Sim::Graphics::Mesh rmesh; Sim::Graphics::Mesh rmesh;
is_dirty = false; is_dirty = false;
double step = 1 / (sys.vessel->diameter / sys.reactor->cell_width * 0.8); double step = 1 / (sys.vessel.diameter / sys.reactor.cell_width * 0.8);
double sx = 0.5 - (sys.reactor->width - 1) * step / 2.0; double sx = 0.5 - (sys.reactor.width - 1) * step / 2.0;
double sy = 0.5 - (sys.reactor->height - 1) * step / 2.0; double sy = 0.5 - (sys.reactor.height - 1) * step / 2.0;
glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.4, step * 0.4, 1)); glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.4, step * 0.4, 1));
glm::mat4 mat_select = glm::translate(glm::mat4(1), glm::vec3(-0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); glm::mat4 mat_select = glm::translate(glm::mat4(1), glm::vec3(-0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1));
glm::mat4 mat_cursor = glm::translate(glm::mat4(1), glm::vec3(-0.8, 0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); glm::mat4 mat_cursor = glm::translate(glm::mat4(1), glm::vec3(-0.8, 0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1));
glm::mat4 mat_spec = glm::translate(glm::mat4(1), glm::vec3(0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); glm::mat4 mat_spec = glm::translate(glm::mat4(1), glm::vec3(0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1));
for(int i = 0; i < sys.reactor->size; i++) for(int i = 0; i < sys.reactor.size; i++)
{ {
int x = i % sys.reactor->width; int x = i % sys.reactor.width;
int y = i / sys.reactor->width; int y = i / sys.reactor.width;
double ox = sx + x * step; double ox = sx + x * step;
double oy = sy + y * step; double oy = sy + y * step;
Reactor::Rod* r = sys.reactor->rods[i].get(); Reactor::Rod* r = sys.reactor.rods[i].get();
if(!r->should_display()) if(!r->should_display())
{ {
@ -263,7 +264,7 @@ void Core::update(double dt)
rmesh.add(add_dot(mat, colour_heat)); rmesh.add(add_dot(mat, colour_heat));
if(sys.reactor->cursor == i) if(sys.reactor.cursor == i)
{ {
rmesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1})); rmesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1}));
} }

View File

@ -107,7 +107,7 @@ void PrimaryLoop::init()
void PrimaryLoop::update(double dt) void PrimaryLoop::update(double dt)
{ {
System& sys = Sim::System::active; System& sys = *System::active;
clock_now += dt; clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now) if(clock_at + 1.0/30.0 < clock_now)
@ -117,12 +117,12 @@ void PrimaryLoop::update(double dt)
clock_at += 1.0/30.0; clock_at += 1.0/30.0;
ss << "\n\n"; ss << "\n\n";
ss << show( sys.turbine_bypass_valve->get_state() * 100 ) << " %\n"; ss << show( sys.loop.turbine_bypass_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.turbine_bypass_valve->get_flow() ) << "g/s\n"; show_units( ss, sys.loop.turbine_bypass_valve.get_flow() ) << "g/s\n";
if(sys.turbine_bypass_valve->get_auto()) if(sys.loop.turbine_bypass_valve.get_auto())
{ {
ss << show( sys.turbine_bypass_valve->get_setpoint() ) << " C\n"; ss << show( sys.loop.turbine_bypass_valve.get_setpoint() ) << " C\n";
} }
else else
@ -131,12 +131,12 @@ void PrimaryLoop::update(double dt)
} }
ss << "\n\n\n"; ss << "\n\n\n";
ss << show( sys.turbine_inlet_valve->get_state() * 100 ) << " %\n"; ss << show( sys.loop.turbine_inlet_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.turbine_inlet_valve->get_flow() ) << "g/s\n"; show_units( ss, sys.loop.turbine_inlet_valve.get_flow() ) << "g/s\n";
if(sys.turbine_inlet_valve->get_auto()) if(sys.loop.turbine_inlet_valve.get_auto())
{ {
ss << show( sys.turbine_inlet_valve->get_setpoint() ) << " C\n"; ss << show( sys.loop.turbine_inlet_valve.get_setpoint() ) << " C\n";
} }
else else
@ -145,14 +145,14 @@ void PrimaryLoop::update(double dt)
} }
ss << "\n\n\n"; ss << "\n\n\n";
ss << show( sys.primary_pump->get_power() * 100 ) << " %\n"; ss << show( sys.loop.primary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.primary_pump->get_rpm() ) << " r/min\n"; ss << show( sys.loop.primary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.primary_pump->get_flow_mass() ) << "g/s\n"; show_units( ss, sys.loop.primary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n"; ss << "\n\n\n";
ss << show( sys.condenser->get_heat() ) << " C\n"; ss << show( sys.loop.condenser.get_heat() ) << " C\n";
show_units( ss, sys.condenser->get_steam() ) << "g\n"; show_units( ss, sys.loop.condenser.get_steam() ) << "g\n";
show_units( ss, sys.condenser->get_pressure() ) << "Pa\n"; show_units( ss, sys.loop.condenser.get_pressure() ) << "Pa\n";
ss << show( sys.condenser->get_level() / 1000 ) << " / " << show( sys.condenser->get_volume() / 1000 ) << " kL\n"; ss << show( sys.loop.condenser.get_level() / 1000 ) << " / " << show( sys.loop.condenser.get_volume() / 1000 ) << " kL\n";
rmesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
mesh2.bind(); mesh2.bind();
@ -160,19 +160,19 @@ void PrimaryLoop::update(double dt)
} }
if(m_joystick_turbine_bypass.check_focus()) if(m_joystick_turbine_bypass.check_focus())
Focus::set(std::make_unique<ValveJoystick>(sys.turbine_bypass_valve.get())); Focus::set(std::make_unique<ValveJoystick>(&sys.loop.turbine_bypass_valve));
if(m_joystick_turbine_inlet.check_focus()) if(m_joystick_turbine_inlet.check_focus())
Focus::set(std::make_unique<ValveJoystick>(sys.turbine_inlet_valve.get())); Focus::set(std::make_unique<ValveJoystick>(&sys.loop.turbine_inlet_valve));
if(m_switch_pump.check_focus()) if(m_switch_pump.check_focus())
sys.primary_pump->powered = !sys.primary_pump->powered; sys.loop.primary_pump.powered = !sys.loop.primary_pump.powered;
if(m_switch_inlet.check_focus()) if(m_switch_inlet.check_focus())
sys.turbine_inlet_valve->toggle_auto(); sys.loop.turbine_inlet_valve.toggle_auto();
if(m_switch_bypass.check_focus()) if(m_switch_bypass.check_focus())
sys.turbine_bypass_valve->toggle_auto(); sys.loop.turbine_bypass_valve.toggle_auto();
gm_switch_inlet.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.turbine_inlet_valve->get_auto() ? 0.07 : 0, 0)); gm_switch_inlet.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.turbine_inlet_valve.get_auto() ? 0.07 : 0, 0));
gm_switch_bypass.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.turbine_bypass_valve->get_auto() ? 0.07 : 0, 0)); gm_switch_bypass.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.turbine_bypass_valve.get_auto() ? 0.07 : 0, 0));
gm_switch_pump.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.primary_pump->powered ? 0.07 : 0, 0)); gm_switch_pump.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.primary_pump.powered ? 0.07 : 0, 0));
} }
void PrimaryLoop::render() void PrimaryLoop::render()

View File

@ -63,7 +63,7 @@ void SecondaryLoop::init()
void SecondaryLoop::update(double dt) void SecondaryLoop::update(double dt)
{ {
System& sys = Sim::System::active; System& sys = *System::active;
clock_now += dt; clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now) if(clock_at + 1.0/30.0 < clock_now)
@ -73,18 +73,18 @@ void SecondaryLoop::update(double dt)
clock_at += 1.0/30.0; clock_at += 1.0/30.0;
ss << "\n\n"; ss << "\n\n";
ss << show( sys.evaporator->get_heat() ) << " C\n"; ss << show( sys.evaporator.get_heat() ) << " C\n";
show_units( ss, sys.evaporator->get_steam_output() ) << "g/s\n"; show_units( ss, sys.evaporator.get_steam_output() ) << "g/s\n";
show_units( ss, sys.evaporator->get_pressure() ) << "Pa\n"; show_units( ss, sys.evaporator.get_pressure() ) << "Pa\n";
ss << show( sys.evaporator->get_level() / 1000 ) << " / " << show( sys.evaporator->get_volume() / 1000 ) << " kL\n"; ss << show( sys.evaporator.get_level() / 1000 ) << " / " << show( sys.evaporator.get_volume() / 1000 ) << " kL\n";
ss << "\n\n\n"; ss << "\n\n\n";
ss << show( sys.secondary_pump->get_power() * 100 ) << " %\n"; ss << show( sys.loop.secondary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.secondary_pump->get_rpm() ) << " r/min\n"; ss << show( sys.loop.secondary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.secondary_pump->get_flow_mass() ) << "g/s\n"; show_units( ss, sys.loop.secondary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n"; ss << "\n\n\n";
ss << show( sys.freight_pump->get_power() * 100 ) << " %\n"; ss << show( sys.freight_pump.get_power() * 100 ) << " %\n";
ss << show( sys.freight_pump->get_rpm() ) << " r/min\n"; ss << show( sys.freight_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.freight_pump->get_flow_mass() ) << "g/s\n"; show_units( ss, sys.freight_pump.get_flow_mass() ) << "g/s\n";
rmesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
mesh2.bind(); mesh2.bind();
@ -92,12 +92,12 @@ void SecondaryLoop::update(double dt)
} }
if(m_switch_2.check_focus()) if(m_switch_2.check_focus())
sys.secondary_pump->powered = !sys.secondary_pump->powered; sys.loop.secondary_pump.powered = !sys.loop.secondary_pump.powered;
if(m_switch_3.check_focus()) if(m_switch_3.check_focus())
sys.freight_pump->powered = !sys.freight_pump->powered; sys.freight_pump.powered = !sys.freight_pump.powered;
gm_switch_2.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.secondary_pump->powered ? 0.07 : 0, 0)); gm_switch_2.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.secondary_pump.powered ? 0.07 : 0, 0));
gm_switch_3.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.freight_pump->powered ? 0.07 : 0, 0)); gm_switch_3.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.freight_pump.powered ? 0.07 : 0, 0));
} }
void SecondaryLoop::render() void SecondaryLoop::render()

View File

@ -57,7 +57,7 @@ void Turbine::init()
void Turbine::update(double dt) void Turbine::update(double dt)
{ {
System& sys = Sim::System::active; System& sys = *System::active;
clock_now += dt; clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now) if(clock_at + 1.0/30.0 < clock_now)
@ -67,9 +67,9 @@ void Turbine::update(double dt)
clock_at += 1.0/30.0; clock_at += 1.0/30.0;
ss << "\n\n"; ss << "\n\n";
ss << show( sys.turbine->get_heat() ) << " C\n"; ss << show( sys.loop.turbine.get_heat() ) << " C\n";
ss << show( sys.turbine->get_pressure() / 1000 ) << " kPa\n"; ss << show( sys.loop.turbine.get_pressure() / 1000 ) << " kPa\n";
ss << show( sys.generator->get_rpm() ) << " r/min\n"; ss << show( sys.loop.generator.get_rpm() ) << " r/min\n";
rmesh2.load_text(ss.str().c_str(), 0.04); rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.5, 0, 0))); rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.5, 0, 0)));
@ -77,8 +77,8 @@ void Turbine::update(double dt)
ss = std::stringstream(); ss = std::stringstream();
ss << "Local\n\n"; ss << "Local\n\n";
ss << show( sys.generator->get_rpm() / 60 ) << " Hz\n"; ss << show( sys.loop.generator.get_rpm() / 60 ) << " Hz\n";
Util::Streams::show_units( ss, sys.generator->get_energy_generated() ) << "W\n"; Util::Streams::show_units( ss, sys.loop.generator.get_energy_generated() ) << "W\n";
rmesh2.load_text(ss.str().c_str(), 0.04); rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.4, 0.7, 0))); rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.4, 0.7, 0)));
@ -86,7 +86,7 @@ void Turbine::update(double dt)
ss = std::stringstream(); ss = std::stringstream();
ss << "Grid\n\n"; ss << "Grid\n\n";
ss << show( sys.grid->frequency ) << " Hz\n"; ss << show( sys.grid.frequency ) << " Hz\n";
rmesh2.load_text(ss.str().c_str(), 0.04); rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.7, 0.7, 0))); rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.7, 0.7, 0)));
@ -95,21 +95,21 @@ void Turbine::update(double dt)
mesh2.set(rmesh, GL_DYNAMIC_DRAW); mesh2.set(rmesh, GL_DYNAMIC_DRAW);
} }
double rpm = sys.generator->get_rpm(); double rpm = sys.loop.generator.get_rpm();
if(rpm > 3570 && rpm < 3630) if(rpm > 3570 && rpm < 3630)
{ {
glm::mat4 mat = glm::mat4(1); glm::mat4 mat = glm::mat4(1);
mat = glm::translate(mat, glm::vec3(6.35, 3.949, 1.35)); mat = glm::translate(mat, glm::vec3(6.35, 3.949, 1.35));
mat = glm::rotate(mat, float(sys.generator->get_phase_diff()), glm::vec3(0, 1, 0)); mat = glm::rotate(mat, float(sys.loop.generator.get_phase_diff()), glm::vec3(0, 1, 0));
mat = glm::translate(mat, glm::vec3(-6.35, -3.949, -1.35)); mat = glm::translate(mat, glm::vec3(-6.35, -3.949, -1.35));
gm_synchroscope_dial.model_matrix = mat; gm_synchroscope_dial.model_matrix = mat;
} }
if(m_switch_breaker.check_focus()) if(m_switch_breaker.check_focus())
sys.generator->breaker_closed = !sys.generator->breaker_closed; sys.loop.generator.breaker_closed = !sys.loop.generator.breaker_closed;
gm_switch_breaker.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.generator->breaker_closed ? 0.07 : 0, 0)); gm_switch_breaker.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.generator.breaker_closed ? 0.07 : 0, 0));
} }
void Turbine::render() void Turbine::render()
@ -122,7 +122,7 @@ void Turbine::render()
mesh2.uniform(); mesh2.uniform();
mesh2.render(); mesh2.render();
double rpm = System::active.generator->get_rpm(); double rpm = System::active->loop.generator.get_rpm();
if(rpm > 3570 && rpm < 3630) if(rpm > 3570 && rpm < 3630)
{ {

View File

@ -56,7 +56,7 @@ void Vessel::update(double dt)
{ {
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh rmesh; Sim::Graphics::Mesh rmesh;
Sim::System& sys = Sim::System::active; Sim::System& sys = *System::active;
clock_now += dt; clock_now += dt;
if(clock_at + 1.0/30.0 > clock_now) if(clock_at + 1.0/30.0 > clock_now)
@ -68,11 +68,11 @@ void Vessel::update(double dt)
double crod_min = INFINITY, crod_max = -INFINITY; double crod_min = INFINITY, crod_max = -INFINITY;
clock_at += 1.0/30.0; clock_at += 1.0/30.0;
sys.reactor->get_stats(Sim::Reactor::Rod::val_t::HEAT, temp_min, temp_max); sys.reactor.get_stats(Sim::Reactor::Rod::val_t::HEAT, temp_min, temp_max);
for(int i = 0; i < sys.reactor->size; i++) for(int i = 0; i < sys.reactor.size; i++)
{ {
Sim::Reactor::Rod* r = sys.reactor->rods[i].get(); Sim::Reactor::Rod* r = sys.reactor.rods[i].get();
if(r->get_id() != 5) if(r->get_id() != 5)
{ {
@ -94,20 +94,20 @@ void Vessel::update(double dt)
} }
ss << "\n\n"; ss << "\n\n";
ss << show( sys.vessel->get_heat() ) << " C\n"; ss << show( sys.vessel.get_heat() ) << " C\n";
show_units( ss, sys.vessel->get_steam() ) << "g\n"; show_units( ss, sys.vessel.get_steam() ) << "g\n";
show_units( ss, sys.vessel->get_pressure() ) << "Pa\n"; show_units( ss, sys.vessel.get_pressure() ) << "Pa\n";
ss << show( sys.vessel->get_level() / 1000 ) << " / " << show( sys.vessel->get_volume() / 1000 ) << " kL\n"; ss << show( sys.vessel.get_level() / 1000 ) << " / " << show( sys.vessel.get_volume() / 1000 ) << " kL\n";
ss << show( sys.vessel->get_void_ratio() * 100 ) << " %\n\n\n\n"; ss << show( sys.vessel.get_void_ratio() * 100 ) << " %\n\n\n\n";
show_units( ss, sys.reactor->get_flux() ) << "n/cm2/s\n"; show_units( ss, sys.reactor.get_flux() ) << "n/cm2/s\n";
show_units( ss, sys.reactor->get_energy_output() ) << "W\n\n\n"; show_units( ss, sys.reactor.get_energy_output() ) << "W\n\n\n";
// ss << show( sys.reactor->flux_rate * 100 ) << " %/s\n\n\n"; // ss << show( sys.reactor.flux_rate * 100 ) << " %/s\n\n\n";
ss << show( temp_min ) << " C\n"; ss << show( temp_min ) << " C\n";
ss << show( temp_max ) << " C\n\n\n"; ss << show( temp_max ) << " C\n\n\n";
ss << show( 100 - crod_max * 100 ) << " %\n"; ss << show( 100 - crod_max * 100 ) << " %\n";
ss << show( 100 - crod_min * 100 ) << " %\n"; ss << show( 100 - crod_min * 100 ) << " %\n";
ss << show( sys.reactor->rod_speed * 100, 1e6 ) << " %/s"; ss << show( sys.reactor.rod_speed * 100, 1e6 ) << " %/s";
if(sys.reactor->rod_speed == 0) ss << " (Stopped)"; if(sys.reactor.rod_speed == 0) ss << " (Stopped)";
ss << "\n"; ss << "\n";
rmesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);

View File

@ -21,7 +21,7 @@ using namespace Sim::Graphics::Widget;
void Clock::update(double dt) void Clock::update(double dt)
{ {
Mesh m; Mesh m;
double at = System::active.clock; double at = System::active->clock;
glm::vec2 wsize(Resize::get_size() / 2); glm::vec2 wsize(Resize::get_size() / 2);
std::stringstream ss; std::stringstream ss;

View File

@ -109,7 +109,7 @@ void Window::create()
Shader::init_program(); Shader::init_program();
Sim::System& sys = Sim::System::active; Sim::System& sys = *System::active;
Mesh m, m2; Mesh m, m2;
m.load_model("../assets", "scene-baked.glb"); m.load_model("../assets", "scene-baked.glb");
@ -178,7 +178,7 @@ void Window::render()
glm::mat4 mat_camera = Camera::get_matrix(); glm::mat4 mat_camera = Camera::get_matrix();
mat_camera = glm::scale(mat_camera, {1, 1, -1}); mat_camera = glm::scale(mat_camera, {1, 1, -1});
glm::vec3 brightness = glm::vec3(Sim::System::active.grid->get_light_intensity()); glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity());
glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 20.f); glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 20.f);
glUniformMatrix4fv(Shader::gl_projection, 1, false, &mat_projection[0][0]); glUniformMatrix4fv(Shader::gl_projection, 1, false, &mat_projection[0][0]);
glUniformMatrix4fv(Shader::gl_camera, 1, false, &mat_camera[0][0]); glUniformMatrix4fv(Shader::gl_camera, 1, false, &mat_camera[0][0]);

View File

@ -41,10 +41,10 @@ int main()
long now = Util::Time::get_now(); long now = Util::Time::get_now();
long passed = now - clock; long passed = now - clock;
double dt = (double)passed / 1e6; double dt = (double)passed / 1e6;
clock += passed; clock += passed;
at += dt * Sim::System::active.speed; at += dt * Sim::System::active->speed;
Sim::System::active->update(dt);
Sim::System::active.update(dt);
Graphics::Camera::update(dt); Graphics::Camera::update(dt);
Graphics::Window::update(dt); Graphics::Window::update(dt);

View File

@ -12,74 +12,53 @@
using namespace Sim; using namespace Sim;
Sim::System System::active; std::unique_ptr<Sim::System> System::active = std::make_unique<Sim::System>();
System::System() const char* CORE_LAYOUT[] = {
" C C C C ",
" C CFCFCFCFC C ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" C CFCFCFCFC C ",
" C C C C "
};
System::System() :
vessel(Coolant::WATER, 8, 10, 6e6, 5e5, 10),
reactor(Reactor::Builder(19, 19, 1.0 / 4.0, 4, Reactor::Fuel::FuelRod(0.5), &vessel, CORE_LAYOUT)),
evaporator(Coolant::WATER, 2, 30, 0, 1000),
sink(Coolant::WATER, 11, 0, 0),
grid(),
freight_pump(&sink, &evaporator, 1e5, 1, 1e4, 0.1, 10, Coolant::Pump::mode_t::DST, 1e6),
loop(&vessel, &evaporator, &grid)
{ {
const char* layout[] = {
" C C C C ",
" C CFCFCFCFC C ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
"CFCFCFCFCFCFCFCFCFC",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFCFC ",
" CFCFCFCFCFCFCFC ",
" C CFCFCFCFC C ",
" C C C C "
};
vessel = std::make_unique<Reactor::Coolant::Vessel>(Sim::Coolant::WATER, 8, 10, 6e6, 5e5, 10);
reactor = std::make_unique<Reactor::Reactor>(Sim::Reactor::Builder(19, 19, 1.0 / 4.0, 4, Reactor::Fuel::FuelRod(0.2), vessel.get(), layout));
condenser = std::make_unique<Coolant::Condenser>(Sim::Coolant::WATER, 6, 4, 3e6, 30000);
grid = std::make_unique<Electric::Grid>();
turbine = std::make_unique<Electric::Turbine>(condenser.get());
generator = std::make_unique<Electric::Generator>(turbine.get(), grid.get(), 6, 3, 2e6);
sink = std::make_unique<Coolant::Sink>(Sim::Coolant::WATER, 11, 0, 0);
evaporator = std::make_unique<Coolant::Evaporator>(Sim::Coolant::WATER, 2, 30, 0, 1000);
condenser_secondary = std::make_unique<Coolant::CondenserSecondary>(condenser.get(), evaporator.get(), 1000);
turbine_inlet_valve = std::make_unique<Coolant::Valve>(vessel.get(), turbine.get(), 0, 0.5);
turbine_bypass_valve = std::make_unique<Coolant::Valve>(vessel.get(), condenser.get(), 0, 0.5);
primary_pump = std::make_unique<Coolant::Pump>(condenser.get(), vessel.get(), 1e5, 1, 1e5, 0.1, 10, Coolant::Pump::mode_t::SRC, 35000);
secondary_pump = std::make_unique<Coolant::Pump>(evaporator.get(), condenser_secondary.get(), 1e5, 1, 1e4, 0.1, 1, Coolant::Pump::mode_t::NONE, 0);
freight_pump = std::make_unique<Coolant::Pump>(sink.get(), evaporator.get(), 1e5, 1, 1e4, 0.1, 10, Coolant::Pump::mode_t::DST, 1e6);
} }
System::System(const Json::Value& node) System::System(const Json::Value& node) :
clock(node["clock"].asDouble()),
vessel(node["vessel"]),
reactor(node["reactor"], &vessel),
grid(node["grid"]),
evaporator(node["evaporator"]),
sink(evaporator.fluid, 11, 0, 0),
freight_pump(node["pump"]["freight"], &sink, &evaporator),
loop(node, &vessel, &evaporator, &grid)
{ {
clock = node["clock"].asDouble();
vessel = std::make_unique<Reactor::Coolant::Vessel>(node["vessel"]);
reactor = std::make_unique<Reactor::Reactor>(node["reactor"], vessel.get());
condenser = std::make_unique<Coolant::Condenser>(node["condenser"]);
grid = std::make_unique<Electric::Grid>(node["grid"]);
turbine = std::make_unique<Electric::Turbine>(condenser.get());
generator = std::make_unique<Electric::Generator>(node["generator"], turbine.get(), grid.get());
evaporator = std::make_unique<Coolant::Evaporator>(node["evaporator"]);
sink = std::make_unique<Coolant::Sink>(evaporator->fluid, 11, 0, 0);
condenser_secondary = std::make_unique<Coolant::CondenserSecondary>(condenser.get(), evaporator.get(), 1000);
turbine_inlet_valve = std::make_unique<Coolant::Valve>(node["valve"]["turbine"]["inlet"], vessel.get(), turbine.get());
turbine_bypass_valve = std::make_unique<Coolant::Valve>(node["valve"]["turbine"]["bypass"], vessel.get(), condenser.get());
primary_pump = std::make_unique<Coolant::Pump>(node["pump"]["primary"], condenser.get(), vessel.get());
secondary_pump = std::make_unique<Coolant::Pump>(node["pump"]["secondary"], evaporator.get(), condenser_secondary.get());
freight_pump = std::make_unique<Coolant::Pump>(node["pump"]["freight"], sink.get(), evaporator.get());
} }
void System::update(double dt) void System::update(double dt)
@ -87,39 +66,23 @@ void System::update(double dt)
dt *= speed; dt *= speed;
clock += dt; clock += dt;
grid->update(dt); grid.update(dt);
reactor->update(dt); reactor.update(dt);
vessel->update(dt); vessel.update(dt);
turbine_inlet_valve->update(dt); freight_pump.update(dt);
turbine_bypass_valve->update(dt); evaporator.update(dt);
condenser->update(dt); loop.update(dt);
turbine->update(dt);
generator->update(dt);
primary_pump->update(dt);
secondary_pump->update(dt);
freight_pump->update(dt);
condenser_secondary->update(dt);
evaporator->update(dt);
} }
System::operator Json::Value() const System::operator Json::Value() const
{ {
Json::Value node; Json::Value node(loop);
node["grid"] = *grid; node["grid"] = grid;
node["vessel"] = *vessel; node["vessel"] = vessel;
node["generator"] = *generator; node["evaporator"] = evaporator;
node["condenser"] = *condenser; node["pump"]["freight"] = freight_pump;
node["evaporator"] = *evaporator; node["reactor"] = reactor;
node["pump"]["primary"] = *primary_pump;
node["pump"]["secondary"] = *secondary_pump;
node["pump"]["freight"] = *freight_pump;
node["valve"]["turbine"]["inlet"] = *turbine_inlet_valve;
node["valve"]["turbine"]["bypass"] = *turbine_bypass_valve;
node["reactor"] = *reactor;
node["clock"] = clock; node["clock"] = clock;
return node; return node;
@ -127,7 +90,7 @@ System::operator Json::Value() const
void System::save(const char* path) void System::save(const char* path)
{ {
Json::Value root(active); Json::Value root(*active);
root["camera"] = Graphics::Camera::serialize(); root["camera"] = Graphics::Camera::serialize();
Json::StreamWriterBuilder builder; Json::StreamWriterBuilder builder;
@ -147,8 +110,8 @@ void System::load(const char* path)
savefile >> root; savefile >> root;
savefile.close(); savefile.close();
System sys(root);
Graphics::Camera::load(root["camera"]); Graphics::Camera::load(root["camera"]);
std::unique_ptr<System> sys = std::make_unique<System>(root);
active = std::move(sys); active = std::move(sys);
} }

View File

@ -6,47 +6,31 @@
#include "reactor/coolant/vessel.hpp" #include "reactor/coolant/vessel.hpp"
#include "reactor/reactor.hpp" #include "reactor/reactor.hpp"
#include "coolant/pump.hpp"
#include "coolant/valve.hpp"
#include "coolant/condenser.hpp"
#include "coolant/condenser_secondary.hpp"
#include "coolant/evaporator.hpp"
#include "coolant/sink.hpp"
#include "electric/turbine.hpp"
#include "electric/generator.hpp"
#include "electric/grid.hpp" #include "electric/grid.hpp"
#include "coolant/loop.hpp"
namespace Sim namespace Sim
{ {
struct System struct System
{ {
static System active; static std::unique_ptr<System> active;
std::unique_ptr<Sim::Reactor::Reactor> reactor; Electric::Grid grid;
std::unique_ptr<Sim::Reactor::Coolant::Vessel> vessel; Reactor::Reactor reactor;
Reactor::Coolant::Vessel vessel;
std::unique_ptr<Sim::Coolant::Sink> sink; Coolant::Evaporator evaporator;
std::unique_ptr<Sim::Coolant::Condenser> condenser; Coolant::Pump freight_pump;
std::unique_ptr<Sim::Coolant::CondenserSecondary> condenser_secondary; Coolant::Sink sink;
std::unique_ptr<Sim::Coolant::Evaporator> evaporator; Coolant::Loop loop;
std::unique_ptr<Sim::Electric::Turbine> turbine;
std::unique_ptr<Sim::Electric::Generator> generator;
std::unique_ptr<Sim::Electric::Grid> grid;
std::unique_ptr<Sim::Coolant::Pump> primary_pump;
std::unique_ptr<Sim::Coolant::Pump> secondary_pump;
std::unique_ptr<Sim::Coolant::Pump> freight_pump;
std::unique_ptr<Sim::Coolant::Valve> turbine_bypass_valve;
std::unique_ptr<Sim::Coolant::Valve> turbine_inlet_valve;
double speed = 1; double speed = 1;
double clock = 3600 * 12; double clock = 3600 * 12;
System(); System();
System(const Json::Value& node); System(const Json::Value& node);
System(const System& o) = delete;
System(System&& o) = delete;
void update(double dt); void update(double dt);