From b1576166872b23bca1b22c9e244c6fa77ff22c4d Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Fri, 2 Feb 2024 22:03:47 +1100 Subject: [PATCH] adding other plant supporting equipment --- src/coolant/condenser.cpp | 40 ++++++++++ src/coolant/condenser.hpp | 24 ++++++ src/coolant/fluid_holder.cpp | 130 +++++++++++++++++++++++++++++++++ src/coolant/fluid_holder.hpp | 46 ++++++++++++ src/coolant/pump.cpp | 72 ++++++++++++++++++ src/coolant/pump.hpp | 57 +++++---------- src/coolant/valve.cpp | 27 +++++++ src/coolant/valve.hpp | 48 +++--------- src/electric/turbine.cpp | 0 src/electric/turbine.hpp | 10 +++ src/reactor/coolant/vessel.cpp | 114 +++-------------------------- src/reactor/coolant/vessel.hpp | 32 ++------ src/system.cpp | 19 +++-- src/system.hpp | 6 +- 14 files changed, 407 insertions(+), 218 deletions(-) create mode 100644 src/coolant/condenser.cpp create mode 100644 src/coolant/condenser.hpp create mode 100644 src/coolant/fluid_holder.cpp create mode 100644 src/coolant/fluid_holder.hpp create mode 100644 src/coolant/pump.cpp create mode 100644 src/coolant/valve.cpp create mode 100644 src/electric/turbine.cpp create mode 100644 src/electric/turbine.hpp diff --git a/src/coolant/condenser.cpp b/src/coolant/condenser.cpp new file mode 100644 index 0000000..3692c73 --- /dev/null +++ b/src/coolant/condenser.cpp @@ -0,0 +1,40 @@ + +#include "condenser.hpp" + +#include +#include + +using namespace sim::coolant; + +constexpr static double calc_cylinder(double h, double d) +{ + double r = d / 2; + + return M_PI * r * r * h; +} + +condenser::condenser(fluid_t type, double height, double diameter, double level) : + height(height), diameter(diameter), fluid_holder(type, calc_cylinder(height, diameter)) +{ + this->level = level; +} + +double condenser::get_bubble_hl() +{ + return (level / volume) * diameter * 0.5 / fluid.bubble_speed; +} + +void condenser::update(double secs) +{ + std::cout << "Condenser:\n\n"; + std::cout << "Level: " << level << "\n"; + std::cout << "Volume: " << volume << "\n"; + std::cout << "Height: " << height << "\n"; + std::cout << "Diameter: " << diameter << "\n"; + std::cout << "Pressure: " << get_pressure() << "\n"; + std::cout << "Teperature: " << heat << "\n\n"; + + ((sim::coolant::fluid_holder*)this)->update(secs); +} + + diff --git a/src/coolant/condenser.hpp b/src/coolant/condenser.hpp new file mode 100644 index 0000000..cbd8414 --- /dev/null +++ b/src/coolant/condenser.hpp @@ -0,0 +1,24 @@ + +#pragma once + +#include "fluid_holder.hpp" + +namespace sim::coolant +{ + +class condenser : public fluid_holder +{ + const double height; + const double diameter; + + virtual double get_bubble_hl(); + +public: + + condenser(fluid_t type, double height, double diameter, double level); + + void update(double dt); +}; + +}; + diff --git a/src/coolant/fluid_holder.cpp b/src/coolant/fluid_holder.cpp new file mode 100644 index 0000000..9682663 --- /dev/null +++ b/src/coolant/fluid_holder.cpp @@ -0,0 +1,130 @@ + +#include "fluid_holder.hpp" +#include "../constants.hpp" +#include "../conversions/temperature.hpp" +#include "../reactor/fuel/half_life.hpp" + +#include + +using namespace sim::coolant; + +fluid_holder::fluid_holder(fluid_t fluid, double volume) : fluid(fluid), volume(volume) +{ + +} + +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 m = m1 + m2; + + heat = t1 - t * m2 / m; + return heat; +} + +double fluid_holder::add_fluid(double v2, double t2) +{ + double v1 = level; + double t1 = get_heat(); + double t = t1 - t2; + + if(level + v2 > volume) + { + v2 = volume - level; + } + + heat = t1 - t * v2 / (v1 + v2); + level += v2; + + return v2; +} + +double fluid_holder::extract_fluid(double amount) +{ + if(amount < level) + { + level -= amount; + } + + else + { + amount = level; + level = 0; + } + + return amount; +} + +double fluid_holder::extract_steam(double dt, double a, double p2) +{ + // calculate the mass moved + double p1 = get_pressure(); + double p = (p1 - p2) * 0.001; // mPa or g/m/s^2 + + if(p == 0) + { + return 0; + } + + 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; +} + +double fluid_holder::get_pressure() const +{ + double T = conversions::temperature::c_to_k(heat); + double V = (volume - level) * 0.001; + double n = fluid.g_to_mol(steam); + + return (n * T * constants::R) / V; +} + +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 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(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; + + if(diff > 0) steam_suspended += diff; + steam_suspended *= reactor::fuel::half_life::get(secs, get_bubble_hl()); +} + diff --git a/src/coolant/fluid_holder.hpp b/src/coolant/fluid_holder.hpp new file mode 100644 index 0000000..68bcd2e --- /dev/null +++ b/src/coolant/fluid_holder.hpp @@ -0,0 +1,46 @@ + +#pragma once + +#include "fluid_t.hpp" + +namespace sim::coolant +{ + +class fluid_holder +{ +protected: + + const fluid_t fluid; + const double volume; // litres + + double level = 0; // litres + double steam = 0; // grams + double steam_suspended = 0; // grams + double heat = 0; // celsius + + fluid_holder(fluid_t fluid, double volume); + +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); + + 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_mass() const { return fluid.l_to_g(level) + steam; } // grams + constexpr double get_steam_density() const { return steam / (volume - level); } // g/L + constexpr double get_steam_suspended() const { return steam_suspended; } // grams + constexpr double get_void_ratio() const { double s = steam_suspended / get_steam_density(); return s / (level + s); } + + virtual double get_bubble_hl() = 0; + + double get_pressure() const; // pascals + void update(double dt); +}; + +}; + diff --git a/src/coolant/pump.cpp b/src/coolant/pump.cpp new file mode 100644 index 0000000..4bf4af3 --- /dev/null +++ b/src/coolant/pump.cpp @@ -0,0 +1,72 @@ + +#include "pump.hpp" + +#include +#include + +using namespace sim::coolant; + +pump::pump(fluid_holder& src, fluid_holder& dst, double mass, double radius, double l_per_rev, double friction) : + src(&src), dst(&dst), mass(mass), radius(radius), l_per_rev(l_per_rev), friction(friction) +{ + power = 1e3; +} + +double pump::get_flow() const +{ + return l_per_rev * get_rpm() / 60; +} + +double pump::get_rpm() const +{ + return velocity / (M_PI * mass * 0.001 * radius * radius); +} + +static double calc_work(double j, double mass) +{ + double m = 1; + + if(j < 0) + { + m = -1; + } + + return m * std::sqrt(m * j / (mass * 0.001)); +} + +void pump::update(double dt) +{ + velocity += calc_work(dt * power, mass); + + double src_heat = src->get_heat(); + double p_diff_1 = dst->get_pressure() - src->get_pressure(); + double src_volume = src->extract_fluid(get_flow() * dt); + double dst_volume = dst->add_fluid(src_volume, src_heat); + + if(dst_volume < src_volume) + { + src->add_fluid(src_volume - dst_volume, src_heat); + } + + double p_diff_2 = dst->get_pressure() - src->get_pressure(); + double p_diff = (p_diff_1 + p_diff_2) / 2; + double work = p_diff * dst_volume + get_rpm() * 60 * dt * friction; + + velocity -= calc_work(work, mass); + + if(dst->get_level() > 400 || src->get_level() < 50) + { + power = 0; + } + + else + { + power = 1e3; + } + + std::cout << "RPM: " << get_rpm() << "\t"; + std::cout << "Flow: " << get_flow() << std::endl; + std::cout << "Work Done: " << work << " J\n"; + std::cout << "Src Volume: " << src_volume << "\n"; +} + diff --git a/src/coolant/pump.hpp b/src/coolant/pump.hpp index a1f928c..e7ed378 100644 --- a/src/coolant/pump.hpp +++ b/src/coolant/pump.hpp @@ -1,57 +1,34 @@ #pragma once -#include +#include "fluid_holder.hpp" namespace sim::coolant { -template class pump { - const double max; - const double heat; - - A* a; - double rate = 0; + fluid_holder* const src; + fluid_holder* const dst; + + const double mass; // grams + const double radius; // meters + const double l_per_rev; // litres + const double friction; // J/rev + + double velocity = 0; // m/s public: - constexpr pump(A& a, double max, double heat) : a(&a), max(max), heat(heat) - { + double power = 0; // watts - } + pump(fluid_holder& src, fluid_holder& dst, double mass, double radius, double l_per_rev, double friction); - constexpr double get_rate() const - { - return rate; - } + double get_flow() const; // L/s + double get_rpm() const; // rev/min + + void update(double dt); +}; - constexpr double get_flow() const - { - return rate * max; - } - - constexpr void change_speed(double amount) - { - rate += amount; - - if(rate < 0) rate = 0; - if(rate > 1) rate = 1; - } - - void update(double secs) - { - a->add_fluid(rate * max * secs, heat); - } - - friend std::ostream& operator<<(std::ostream& o, const pump& p) - { - o << "Rate: " << (p.get_rate() * 100) << " %\n"; - o << "Flow: " << (p.get_flow() * 0.001) << " kg/s\n"; - return o; - } -}; - }; diff --git a/src/coolant/valve.cpp b/src/coolant/valve.cpp new file mode 100644 index 0000000..8d19958 --- /dev/null +++ b/src/coolant/valve.cpp @@ -0,0 +1,27 @@ + +#include "valve.hpp" + +using namespace sim::coolant; + +valve::valve(fluid_holder& src, fluid_holder& dst, double max) : src(&src), dst(&dst), max(max) +{ + +} + +void valve::set_state(double v) +{ + if(v > 1) v = 1; + if(v < 0) v = 0; + state = v; +} + +void valve::open(double v) +{ + set_state(state + v); +} + +void valve::update(double dt) +{ +// rate = a->extract_steam(dt, state * max, pressure) / dt; TODO +} + diff --git a/src/coolant/valve.hpp b/src/coolant/valve.hpp index 8498832..1339b49 100644 --- a/src/coolant/valve.hpp +++ b/src/coolant/valve.hpp @@ -1,55 +1,29 @@ #pragma once +#include "fluid_holder.hpp" + namespace sim::coolant { -template class valve { - A* a; - const double max; - const double pressure; + + fluid_holder* const src; + fluid_holder* const dst; double state = 0; - double rate = 0; public: - constexpr valve(A& a, double max, double pressure) : a(&a), max(max), pressure(pressure) - { + valve(fluid_holder& src, fluid_holder& dst, double max); - } - - constexpr double get_state() const - { - return state; - } - - constexpr void set_state(double v) - { - if(v > 1) v = 1; - if(v < 0) v = 0; - state = v; - } - - constexpr void open(double v) - { - set_state(state + v); - } - - constexpr void update(double secs) - { - rate = a->extract_steam(secs, state * max, pressure) / secs; - } - - friend std::ostream& operator<<(std::ostream& o, const valve& v) - { - o << "Opened: " << (v.state * 100) << " %\n"; - o << "Rate: " << v.rate << " g/s\n"; - return o; - } + void open(double v); + void update(double secs); + void set_state(double v); + + constexpr double get_state() const { return state; } }; }; diff --git a/src/electric/turbine.cpp b/src/electric/turbine.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/electric/turbine.hpp b/src/electric/turbine.hpp new file mode 100644 index 0000000..cf806ae --- /dev/null +++ b/src/electric/turbine.hpp @@ -0,0 +1,10 @@ + +#pragma once + +namespace sim::electric +{ + + + +}; + diff --git a/src/reactor/coolant/vessel.cpp b/src/reactor/coolant/vessel.cpp index 0c82ffe..b594669 100644 --- a/src/reactor/coolant/vessel.cpp +++ b/src/reactor/coolant/vessel.cpp @@ -15,114 +15,20 @@ constexpr static double calc_cylinder(double h, double d) return M_PI * r * r * h; } -vessel::vessel(double height, double diameter, double level, sim::coolant::fluid_t fluid) : - height(height), - diameter(diameter), - volume(calc_cylinder(height, diameter)), - fluid(fluid), - level(level), - bubble_hl(height * 0.5 / fluid.bubble_speed) +vessel::vessel(sim::coolant::fluid_t fluid, double height, double diameter, double level) : + sim::coolant::fluid_holder(fluid, calc_cylinder(height, diameter)), + height(height), diameter(diameter) { - + this->level = level; +} + +double vessel::get_bubble_hl() +{ + return (level / volume) * height * 0.5 / fluid.bubble_speed; } void vessel::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 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(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; - - if(diff > 0) steam_suspended += diff; - steam_suspended *= fuel::half_life::get(secs, bubble_hl); -} - -double vessel::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 m = m1 + m2; - - heat = t1 - t * m2 / m; - return heat; -} - -double vessel::add_fluid(double m2, double t2) -{ - double m1 = get_mass(); - double t1 = get_heat(); - double t = t1 - t2; - - m2 = fluid.g_to_l(m2); - - if(level + m2 > volume) - { - m2 = volume - level; - } - - heat = t1 - t * m2 / (m1 + m2); - level += m2; - return m2; -} - -double vessel::extract_steam(double dt, double a, double p2) -{ - // calculate the mass moved - double p1 = get_pressure(); - double p = (p1 - p2) * 0.001; // mPa or g/m/s^2 - - if(p == 0) - { - return 0; - } - - 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; -} - -double vessel::get_pressure() const -{ - double T = conversions::temperature::c_to_k(heat); - double V = (volume - level) * 0.001; - double n = fluid.g_to_mol(steam); - - return (n * T * constants::R) / V; + ((sim::coolant::fluid_holder*)this)->update(secs); } diff --git a/src/reactor/coolant/vessel.hpp b/src/reactor/coolant/vessel.hpp index 99ddcac..4533075 100644 --- a/src/reactor/coolant/vessel.hpp +++ b/src/reactor/coolant/vessel.hpp @@ -3,44 +3,22 @@ #include -#include "../../coolant/fluid_t.hpp" +#include "../../coolant/fluid_holder.hpp" namespace sim::reactor::coolant { -class vessel +class vessel : public sim::coolant::fluid_holder { - double level; // litres - double heat = 0; // celsius - double steam = 0; // grams - double steam_suspended = 0; // grams - public: const double height; // meters const double diameter; // meters - const double volume; // litres - const double bubble_hl; // seconds - const sim::coolant::fluid_t fluid; - - vessel(double height, double diameter, double level, sim::coolant::fluid_t fluid); + vessel(sim::coolant::fluid_t fluid, double height, double diameter, double level); + virtual double get_bubble_hl(); void update(double secs); - double add_heat(double m, double t); - double add_fluid(double amount, double heat); - double extract_steam(double dt, double a, double p2); - - 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_mass() const { return fluid.l_to_g(level) + steam; } // grams - constexpr double get_steam_density() const { return steam / (volume - level); } // g/L - constexpr double get_steam_suspended() const { return steam_suspended; } // grams - constexpr double get_void_ratio() const { double s = steam_suspended / get_steam_density(); return s / (level + s); } - - double get_pressure() const; // pascals friend std::ostream& operator<<(std::ostream& o, const vessel& v) { @@ -56,5 +34,5 @@ public: }; -} +}; diff --git a/src/system.cpp b/src/system.cpp index 9bea50c..f8495bb 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -35,19 +35,21 @@ system::system() " C C C C " }; - vessel = std::make_unique(8, 10, 300, sim::coolant::WATER); - reactor = std::make_unique(sim::reactor::builder(19, 19, 1.0 / 4.0, 4, reactor::fuel::fuel_rod(0.5), *vessel.get(), layout)); + 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, 200); - valve = std::make_unique>(*vessel.get(), 1, 500); - pump = std::make_unique>(*vessel.get(), 1e4, 15); + turbine_bypass_valve = std::make_unique(*vessel.get(), *condenser.get(), 1); + core_pump = std::make_unique(*condenser.get(), *vessel.get(), 1e6, 1, 100, 100); } system::system(system&& o) { vessel = std::move(o.vessel); reactor = std::move(o.reactor); - valve = std::move(o.valve); - pump = std::move(o.pump); + condenser = std::move(o.condenser); + turbine_bypass_valve = std::move(o.turbine_bypass_valve); + core_pump = std::move(o.core_pump); } void system::update(double dt) @@ -55,7 +57,8 @@ void system::update(double dt) dt *= speed; vessel->update(dt); reactor->update(dt); - valve->update(dt); - pump->update(dt); + condenser->update(dt); + turbine_bypass_valve->update(dt); + core_pump->update(dt); } diff --git a/src/system.hpp b/src/system.hpp index 81b5436..db4405d 100644 --- a/src/system.hpp +++ b/src/system.hpp @@ -7,6 +7,7 @@ #include "reactor/reactor.hpp" #include "coolant/pump.hpp" #include "coolant/valve.hpp" +#include "coolant/condenser.hpp" #include "graphics/mesh/mesh.hpp" namespace sim @@ -18,8 +19,9 @@ struct system std::unique_ptr reactor; std::unique_ptr vessel; - std::unique_ptr> valve; - std::unique_ptr> pump; + std::unique_ptr condenser; + std::unique_ptr core_pump; + std::unique_ptr turbine_bypass_valve; sim::graphics::mesh scene; double speed = 1;