From 67b9f29745cecef57eeffcb43275b22e1789f41f Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Sun, 4 Feb 2024 23:22:15 +1100 Subject: [PATCH] steam flow sort of works --- CMakeLists.txt | 2 +- src/coolant/fluid_holder.cpp | 85 ++++++++++++--------------- src/coolant/fluid_holder.hpp | 5 +- src/coolant/valve.cpp | 37 +++++++++++- src/coolant/valve.hpp | 4 +- src/electric/turbine.cpp | 18 ++++++ src/graphics/input/focus.cpp | 29 ++++++--- src/graphics/input/focus.hpp | 4 +- src/graphics/input/keyboard.cpp | 2 +- src/graphics/monitor/core.cpp | 9 ++- src/graphics/monitor/helpers.hpp | 5 +- src/graphics/monitor/primary_loop.cpp | 35 +++++++++-- src/main.cpp | 2 +- src/reactor/coolant/vessel.cpp | 16 +++-- src/reactor/rod.cpp | 1 - src/system.cpp | 8 +-- 16 files changed, 178 insertions(+), 84 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f0422a..b09541e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25) project(FastNuclearSim VERSION 1.0) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_FLAGS "-g -O3 -I/usr/include/freetype2") file(GLOB_RECURSE SOURCES src/*.cpp) diff --git a/src/coolant/fluid_holder.cpp b/src/coolant/fluid_holder.cpp index 266a382..7de0e9c 100644 --- a/src/coolant/fluid_holder.cpp +++ b/src/coolant/fluid_holder.cpp @@ -18,7 +18,7 @@ double fluid_holder::add_heat(double m1, double t1) { double t2 = get_heat(); double t = t1 - t2; - double m2 = (fluid.l_to_g(level) + steam) * fluid.jPgk; + double m2 = get_mass() * fluid.jPgk; double m = m1 + m2; if(m1 == 0 || m2 == 0) @@ -62,33 +62,24 @@ double fluid_holder::extract_fluid(double amount) return amount; } -double fluid_holder::extract_steam(double dt, double a, double p2) +void fluid_holder::add_steam(double m2, double t2) { - // calculate the mass moved - double p1 = get_pressure(); - double p = (p1 - p2) * 0.001; // mPa or g/m/s^2 + double m1 = steam; + double t1 = heat; + double m = m1 + m2; - if(p == 0) + if(m > 0) { - return 0; + heat = (t1 * m1 + t2 * m2) / m; } - double V = (volume - level) * 0.001; // m^3 - double mass = std::min(dt * a * p / std::sqrt( V * std::abs(p) / steam ), steam); - - if(std::isnan(mass)) - { - return 0; - } - - steam -= mass; - return mass; + steam = m; } double fluid_holder::get_pressure() const { double T = conversions::temperature::c_to_k(heat); - double V = (volume - level) * 0.001; + double V = get_steam_volume() * 0.001; double n = fluid.g_to_mol(steam); return (n * T * constants::R) / V; @@ -96,38 +87,36 @@ double fluid_holder::get_pressure() const void fluid_holder::update(double secs) { - double V = (volume - level) * 0.001; - double P = fluid.vapor_pressure.calc_p(heat); - double T = conversions::temperature::c_to_k(heat); - double n = fluid.mol_to_g((V * P) / (T * constants::R)) - steam; + double mass = get_mass(); - double s = steam + n; - double l = fluid.l_to_g(level) - n; - double v = fluid.l_to_g(volume); - - if(l < 0) + if(mass > 0) { - s += l; - l = 0; + double V = get_steam_volume() * 0.001; + double P = fluid.vapor_pressure.calc_p(heat); + double T = conversions::temperature::c_to_k(heat); + double n = fluid.mol_to_g((V * P) / (T * constants::R)) - steam; + + double s = steam + n; + double l = fluid.l_to_g(level) - n; + double v = fluid.l_to_g(volume); + + if(l < 0) + { + s += l; + l = 0; + } + + if(l > v) + { + l = v; + s = 0; + } + + double diff = s - steam; + + steam = s; + level = fluid.g_to_l(l); + heat -= diff * fluid.jPg / mass / fluid.jPgk; } - - if(s > v) - { - s = v; - l = 0; - } - - if(l > v) - { - l = v; - s = 0; - } - - double diff = s - steam; - - steam = s; - level = fluid.g_to_l(l); - heat -= diff * fluid.jPg / (fluid.l_to_g(level) + steam) / fluid.jPgk; - } diff --git a/src/coolant/fluid_holder.hpp b/src/coolant/fluid_holder.hpp index f191344..9374f5d 100644 --- a/src/coolant/fluid_holder.hpp +++ b/src/coolant/fluid_holder.hpp @@ -23,15 +23,16 @@ public: double add_heat(double m, double t); double add_fluid(double amount, double heat); - double extract_steam(double dt, double a, double p2); double extract_fluid(double amount); + virtual void add_steam(double amount, double t); constexpr double get_volume() const { return volume; } // litres constexpr double get_level() const { return level; } // litres constexpr double get_heat() const { return heat; } // celsius constexpr double get_steam() const { return steam; } // grams + constexpr double get_steam_volume() const { return volume - level; } // litres + constexpr double get_steam_density() const { return steam / get_steam_volume(); } // g/L constexpr double get_mass() const { return fluid.l_to_g(level) + steam; } // grams - constexpr double get_steam_density() const { return steam / (volume - level); } // g/L double get_pressure() const; // pascals void update(double dt); diff --git a/src/coolant/valve.cpp b/src/coolant/valve.cpp index 79ed2e2..4d28159 100644 --- a/src/coolant/valve.cpp +++ b/src/coolant/valve.cpp @@ -1,6 +1,9 @@ #include "valve.hpp" +#include +#include + using namespace sim::coolant; valve::valve(fluid_holder* src, fluid_holder* dst, double max) : src(src), dst(dst), max(max) @@ -10,18 +13,46 @@ valve::valve(fluid_holder* src, fluid_holder* dst, double max) : src(src), dst(d void valve::add_open_speed(double v) { - open_speed += v; + speed += v; } void valve::clear_open_speed() { - open_speed = 0; + speed = 0; } void valve::update(double dt) { - state += open_speed * dt; + state += speed * dt; + if(state > 1) state = 1; if(state < 0) state = 0; + + double r = max * state; // L + double m = r * dt;//1 - std::pow(0.5, dt * -std::log2(1 - r)); + + double pressure1 = src->get_pressure(); + double pressure2 = dst->get_pressure(); + double density1 = src->get_steam_density(); // g/L + double density2 = dst->get_steam_density(); // g/L + double diff = (pressure1 - pressure2) * m; + double temp, mass; + + if(diff > 0) + { + temp = src->get_heat(); + mass = diff * src->get_steam_density(); + } + + else + { + temp = dst->get_heat(); + mass = diff * dst->get_steam_density(); + } + + src->add_steam(-mass, temp); + dst->add_steam(mass, temp); + + this->flow = mass / dt; } diff --git a/src/coolant/valve.hpp b/src/coolant/valve.hpp index 45060f2..4b1cd9f 100644 --- a/src/coolant/valve.hpp +++ b/src/coolant/valve.hpp @@ -13,8 +13,9 @@ class valve fluid_holder* const src; fluid_holder* const dst; - double open_speed = 0; + double speed = 0; double state = 0; + double flow = 0; // L/s public: @@ -25,6 +26,7 @@ public: void clear_open_speed(); constexpr double get_state() const { return state; } + constexpr double get_flow() const { return flow; } }; }; diff --git a/src/electric/turbine.cpp b/src/electric/turbine.cpp index 9f77877..8f20159 100644 --- a/src/electric/turbine.cpp +++ b/src/electric/turbine.cpp @@ -1,5 +1,6 @@ #include "turbine.hpp" +#include "../system.hpp" #include #include @@ -21,7 +22,24 @@ turbine::turbine(coolant::fluid_t type, double height, double diameter, double l void turbine::update(double secs) { + sim::system& sys = sim::system::active; + auto& o = *sys.turbine.get(); + ((sim::coolant::fluid_holder*)this)->update(secs); + +/* if(level + o.level > o.volume) + { + level += o.level - o.volume; + o.level = o.volume; + } + + else + { + o.level += level; + level = 0; + } + + balance_steam(o);*/ } diff --git a/src/graphics/input/focus.cpp b/src/graphics/input/focus.cpp index d7674a2..459a6ca 100644 --- a/src/graphics/input/focus.cpp +++ b/src/graphics/input/focus.cpp @@ -12,12 +12,14 @@ #include #include +#include using namespace sim::graphics; static glm::vec<3, double> trigger_near; static glm::vec<3, double> trigger_far; +static std::vector> stack; static std::unique_ptr state = nullptr; static bool mouse_visible = false; static bool mouse_locked = false; @@ -51,11 +53,9 @@ void focus::on_mouse_button(int button, int action, int mods) state->on_mouse_button(button, action, mods); } - else if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) + if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { - triggered = true; - - if(is_mouse_locked()) + if(is_mouse_locked() && mouse_visible) { double mx, my; mouse::get(mx, my); @@ -66,12 +66,14 @@ void focus::on_mouse_button(int button, int action, int mods) trigger_near = glm::unProject(glm::vec3(mouse, -1), camera::get_matrix(), window::projection_matrix, viewport); trigger_far = glm::unProject(glm::vec3(mouse, 1), camera::get_matrix(), window::projection_matrix, viewport); + triggered = true; } - else + else if(!mouse_visible) { trigger_near = camera::get_pos(); trigger_far = trigger_near + camera::get_normal(); + triggered = true; } } } @@ -102,7 +104,7 @@ glm::vec<3, double> focus::get_trigger_far() return trigger_far; } -void focus::update() +void focus::update(double dt) { triggered = false; @@ -130,7 +132,7 @@ void focus::update() if(state) { - state->update(); + state->update(dt); } } @@ -142,6 +144,12 @@ bool focus::is_focused() void focus::clear_focus() { state = nullptr; + + if(stack.size() != 0) + { + state = std::move(stack.back()); + stack.pop_back(); + } } bool focus::is_mouse_locked() @@ -152,11 +160,16 @@ bool focus::is_mouse_locked() void focus::clear_mouse_locked() { mouse_locked = false; - state = nullptr; + clear_focus(); } void focus::set(std::unique_ptr f) { + if(state != nullptr) + { + stack.push_back(std::move(state)); + } + state = std::move(f); } diff --git a/src/graphics/input/focus.hpp b/src/graphics/input/focus.hpp index a586f0f..ad8f5cb 100644 --- a/src/graphics/input/focus.hpp +++ b/src/graphics/input/focus.hpp @@ -16,7 +16,7 @@ struct focus_t virtual void on_mouse_button(int button, int action, int mods) { } virtual void on_cursor_pos(double x, double y) { } virtual void on_charcode(unsigned int c) { } - virtual void update() { } + virtual void update(double dt) { } }; bool is_focused(); @@ -31,7 +31,7 @@ void on_keypress(int key, int sc, int action, int mods); void on_mouse_button(int button, int action, int mods); void on_cursor_pos(double x, double y); void on_charcode(unsigned int c); -void update(); +void update(double dt); }; diff --git a/src/graphics/input/keyboard.cpp b/src/graphics/input/keyboard.cpp index 9145ba6..391999b 100644 --- a/src/graphics/input/keyboard.cpp +++ b/src/graphics/input/keyboard.cpp @@ -61,7 +61,7 @@ static void cb_charcode(GLFWwindow* win, unsigned int code) bool keyboard::is_pressed(int key) { - if(focus::is_focused()) + if(focus::is_mouse_locked()) { return false; } diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 0604e25..12054b1 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -73,9 +73,16 @@ struct core_monitor : public focus::focus_t struct core_joystick : public focus::focus_t { + double ypos = 0; + virtual void on_cursor_pos(double x, double y) { - sim::system::active.reactor->add_rod_speed(y * 1e-6); + ypos += y; + } + + virtual void update(double dt) + { + sim::system::active.reactor->add_rod_speed(ypos * dt * 1e-6); } virtual void on_mouse_button(int button, int action, int mods) diff --git a/src/graphics/monitor/helpers.hpp b/src/graphics/monitor/helpers.hpp index 4aae605..4e64441 100644 --- a/src/graphics/monitor/helpers.hpp +++ b/src/graphics/monitor/helpers.hpp @@ -8,7 +8,8 @@ constexpr double show(double v, double m) return std::round(v * m) / m; } -constexpr double show(double v) +constexpr double show(double a) { - return std::round(v * 1e3) * 1e-3; + double b = std::round(a * 1e3) * 1e-3; + return b == 0 ? 0 : b; } diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index bd61b5f..7720471 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -10,6 +10,7 @@ #include "../input/focus.hpp" #include +#include using namespace sim::graphics; using namespace sim::graphics::monitor; @@ -30,7 +31,7 @@ struct valve_joystick : public focus::focus_t virtual void on_cursor_pos(double x, double y) { - active->add_open_speed(y * 1e-5); + active->add_open_speed(-y * 1e-6); } virtual void on_mouse_button(int button, int action, int mods) @@ -68,9 +69,20 @@ void primary_loop::init() std::stringstream ss; sim::graphics::mesh rmesh; - ss << "Turbine Valves\n\n"; - ss << "Inlet\n"; - ss << "Bypass\n"; + ss << "Turbine Bypass Valve\n\n"; + ss << "Opened\nFlow\n\n"; + ss << "Turbine Inlet Valve\n\n"; + ss << "Opened\nFlow\n\n"; + ss << "Turbine\n\n"; + ss << "Heat\n"; + ss << "Steam\n"; + ss << "Pressure\n"; + ss << "Level\n\n"; + ss << "Condenser\n\n"; + ss << "Heat\n"; + ss << "Steam\n"; + ss << "Pressure\n"; + ss << "Level\n\n"; rmesh.load_text(ss.str().c_str(), 0.04); mesh1.bind(); @@ -87,8 +99,21 @@ void primary_loop::update() system& sys = sim::system::active; ss << "\n\n"; - ss << show( sys.turbine_inlet_valve->get_state() * 100 ) << " %\n"; ss << show( sys.turbine_bypass_valve->get_state() * 100 ) << " %\n"; + ss << show( sys.turbine_bypass_valve->get_flow() ) << " g/s\n"; + ss << "\n\n\n"; + ss << show( sys.turbine_inlet_valve->get_state() * 100 ) << " %\n"; + ss << show( sys.turbine_inlet_valve->get_flow() ) << " g/s\n"; + ss << "\n\n\n"; + ss << show( sys.turbine->get_heat() ) << " C\n"; + ss << show( sys.turbine->get_steam() ) << " g\n"; + ss << show( sys.turbine->get_pressure() / 1000 ) << " kPa\n"; + ss << sys.turbine->get_level() << " / " << show( sys.turbine->get_volume() ) << " L\n"; + ss << "\n\n\n"; + ss << show( sys.condenser->get_heat() ) << " C\n"; + ss << show( sys.condenser->get_steam() ) << " g\n"; + ss << show( sys.condenser->get_pressure() / 1000 ) << " kPa\n"; + ss << sys.condenser->get_level() << " / " << show( sys.condenser->get_volume() ) << " L\n"; rmesh.load_text(ss.str().c_str(), 0.04); mesh2.bind(); diff --git a/src/main.cpp b/src/main.cpp index 870a083..3b316f9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,7 @@ int main() graphics::camera::update(dt); graphics::window::update(dt); - graphics::focus::update(); + graphics::focus::update(dt); graphics::window::render(); } diff --git a/src/reactor/coolant/vessel.cpp b/src/reactor/coolant/vessel.cpp index 3b4f538..ecd75d9 100644 --- a/src/reactor/coolant/vessel.cpp +++ b/src/reactor/coolant/vessel.cpp @@ -30,14 +30,22 @@ double vessel::get_steam_suspended() const double vessel::get_void_ratio() const { - double s = steam_suspended / get_steam_density(); - - if(s == 0) + double density = get_steam_density(); + + if(density == 0) { return 0; } - return s / (level + s); + double s = steam_suspended / density; + double m = level + s; + + if(m == 0) + { + return 0; + } + + return s / m; } double vessel::get_bubble_hl() const diff --git a/src/reactor/rod.cpp b/src/reactor/rod.cpp index d0379eb..cc30173 100644 --- a/src/reactor/rod.cpp +++ b/src/reactor/rod.cpp @@ -31,7 +31,6 @@ double rod::extract(val_t type, double s, double k, double o) m = 1 - std::pow(0.5, s * -std::log2(k)); } - double v = m * 0.5 * (get(type) - o); vals[type] -= v; diff --git a/src/system.cpp b/src/system.cpp index 6ffa934..909fc30 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -37,11 +37,11 @@ system::system() vessel = std::make_unique(sim::coolant::WATER, 8, 10, 300); reactor = std::make_unique(sim::reactor::builder(19, 19, 1.0 / 4.0, 4, reactor::fuel::fuel_rod(0.5), vessel.get(), layout)); - condenser = std::make_unique(sim::coolant::WATER, 8, 6, 20); - turbine = std::make_unique(sim::coolant::WATER, 6, 3, 20); + condenser = std::make_unique(sim::coolant::WATER, 8, 6, 0); + turbine = std::make_unique(sim::coolant::WATER, 6, 3, 0); - turbine_inlet_valve = std::make_unique(vessel.get(), turbine.get(), 1); - turbine_bypass_valve = std::make_unique(vessel.get(), condenser.get(), 1); + turbine_inlet_valve = std::make_unique(vessel.get(), turbine.get(), 1e-7); + turbine_bypass_valve = std::make_unique(vessel.get(), condenser.get(), 1e-7); core_pump = std::make_unique(condenser.get(), vessel.get(), 1e6, 1, 100, 100); }