From b45f76b7bde6f9168d3fe8663594136b1f3a7703 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Sat, 13 Jan 2024 15:21:17 +1100 Subject: [PATCH] initial commit --- .gitattributes | 8 ++++ .gitignore | 3 ++ CMakeLists.txt | 12 ++++++ src/fuel_rod.cpp | 51 ++++++++++++++++++++++++ src/fuel_rod.hpp | 38 ++++++++++++++++++ src/half_life.hpp | 20 ++++++++++ src/main.cpp | 26 +++++++++++++ src/sample.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++ src/sample.hpp | 48 +++++++++++++++++++++++ src/waste.cpp | 57 +++++++++++++++++++++++++++ src/waste.hpp | 25 ++++++++++++ 11 files changed, 387 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 src/fuel_rod.cpp create mode 100644 src/fuel_rod.hpp create mode 100644 src/half_life.hpp create mode 100644 src/main.cpp create mode 100644 src/sample.cpp create mode 100644 src/sample.hpp create mode 100644 src/waste.cpp create mode 100644 src/waste.hpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..df209d7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* !text !filter !merge !diff +*.blend filter=lfs diff=lfs merge=lfs -text +*.glb filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.obj filter=lfs diff=lfs merge=lfs -text +*.fbx filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.xcf filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2475ac7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ + +build + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f726ec5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.25) + +project(FastNuclearSim VERSION 1.0) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_FLAGS "-O3 -lncurses") + +file(GLOB_RECURSE SOURCES src/*.cpp) + +add_executable(FastNuclearSim ${SOURCES}) +target_link_libraries(FastNuclearSim PUBLIC stdc++ m) + diff --git a/src/fuel_rod.cpp b/src/fuel_rod.cpp new file mode 100644 index 0000000..c5a0346 --- /dev/null +++ b/src/fuel_rod.cpp @@ -0,0 +1,51 @@ + +#include "fuel_rod.hpp" + +using namespace sim; + +fuel_rod::fuel_rod(double f, double m) : fuel(f, m) +{ + +} + +void fuel_rod::update(double secs) +{ + double n = fuel.extract_fast_neutrons(); + double n_slow = n * 0.5 * reactivity; + fuel.add_slow_neutrons(n_slow); + neutrons_absorbed += n_slow; + neutrons_free += n_slow; + + fuel.update(secs); + + + temperature += fuel.extract_energy() / fuel.get_mass(); +} + +double fuel_rod::extract_free_neutrons() +{ + double v = neutrons_free; + neutrons_free = 0; + return v; +} + +double fuel_rod::extract_heat(double k, double o) +{ + double v = k * (temperature - o); + temperature -= v; + return v; +} + +void fuel_rod::set_reactivity(double v) +{ + reactivity = v; +} + +void fuel_rod::display(std::ostream& o) const +{ + o << "Temperature: " << temperature << "\n"; + o << "Reactivity: " << reactivity << "\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 new file mode 100644 index 0000000..e48a853 --- /dev/null +++ b/src/fuel_rod.hpp @@ -0,0 +1,38 @@ + +#pragma once + +#include "sample.hpp" + +namespace sim +{ + +class fuel_rod +{ + sample fuel; + + double reactivity = 0; + double temperature = 0; + double neutrons_absorbed = 0; + double neutrons_free = 0; + + void display(std::ostream& o) const; + +public: + + fuel_rod(double fuel, double mass); + + void update(double secs); + void set_reactivity(double amount); + + double extract_free_neutrons(); + double extract_heat(double k, double o); + + friend std::ostream& operator<<(std::ostream& o, const fuel_rod& fr) + { + fr.display(o); + return o; + } +}; + +}; + diff --git a/src/half_life.hpp b/src/half_life.hpp new file mode 100644 index 0000000..a2a1ee5 --- /dev/null +++ b/src/half_life.hpp @@ -0,0 +1,20 @@ + +#pragma once + +#include + +namespace sim::half_life +{ + +const double Te_135 = 19; +const double I_135 = 23652; +const double Xe_135 = 32904; +const double Cs_135 = 41971608000000; + +constexpr double get(double secs, double hl) noexcept +{ + return std::pow(0.5, secs / hl); +} + +}; + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..adefa5e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,26 @@ + +#include "fuel_rod.hpp" + +#include + +#include + +int main() +{ + sim::fuel_rod fr(100, 200); + + fr.set_reactivity(0); + + for(;;) + { + for(int i = 0; i < 1e4; i++) + { + fr.update(1e-4); + } + + std::cout << "\nFuel Rod:\n\n" << fr << "\n\n"; + } + + return 0; +} + diff --git a/src/sample.cpp b/src/sample.cpp new file mode 100644 index 0000000..52e32a0 --- /dev/null +++ b/src/sample.cpp @@ -0,0 +1,99 @@ + +#include "sample.hpp" +#include "half_life.hpp" + +using namespace sim; + +static const double Xe_135_M = 1e4; +static const double NEUTRON_BG = 1e-10; + +sample::sample(double fuel, double mass) +{ + this->fuel = fuel; + this->mass = mass; +} + +void sample::update(double secs) +{ + double m; + + // simulate waste and extract products + waste.update(secs); + fast_neutrons += waste.extract_neutrons(); + energy += waste.extract_energy(); + + // decay Xe-135 + m = half_life::get(secs, half_life::Xe_135); + xe_135 *= m; + + // decay I-135 into Xe-135 + m = half_life::get(secs, half_life::I_135); + xe_135 += i_135 * (1 - m); + i_135 *= m; + + // decay Te-135 into I-135 + m = half_life::get(secs, half_life::Te_135); + i_135 += te_135 * (1 - m); + te_135 *= m; + + // absorb neutrons + double volume = get_volume(); + double neutrons = (slow_neutrons + NEUTRON_BG * secs) * (fuel / volume); + slow_neutrons = 0; + + // deal with this edge case + if(neutrons > fuel) + { + slow_neutrons = neutrons - fuel; + neutrons = fuel; + } + + // simulate fuel use + fuel -= neutrons; + energy += neutrons; + fast_neutrons += neutrons * 3; + waste.add_fissile(neutrons * 2); + + // add the poison + te_135 += neutrons; +} + +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; + energy = 0; + return v; +} + +double sample::extract_fast_neutrons() +{ + double v = fast_neutrons; + fast_neutrons = 0; + return v; +} + +void sample::add_slow_neutrons(double a) +{ + slow_neutrons += a; +} + +void sample::display(std::ostream& o) const +{ + o << "Fuel: " << fuel << "\n"; + o << "Mass: " << mass << "\n"; + o << "Energy: " << energy << "\n"; + o << "Neutrons:\n Fast: " << fast_neutrons << "\n Slow: " << slow_neutrons << "\n"; + o << "Poison:\n Te-135: " << te_135 << "\n I-135: " << i_135 << "\n Xe-135: " << xe_135 << "\n"; + o << "Neutron Absorbtion: " << (fuel / get_volume()) << "\n"; +} + diff --git a/src/sample.hpp b/src/sample.hpp new file mode 100644 index 0000000..e97d2b5 --- /dev/null +++ b/src/sample.hpp @@ -0,0 +1,48 @@ + +#pragma once + +#include "waste.hpp" + +#include + +namespace sim +{ + +class sample +{ + sim::waste waste; + + double fuel = 0; + double i_135 = 0; + double xe_135 = 0; + double te_135 = 0; + double mass = 0; + + double energy = 0; + double fast_neutrons = 0; + double slow_neutrons = 0; + + void display(std::ostream& o) const; + +public: + + sample(double fuel, double mass); + + void update(double secs); + double extract_energy(); + double extract_fast_neutrons(); + void add_slow_neutrons(double a); + + double get_volume() const; + double get_mass() const; + + friend std::ostream& operator<<(std::ostream& o, const sample& s) + { + s.display(o); + return o; + } +}; + + +} + diff --git a/src/waste.cpp b/src/waste.cpp new file mode 100644 index 0000000..2750b4b --- /dev/null +++ b/src/waste.cpp @@ -0,0 +1,57 @@ + +#include "waste.hpp" +#include "half_life.hpp" + +using namespace sim; + +void waste::update(double secs) +{ + double hl = 1; + double next[waste::N - 1] = {0}; + + for(int i = 0; i < waste::N - 1; i++) + { + double m = 1 - half_life::get(secs, hl); + double h = high[i] * m; + double l = low[i] * m; + + next[i] += h + l; + high[i] -= h; + low[i] -= l; + + neutrons += h; + energy += h + l; + hl *= 2; + } + + for(int i = 0; i < waste::N - 1; i++) + { + low[i + 1] += next[i]; + } +} + +void waste::add_fissile(double amount) +{ + double m = 0.5; + + for(int i = 0; i < waste::N; i++) + { + high[i] += amount * m; + m *= 0.5; + } +} + +double waste::extract_neutrons() +{ + double v = neutrons; + neutrons = 0; + return v; +} + +double waste::extract_energy() +{ + double v = energy; + energy = 0; + return v; +} + diff --git a/src/waste.hpp b/src/waste.hpp new file mode 100644 index 0000000..5cd4bd1 --- /dev/null +++ b/src/waste.hpp @@ -0,0 +1,25 @@ + +#pragma once + +namespace sim +{ + +class waste +{ + static const int N = 64; + + double high[N] = {0}; + double low[N] = {0}; + double neutrons = 0; + double energy = 0; + +public: + + void update(double secs); + void add_fissile(double amount); + double extract_neutrons(); + double extract_energy(); +}; + +} +