initial commit

This commit is contained in:
Jay Robson 2024-01-13 15:21:17 +11:00
commit b45f76b7bd
11 changed files with 387 additions and 0 deletions

8
.gitattributes vendored Normal file
View File

@ -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

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build

12
CMakeLists.txt Normal file
View File

@ -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)

51
src/fuel_rod.cpp Normal file
View File

@ -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;
}

38
src/fuel_rod.hpp Normal file
View File

@ -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;
}
};
};

20
src/half_life.hpp Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <cmath>
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);
}
};

26
src/main.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "fuel_rod.hpp"
#include <iostream>
#include <unistd.h>
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;
}

99
src/sample.cpp Normal file
View File

@ -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";
}

48
src/sample.hpp Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include "waste.hpp"
#include <ostream>
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;
}
};
}

57
src/waste.cpp Normal file
View File

@ -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;
}

25
src/waste.hpp Normal file
View File

@ -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();
};
}