made sim more accurate, fancy displays now show stuff
This commit is contained in:
parent
3c0dbabf16
commit
853c8dde3d
|
@ -137,7 +137,7 @@ void mesh::load_text(const char* text, double size)
|
||||||
x += ch.advance * size;
|
x += ch.advance * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_vertices(&vertices[0], vertices.size(), GL_DYNAMIC_DRAW);
|
set_vertices(&vertices[0], vertices.size());
|
||||||
set_indices(&indices[0], indices.size(), GL_DYNAMIC_DRAW);
|
set_indices(&indices[0], indices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "glmesh.hpp"
|
||||||
|
#include "arrays.hpp"
|
||||||
|
#include "../shader.hpp"
|
||||||
|
#include "../camera.hpp"
|
||||||
|
|
||||||
|
using namespace sim::graphics;
|
||||||
|
|
||||||
|
constexpr static void init(glmesh* m)
|
||||||
|
{
|
||||||
|
if(m->vao != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &m->vao);
|
||||||
|
glGenBuffers(1, &m->vbo);
|
||||||
|
glGenBuffers(1, &m->ebo);
|
||||||
|
|
||||||
|
glBindVertexArray(m->vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo);
|
||||||
|
|
||||||
|
arrays::vertex_attrib_pointers();
|
||||||
|
}
|
||||||
|
|
||||||
|
glmesh::glmesh(glmesh&& o)
|
||||||
|
{
|
||||||
|
vbo = o.vbo;
|
||||||
|
ebo = o.ebo;
|
||||||
|
vao = o.vao;
|
||||||
|
size = o.size;
|
||||||
|
colour_matrix = o.colour_matrix;
|
||||||
|
model_matrix = o.model_matrix;
|
||||||
|
|
||||||
|
o.vbo = 0;
|
||||||
|
o.ebo = 0;
|
||||||
|
o.vao = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glmesh::~glmesh()
|
||||||
|
{
|
||||||
|
if(vbo) glDeleteBuffers(1, &vbo);
|
||||||
|
if(ebo) glDeleteBuffers(1, &ebo);
|
||||||
|
if(vao) glDeleteVertexArrays(1, &vao);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glmesh::bind()
|
||||||
|
{
|
||||||
|
init(this);
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glmesh::uniform()
|
||||||
|
{
|
||||||
|
glm::mat4 m = camera::get_matrix() * model_matrix;
|
||||||
|
glUniformMatrix4fv(shader::gl_model, 1, false, &m[0][0]);
|
||||||
|
glUniformMatrix4fv(shader::gl_tex_mat, 1, false, &colour_matrix[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glmesh::set(const mesh& m, int mode)
|
||||||
|
{
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, m.vertices.size() * sizeof(m.vertices[0]), &m.vertices[0], mode);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m.indices.size() * sizeof(m.indices[0]), &m.indices[0], mode);
|
||||||
|
this->size = m.indices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glmesh::render()
|
||||||
|
{
|
||||||
|
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "arrays.hpp"
|
||||||
|
#include "mesh.hpp"
|
||||||
|
|
||||||
|
#include <glm/matrix.hpp>
|
||||||
|
|
||||||
|
namespace sim::graphics
|
||||||
|
{
|
||||||
|
|
||||||
|
struct glmesh
|
||||||
|
{
|
||||||
|
unsigned int vao = 0, vbo = 0, ebo = 0, size = 0;
|
||||||
|
|
||||||
|
glm::mat4 model_matrix {1.0f};
|
||||||
|
glm::mat4 colour_matrix {1.0f};
|
||||||
|
|
||||||
|
constexpr glmesh() { }
|
||||||
|
|
||||||
|
glmesh(glmesh&& o);
|
||||||
|
glmesh(const glmesh& o) = delete;
|
||||||
|
~glmesh();
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void uniform();
|
||||||
|
void set(const mesh& m, int mode);
|
||||||
|
void render();
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
|
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "mesh.hpp"
|
#include "mesh.hpp"
|
||||||
#include "arrays.hpp"
|
#include "arrays.hpp"
|
||||||
#include "../shader.hpp"
|
#include "../shader.hpp"
|
||||||
|
@ -9,71 +6,47 @@
|
||||||
|
|
||||||
using namespace sim::graphics;
|
using namespace sim::graphics;
|
||||||
|
|
||||||
constexpr static void init(mesh* m)
|
void mesh::add(const mesh& o, glm::mat4 mat)
|
||||||
{
|
{
|
||||||
if(m->vao != 0)
|
unsigned int off = vertices.size();
|
||||||
|
glm::mat3 mat3(mat);
|
||||||
|
|
||||||
|
vertices.reserve(vertices.size() + o.vertices.size());
|
||||||
|
indices.reserve(indices.size() + o.indices.size());
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < o.vertices.size(); i++)
|
||||||
{
|
{
|
||||||
return;
|
arrays::vertex v = o.vertices[i];
|
||||||
|
v.normal = v.normal * mat3;
|
||||||
|
v.pos = v.pos * mat;
|
||||||
|
vertices.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenVertexArrays(1, &m->vao);
|
for(unsigned int i = 0; i < o.indices.size(); i++)
|
||||||
glGenBuffers(1, &m->vbo);
|
{
|
||||||
glGenBuffers(1, &m->ebo);
|
indices.push_back(o.indices[i] + off);
|
||||||
|
}
|
||||||
glBindVertexArray(m->vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo);
|
|
||||||
|
|
||||||
arrays::vertex_attrib_pointers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh::mesh(mesh&& o)
|
void mesh::set_vertices(const arrays::vertex* data, size_t size)
|
||||||
{
|
{
|
||||||
vbo = o.vbo;
|
vertices.clear();
|
||||||
ebo = o.ebo;
|
vertices.reserve(size);
|
||||||
vao = o.vao;
|
|
||||||
size = o.size;
|
|
||||||
colour_matrix = o.colour_matrix;
|
|
||||||
model_matrix = o.model_matrix;
|
|
||||||
|
|
||||||
o.vbo = 0;
|
for(unsigned int i = 0; i < size; i++)
|
||||||
o.ebo = 0;
|
{
|
||||||
o.vao = 0;
|
vertices.push_back(data[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh::~mesh()
|
void mesh::set_indices(const unsigned int* data, size_t size)
|
||||||
{
|
{
|
||||||
if(vbo) glDeleteBuffers(1, &vbo);
|
indices.clear();
|
||||||
if(ebo) glDeleteBuffers(1, &ebo);
|
indices.reserve(size);
|
||||||
if(vao) glDeleteVertexArrays(1, &vao);
|
|
||||||
}
|
for(unsigned int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
void mesh::set_vertices(const arrays::vertex* data, size_t size, int mode)
|
indices.push_back(data[i]);
|
||||||
{
|
}
|
||||||
glBufferData(GL_ARRAY_BUFFER, size * sizeof(data[0]), data, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mesh::set_indices(const unsigned int* data, size_t size, int mode)
|
|
||||||
{
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(data[0]), data, mode);
|
|
||||||
this->size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mesh::bind()
|
|
||||||
{
|
|
||||||
init(this);
|
|
||||||
|
|
||||||
glm::mat4 m = camera::get_matrix() * model_matrix;
|
|
||||||
glUniformMatrix4fv(shader::gl_model, 1, false, &m[0][0]);
|
|
||||||
glUniformMatrix4fv(shader::gl_tex_mat, 1, false, &colour_matrix[0][0]);
|
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mesh::render()
|
|
||||||
{
|
|
||||||
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,35 +2,30 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <glm/matrix.hpp>
|
||||||
|
|
||||||
#include "arrays.hpp"
|
#include "arrays.hpp"
|
||||||
|
|
||||||
#include <glm/matrix.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace sim::graphics
|
namespace sim::graphics
|
||||||
{
|
{
|
||||||
|
|
||||||
struct mesh
|
struct mesh
|
||||||
{
|
{
|
||||||
unsigned int vao = 0, vbo = 0, ebo = 0, size = 0;
|
std::vector<arrays::vertex> vertices;
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
glm::mat4 model_matrix {1.0f};
|
|
||||||
glm::mat4 colour_matrix {1.0f};
|
|
||||||
|
|
||||||
constexpr mesh() { }
|
constexpr mesh() { }
|
||||||
|
|
||||||
mesh(mesh&& o);
|
void set_vertices(const arrays::vertex* data, size_t size);
|
||||||
mesh(const mesh& o) = delete;
|
void set_indices(const unsigned int* data, size_t size);
|
||||||
~mesh();
|
|
||||||
|
|
||||||
void bind();
|
|
||||||
void set_vertices(const arrays::vertex* data, size_t size, int mode);
|
|
||||||
void set_indices(const unsigned int* data, size_t size, int mode);
|
|
||||||
void load_model(std::string base, std::string path);
|
void load_model(std::string base, std::string path);
|
||||||
void load_model(std::string path) { load_model(".", path); }
|
void load_model(std::string path) { load_model(".", path); }
|
||||||
void load_text(const char* text, double size);
|
void load_text(const char* text, double size);
|
||||||
void render();
|
void add(const mesh& o, glm::mat4 mat);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void load_text(const char* header, T& item, double size)
|
void load_text(const char* header, T& item, double size)
|
||||||
|
|
|
@ -64,6 +64,7 @@ static void proc_mesh(proc_state& state, glm::mat4 mat, aiMesh* mesh, const aiSc
|
||||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
unsigned int handle = proc_texture(state, material, scene);
|
unsigned int handle = proc_texture(state, material, scene);
|
||||||
unsigned int offset = state.offset;
|
unsigned int offset = state.offset;
|
||||||
|
glm::mat3 mat3(mat);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +77,7 @@ static void proc_mesh(proc_state& state, glm::mat4 mat, aiMesh* mesh, const aiSc
|
||||||
if(mesh->HasNormals())
|
if(mesh->HasNormals())
|
||||||
{
|
{
|
||||||
auto [x, y, z] = mesh->mNormals[i];
|
auto [x, y, z] = mesh->mNormals[i];
|
||||||
vertex.normal = glm::vec3(x, y, z) * glm::mat3(mat);
|
vertex.normal = glm::vec3(x, y, z) * mat3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mesh->mTextureCoords[0])
|
if(mesh->mTextureCoords[0])
|
||||||
|
@ -165,7 +166,7 @@ void mesh::load_model(std::string base, std::string filename)
|
||||||
|
|
||||||
proc_node(state, glm::mat4(1), scene->mRootNode, scene);
|
proc_node(state, glm::mat4(1), scene->mRootNode, scene);
|
||||||
|
|
||||||
set_vertices(&state.vertices[0], state.vertices.size(), GL_STATIC_DRAW);
|
set_vertices(&state.vertices[0], state.vertices.size());
|
||||||
set_indices(&state.indices[0], state.indices.size(), GL_STATIC_DRAW);
|
set_indices(&state.indices[0], state.indices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "core.hpp"
|
#include "core.hpp"
|
||||||
#include "../locations.hpp"
|
#include "../locations.hpp"
|
||||||
|
|
||||||
|
@ -14,7 +17,7 @@ core::core()
|
||||||
|
|
||||||
void core::init()
|
void core::init()
|
||||||
{
|
{
|
||||||
mesh1.model_matrix = mesh2.model_matrix = locations::monitors[2];
|
mesh1.model_matrix = locations::monitors[2];
|
||||||
mesh1.colour_matrix = {
|
mesh1.colour_matrix = {
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
|
@ -22,23 +25,57 @@ void core::init()
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
std::stringstream ss;
|
sim::graphics::mesh rmesh1, rmesh2;
|
||||||
|
|
||||||
ss << "Reactor Core";
|
rmesh1.load_text("Reactor Core", 0.04);
|
||||||
|
rmesh2.load_model("../assets/model/", "reactor_core_interface_circle.stl");
|
||||||
|
rmesh1.add(rmesh2, glm::mat4(1));
|
||||||
|
|
||||||
mesh1.bind();
|
mesh1.bind();
|
||||||
mesh1.load_text(ss.str().c_str(), 0.05);
|
mesh1.set(rmesh1, GL_STATIC_DRAW);
|
||||||
|
rmesh2.load_model("../assets/model/", "reactor_core_interface_cell.stl");
|
||||||
mesh2.bind();
|
mesh2.bind();
|
||||||
mesh2.load_model("../assets/model/", "reactor_core_interface.stl");
|
mesh2.set(rmesh2, GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core::update(sim::system& sys)
|
void core::render(sim::system& sys)
|
||||||
{
|
{
|
||||||
}
|
double step = 1 / (sys.vessel->diameter / sys.reactor->cell_width * 0.8);
|
||||||
|
double sx = 0.5 - (sys.reactor->width - 1) * step / 2.0;
|
||||||
void core::render()
|
double sy = 0.5 - (sys.reactor->height - 1) * step / 2.0;
|
||||||
{
|
|
||||||
mesh1.bind(); mesh1.render();
|
glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.5, step * 0.5, 1));
|
||||||
mesh2.bind(); mesh2.render();
|
|
||||||
|
mesh1.bind();
|
||||||
|
mesh1.uniform();
|
||||||
|
mesh1.render();
|
||||||
|
mesh2.bind();
|
||||||
|
|
||||||
|
for(int i = 0; i < sys.reactor->size; i++)
|
||||||
|
{
|
||||||
|
int x = i % sys.reactor->width;
|
||||||
|
int y = i / sys.reactor->width;
|
||||||
|
double ox = sx + x * step;
|
||||||
|
double oy = sy + y * step;
|
||||||
|
|
||||||
|
reactor::rod* r = sys.reactor->rods[i].get();
|
||||||
|
glm::vec4 colour = r->get_colour();
|
||||||
|
|
||||||
|
if(!r->should_display() || colour[3] == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh2.model_matrix = mesh1.model_matrix * glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale;
|
||||||
|
mesh2.colour_matrix = glm::mat4({
|
||||||
|
colour[0], colour[1], colour[2], colour[3],
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0
|
||||||
|
});
|
||||||
|
|
||||||
|
mesh2.uniform();
|
||||||
|
mesh2.render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../mesh/mesh.hpp"
|
#include "../mesh/glmesh.hpp"
|
||||||
#include "../../system.hpp"
|
#include "../../system.hpp"
|
||||||
|
|
||||||
namespace sim::graphics::monitor
|
namespace sim::graphics::monitor
|
||||||
|
@ -9,14 +9,13 @@ namespace sim::graphics::monitor
|
||||||
|
|
||||||
class core
|
class core
|
||||||
{
|
{
|
||||||
sim::graphics::mesh mesh1, mesh2;
|
sim::graphics::glmesh mesh1, mesh2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
core();
|
core();
|
||||||
void init();
|
void init();
|
||||||
void update(sim::system& sys);
|
void render(sim::system& sys);
|
||||||
void render();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "vessel.hpp"
|
#include "vessel.hpp"
|
||||||
|
#include "../../reactor/rod.hpp"
|
||||||
|
#include "../../reactor/control/boron_rod.hpp"
|
||||||
#include "../locations.hpp"
|
#include "../locations.hpp"
|
||||||
|
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
@ -15,7 +20,7 @@ vessel::vessel()
|
||||||
void vessel::init()
|
void vessel::init()
|
||||||
{
|
{
|
||||||
mesh1.model_matrix = locations::monitors[1];
|
mesh1.model_matrix = locations::monitors[1];
|
||||||
mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(3.0 / 8.0, 0, 0));
|
mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(0.5, 0, 0));
|
||||||
|
|
||||||
mesh1.colour_matrix = mesh2.colour_matrix = {
|
mesh1.colour_matrix = mesh2.colour_matrix = {
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
|
@ -25,36 +30,88 @@ void vessel::init()
|
||||||
};
|
};
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
sim::graphics::mesh rmesh;
|
||||||
|
|
||||||
ss << "Reactor Vessel\n\n";
|
ss << "Reactor Vessel\n\n";
|
||||||
ss << "Heat\n";
|
ss << "Heat\n";
|
||||||
ss << "Steam\n";
|
ss << "Steam\n";
|
||||||
ss << "Pressure\n";
|
ss << "Pressure\n";
|
||||||
ss << "Level\n";
|
ss << "Level\n";
|
||||||
ss << "Void Ratio\n";
|
ss << "Void Ratio\n\n\n\n";
|
||||||
|
ss << "Reactor Core\n\n";
|
||||||
|
ss << "Temperature\nMin\nMax\n\n";
|
||||||
|
ss << "Neutron Flux\nSlow\nFast\n\n";
|
||||||
|
ss << "Control Rods\nMin\nMax\n\n";
|
||||||
|
|
||||||
|
rmesh.load_text(ss.str().c_str(), 0.04);
|
||||||
mesh1.bind();
|
mesh1.bind();
|
||||||
mesh1.load_text(ss.str().c_str(), 0.05);
|
mesh1.set(rmesh, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double show(double v)
|
||||||
|
{
|
||||||
|
return std::round(v * 1e3) * 1e-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vessel::update(sim::system& sys)
|
void vessel::update(sim::system& sys)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
sim::graphics::mesh rmesh;
|
||||||
|
|
||||||
|
double temp_min, temp_max;
|
||||||
|
double crod_min = INFINITY, crod_max = -INFINITY;
|
||||||
|
|
||||||
|
sys.reactor->get_stats(sim::reactor::rod::val_t::HEAT, temp_min, temp_max);
|
||||||
|
|
||||||
|
for(int i = 0; i < sys.reactor->size; i++)
|
||||||
|
{
|
||||||
|
sim::reactor::rod* r = sys.reactor->rods[i].get();
|
||||||
|
|
||||||
|
if(r->get_id() != 5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto br = (sim::reactor::control::boron_rod*)r;
|
||||||
|
double v = br->get_inserted();
|
||||||
|
|
||||||
|
if(v > crod_max)
|
||||||
|
{
|
||||||
|
crod_max = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v < crod_min)
|
||||||
|
{
|
||||||
|
crod_min = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ss << "\n\n";
|
ss << "\n\n";
|
||||||
ss << sys.vessel.get_heat() << " C\n";
|
ss << show( sys.vessel->get_heat() ) << " C\n";
|
||||||
ss << sys.vessel.get_steam() << " g\n";
|
ss << show( sys.vessel->get_steam() ) << " g\n";
|
||||||
ss << (sys.vessel.get_pressure() * 0.001) << " kPa\n";
|
ss << show( sys.vessel->get_pressure() * 0.001 ) << " kPa\n";
|
||||||
ss << sys.vessel.get_level() << " / " << sys.vessel.get_volume() << " L\n";
|
ss << show( sys.vessel->get_level() ) << " / " << show( sys.vessel->get_volume() ) << " L\n";
|
||||||
ss << (sys.vessel.get_void_ratio() * 100) << " %\n";
|
ss << show( sys.vessel->get_void_ratio() * 100 ) << " %\n\n\n\n\n\n\n";
|
||||||
|
ss << show( temp_min ) << " C\n";
|
||||||
|
ss << show( temp_max ) << " C\n\n\n";
|
||||||
|
ss << sys.reactor->get_total(sim::reactor::rod::val_t::N_SLOW) << " mol\n";
|
||||||
|
ss << sys.reactor->get_total(sim::reactor::rod::val_t::N_FAST) << " mol\n\n\n";
|
||||||
|
ss << show( crod_min * 100 ) << " %\n";
|
||||||
|
ss << show( crod_max * 100 ) << " %\n";
|
||||||
|
|
||||||
|
rmesh.load_text(ss.str().c_str(), 0.04);
|
||||||
mesh2.bind();
|
mesh2.bind();
|
||||||
mesh2.load_text(ss.str().c_str(), 0.05);
|
mesh2.set(rmesh, GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vessel::render()
|
void vessel::render()
|
||||||
{
|
{
|
||||||
mesh1.bind(); mesh1.render();
|
mesh1.bind();
|
||||||
mesh2.bind(); mesh2.render();
|
mesh1.uniform();
|
||||||
|
mesh1.render();
|
||||||
|
|
||||||
|
mesh2.bind();
|
||||||
|
mesh2.uniform();
|
||||||
|
mesh2.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../mesh/mesh.hpp"
|
#include "../mesh/glmesh.hpp"
|
||||||
#include "../../system.hpp"
|
#include "../../system.hpp"
|
||||||
|
|
||||||
namespace sim::graphics::monitor
|
namespace sim::graphics::monitor
|
||||||
|
@ -9,7 +9,7 @@ namespace sim::graphics::monitor
|
||||||
|
|
||||||
class vessel
|
class vessel
|
||||||
{
|
{
|
||||||
sim::graphics::mesh mesh1, mesh2;
|
sim::graphics::glmesh mesh1, mesh2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ using namespace sim::graphics;
|
||||||
static GLFWwindow* win;
|
static GLFWwindow* win;
|
||||||
static bool win_should_close = false;
|
static bool win_should_close = false;
|
||||||
|
|
||||||
static mesh MeshScene;
|
static glmesh MeshScene;
|
||||||
static monitor::vessel MonitorVessel;
|
static monitor::vessel MonitorVessel;
|
||||||
static monitor::core MonitorCore;
|
static monitor::core MonitorCore;
|
||||||
|
|
||||||
|
@ -96,9 +96,11 @@ void window::create()
|
||||||
font::init();
|
font::init();
|
||||||
|
|
||||||
shader::init_program();
|
shader::init_program();
|
||||||
|
mesh rmesh;
|
||||||
|
|
||||||
|
rmesh.load_model("../assets", "scene-baked.glb");
|
||||||
MeshScene.bind();
|
MeshScene.bind();
|
||||||
MeshScene.load_model("../assets", "scene-baked.glb");
|
MeshScene.set(rmesh, GL_STATIC_DRAW);
|
||||||
|
|
||||||
MonitorCore.init();
|
MonitorCore.init();
|
||||||
MonitorVessel.init();
|
MonitorVessel.init();
|
||||||
|
@ -109,7 +111,6 @@ void window::create()
|
||||||
|
|
||||||
void window::loop(sim::system& sys)
|
void window::loop(sim::system& sys)
|
||||||
{
|
{
|
||||||
MonitorCore.update(sys);
|
|
||||||
MonitorVessel.update(sys);
|
MonitorVessel.update(sys);
|
||||||
|
|
||||||
glm::mat4 mat_projection = glm::perspective(glm::radians(80.0f), resize::get_aspect(), 0.01f, 20.f);
|
glm::mat4 mat_projection = glm::perspective(glm::radians(80.0f), resize::get_aspect(), 0.01f, 20.f);
|
||||||
|
@ -118,9 +119,11 @@ void window::loop(sim::system& sys)
|
||||||
glClearColor(0, 0, 0, 1.0f);
|
glClearColor(0, 0, 0, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
MeshScene.bind(); MeshScene.render();
|
MeshScene.bind();
|
||||||
|
MeshScene.uniform();
|
||||||
|
MeshScene.render();
|
||||||
|
|
||||||
MonitorCore.render();
|
MonitorCore.render(sys);
|
||||||
MonitorVessel.render();
|
MonitorVessel.render();
|
||||||
|
|
||||||
glfwSwapBuffers(win);
|
glfwSwapBuffers(win);
|
||||||
|
|
|
@ -27,7 +27,7 @@ unsigned long get_now()
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
graphics::window::create();
|
graphics::window::create();
|
||||||
sim::system sys(system::generate());
|
sim::system sys;
|
||||||
|
|
||||||
long clock = get_now();
|
long clock = get_now();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
|
||||||
#include "builder.hpp"
|
#include "builder.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace sim::reactor;
|
using namespace sim::reactor;
|
||||||
|
|
||||||
sim::reactor::reactor sim::reactor::builder(const int W, const int H, fuel::fuel_rod fr, control::control_rod cr, coolant::pipe p, const char** lines)
|
sim::reactor::reactor sim::reactor::builder(const int W, const int H, const double CW, const double CH, fuel::fuel_rod fr, control::boron_rod br, coolant::vessel& v, const char** lines)
|
||||||
{
|
{
|
||||||
std::unique_ptr<rod> arr[W * H];
|
std::vector<std::unique_ptr<rod>> arr(W * H);
|
||||||
|
|
||||||
for(int y = 0; y < H; y++)
|
for(int y = 0; y < H; y++)
|
||||||
for(int x = 0; x < W; x++)
|
for(int x = 0; x < W; x++)
|
||||||
|
@ -19,7 +22,7 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, fuel::fuel
|
||||||
r = new fuel::fuel_rod(fr);
|
r = new fuel::fuel_rod(fr);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
r = new control::control_rod(cr);
|
r = new control::boron_rod(br);
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
r = new control::graphite_rod();
|
r = new control::graphite_rod();
|
||||||
|
@ -27,10 +30,10 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, fuel::fuel
|
||||||
case 'H':
|
case 'H':
|
||||||
r = new coolant::heater();
|
r = new coolant::heater();
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case 'P':
|
||||||
r = new coolant::pipe(p);
|
r = new coolant::pipe(v);
|
||||||
break;
|
break;
|
||||||
case '#':
|
case ' ':
|
||||||
r = new rod();
|
r = new rod();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +41,6 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, fuel::fuel
|
||||||
arr[y * W + x] = std::unique_ptr<rod>(std::move(r));
|
arr[y * W + x] = std::unique_ptr<rod>(std::move(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
return reactor(arr, W, H);
|
return reactor(&arr[0], W, H, CW, CH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
|
|
||||||
#include "rod.hpp"
|
#include "rod.hpp"
|
||||||
#include "fuel/fuel_rod.hpp"
|
#include "fuel/fuel_rod.hpp"
|
||||||
#include "control/control_rod.hpp"
|
#include "control/boron_rod.hpp"
|
||||||
#include "control/graphite_rod.hpp"
|
#include "control/graphite_rod.hpp"
|
||||||
#include "coolant/pipe.hpp"
|
#include "coolant/pipe.hpp"
|
||||||
#include "coolant/heater.hpp"
|
#include "coolant/heater.hpp"
|
||||||
|
#include "coolant/vessel.hpp"
|
||||||
#include "reactor.hpp"
|
#include "reactor.hpp"
|
||||||
|
|
||||||
namespace sim::reactor
|
namespace sim::reactor
|
||||||
{
|
{
|
||||||
|
|
||||||
reactor builder(const int W, const int H, fuel::fuel_rod fr, control::control_rod cr, coolant::pipe p, const char** lines);
|
reactor builder(const int W, const int H, const double CW, const double CH, fuel::fuel_rod fr, control::boron_rod br, coolant::vessel& v, const char** lines);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
#include "boron_rod.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace sim::reactor::control;
|
||||||
|
|
||||||
|
constexpr double boron_density = 2340000; // g/m^3
|
||||||
|
constexpr double boron_molar_mass = 10; // g/mol
|
||||||
|
constexpr double boron_molar_density = boron_density / boron_molar_mass; // mol/m^3
|
||||||
|
|
||||||
|
boron_rod::boron_rod(coolant::vessel& v, double max) : coolant::pipe(v), max(max)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void boron_rod::display(std::ostream& o) const
|
||||||
|
{
|
||||||
|
double limit = get_volume() * boron_molar_density;
|
||||||
|
|
||||||
|
o << "Inserted: " << (inserted * 100) << "%\n";
|
||||||
|
o << "Use: " << (absorbed * limit) << " / " << limit << "\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
void boron_rod::set_reactivity(double a)
|
||||||
|
{
|
||||||
|
inserted = 1 - a;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec4 boron_rod::get_colour() const
|
||||||
|
{
|
||||||
|
double v = inserted * 0.75 + 0.25;
|
||||||
|
return {v, v, v, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
void boron_rod::update(double secs)
|
||||||
|
{
|
||||||
|
double limit = get_volume() * boron_molar_density;
|
||||||
|
|
||||||
|
update_rod(secs);
|
||||||
|
|
||||||
|
double k = (1 - absorbed) * inserted * max;
|
||||||
|
double m = 1 - std::pow(0.5, secs * -std::log2(1 - k));
|
||||||
|
double r_fast = vals[val_t::N_FAST] * m;
|
||||||
|
double r_slow = vals[val_t::N_SLOW] * m;
|
||||||
|
|
||||||
|
vals[val_t::N_FAST] -= r_fast;
|
||||||
|
vals[val_t::N_SLOW] -= r_slow;
|
||||||
|
absorbed += (r_fast + r_slow) / limit;
|
||||||
|
|
||||||
|
update_pipe(secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void boron_rod::update_selected(double a)
|
||||||
|
{
|
||||||
|
inserted += a;
|
||||||
|
|
||||||
|
if(inserted > 1) inserted = 1;
|
||||||
|
if(inserted < 0) inserted = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -6,25 +6,26 @@
|
||||||
namespace sim::reactor::control
|
namespace sim::reactor::control
|
||||||
{
|
{
|
||||||
|
|
||||||
class control_rod : public sim::reactor::coolant::pipe
|
class boron_rod : public sim::reactor::coolant::pipe
|
||||||
{
|
{
|
||||||
const double limit;
|
|
||||||
const double max;
|
const double max;
|
||||||
|
|
||||||
double inserted = 1;
|
double inserted = 1;
|
||||||
double absorbed = 0;
|
double absorbed = 0;
|
||||||
|
|
||||||
virtual void display(std::ostream& o) const;
|
virtual void display(std::ostream& o) const;
|
||||||
|
virtual const char* get_name() const { return "Boron Control Rod"; }
|
||||||
virtual const char* get_name() const { return "Control Rod"; }
|
virtual rod* clone() const { return new boron_rod(*this); }
|
||||||
virtual rod* clone() const { return new control_rod(*this); };
|
virtual glm::vec4 get_colour() const;
|
||||||
|
virtual int get_id() const { return 5; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
control_rod(coolant::vessel& v, double limit, double max);
|
boron_rod(coolant::vessel& v, double max);
|
||||||
|
|
||||||
virtual void update(double secs);
|
virtual void update(double secs);
|
||||||
void set_reactivity(double a);
|
void set_reactivity(double a);
|
||||||
|
double get_inserted() { return inserted; }
|
||||||
|
|
||||||
virtual bool should_display() const { return true; }
|
virtual bool should_display() const { return true; }
|
||||||
virtual bool should_select() const { return true; }
|
virtual bool should_select() const { return true; }
|
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
#include "control_rod.hpp"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace sim::reactor::control;
|
|
||||||
|
|
||||||
control_rod::control_rod(coolant::vessel& v, double limit, double max) : coolant::pipe(v), limit(limit), max(max)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void control_rod::display(std::ostream& o) const
|
|
||||||
{
|
|
||||||
o << "Inserted: " << (inserted * 100) << "%\n";
|
|
||||||
o << "Use: " << absorbed << " / " << limit << " mol\n";
|
|
||||||
};
|
|
||||||
|
|
||||||
void control_rod::set_reactivity(double a)
|
|
||||||
{
|
|
||||||
inserted = 1 - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void control_rod::update(double secs)
|
|
||||||
{
|
|
||||||
update_rod(secs);
|
|
||||||
|
|
||||||
double k = (1 - absorbed / limit) * inserted * max;
|
|
||||||
double m = 1 - std::pow(0.5, secs * -std::log2(1 - k));
|
|
||||||
double r_fast = vals[val_t::N_FAST] * m;
|
|
||||||
double r_slow = vals[val_t::N_SLOW] * m;
|
|
||||||
|
|
||||||
vals[val_t::N_FAST] -= r_fast;
|
|
||||||
vals[val_t::N_SLOW] -= r_slow;
|
|
||||||
absorbed += r_fast + r_slow;
|
|
||||||
|
|
||||||
update_pipe(secs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void control_rod::update_selected(double a)
|
|
||||||
{
|
|
||||||
inserted += a;
|
|
||||||
|
|
||||||
if(inserted > 1) inserted = 1;
|
|
||||||
if(inserted < 0) inserted = 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,12 @@ void graphite_rod::display(std::ostream& o) const
|
||||||
o << "Inserted: " << (inserted * 100) << "%\n";
|
o << "Inserted: " << (inserted * 100) << "%\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
glm::vec4 graphite_rod::get_colour() const
|
||||||
|
{
|
||||||
|
double v = inserted * 0.75 + 0.25;
|
||||||
|
return {v, v, v, 1};
|
||||||
|
}
|
||||||
|
|
||||||
double graphite_rod::get_k(val_t type) const
|
double graphite_rod::get_k(val_t type) const
|
||||||
{
|
{
|
||||||
if(type == val_t::HEAT) return 0.5;
|
if(type == val_t::HEAT) return 0.5;
|
||||||
|
|
|
@ -11,10 +11,13 @@ class graphite_rod : public sim::reactor::rod
|
||||||
double inserted = 0;
|
double inserted = 0;
|
||||||
|
|
||||||
virtual void display(std::ostream& o) const;
|
virtual void display(std::ostream& o) const;
|
||||||
|
|
||||||
virtual const char* get_name() const { return "Graphite Rod"; }
|
virtual const char* get_name() const { return "Graphite Rod"; }
|
||||||
virtual rod* clone() const { return new graphite_rod(*this); };
|
virtual rod* clone() const { return new graphite_rod(*this); };
|
||||||
virtual double get_k(val_t type) const;
|
virtual double get_k(val_t type) const;
|
||||||
|
virtual glm::vec4 get_colour() const;
|
||||||
|
virtual int get_id() const { return 4; }
|
||||||
|
|
||||||
|
double get_inserted() { return inserted; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,11 @@ class heater : public sim::reactor::rod
|
||||||
|
|
||||||
virtual void display(std::ostream& o) const;
|
virtual void display(std::ostream& o) const;
|
||||||
|
|
||||||
|
virtual bool has_sensors(val_t t) const { return true; }
|
||||||
virtual const char* get_name() const { return "Heater"; }
|
virtual const char* get_name() const { return "Heater"; }
|
||||||
virtual double get_k(val_t type) const { return 0.5; }
|
virtual double get_k(val_t type) const { return 0.5; }
|
||||||
virtual rod* clone() const { return new heater(*this); };
|
virtual rod* clone() const { return new heater(*this); };
|
||||||
|
virtual int get_id() const { return 3; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "pipe.hpp"
|
#include "pipe.hpp"
|
||||||
|
#include "../reactor.hpp"
|
||||||
|
|
||||||
using namespace sim::reactor::coolant;
|
using namespace sim::reactor::coolant;
|
||||||
|
|
||||||
|
@ -22,7 +23,10 @@ void pipe::update(double secs)
|
||||||
|
|
||||||
void pipe::update_pipe(double secs)
|
void pipe::update_pipe(double secs)
|
||||||
{
|
{
|
||||||
vals[val_t::HEAT] = vessel->add_heat(vals[val_t::HEAT]);
|
sim::reactor::reactor* r = (sim::reactor::reactor*)reactor;
|
||||||
|
double m = r->cell_width * r->cell_width * r->cell_height * 1e6;
|
||||||
|
|
||||||
|
vals[val_t::HEAT] = vessel->add_heat(m, vals[val_t::HEAT]);
|
||||||
vals[val_t::N_SLOW] += vals[val_t::N_FAST];
|
vals[val_t::N_SLOW] += vals[val_t::N_FAST];
|
||||||
vals[val_t::N_FAST] = 0;
|
vals[val_t::N_FAST] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ protected:
|
||||||
virtual double get_k(sim::reactor::rod::val_t type) const;
|
virtual double get_k(sim::reactor::rod::val_t type) const;
|
||||||
virtual const char* get_name() const { return "Coolant"; }
|
virtual const char* get_name() const { return "Coolant"; }
|
||||||
virtual rod* clone() const { return new pipe(*this); };
|
virtual rod* clone() const { return new pipe(*this); };
|
||||||
|
virtual int get_id() const { return 2; }
|
||||||
|
|
||||||
void update_pipe(double secs);
|
void update_pipe(double secs);
|
||||||
|
|
||||||
|
|
|
@ -65,15 +65,15 @@ void vessel::update(double secs)
|
||||||
steam_suspended *= fuel::half_life::get(secs, bubble_hl);
|
steam_suspended *= fuel::half_life::get(secs, bubble_hl);
|
||||||
}
|
}
|
||||||
|
|
||||||
double vessel::add_heat(double t1)
|
double vessel::add_heat(double m1, double t1)
|
||||||
{
|
{
|
||||||
double t2 = get_heat();
|
double t2 = get_heat();
|
||||||
double t = t1 - t2;
|
double t = t1 - t2;
|
||||||
double m1 = 1e6;
|
|
||||||
double m2 = (fluid.l_to_g(level) + steam) * fluid.jPgk;
|
double m2 = (fluid.l_to_g(level) + steam) * fluid.jPgk;
|
||||||
double m = m1 + m2;
|
double m = m1 + m2;
|
||||||
|
|
||||||
return heat = t1 - t * m2 / m;
|
heat = t1 - t * m2 / m;
|
||||||
|
return heat;
|
||||||
}
|
}
|
||||||
|
|
||||||
double vessel::add_fluid(double m2, double t2)
|
double vessel::add_fluid(double m2, double t2)
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace sim::reactor::coolant
|
||||||
class vessel
|
class vessel
|
||||||
{
|
{
|
||||||
double level; // litres
|
double level; // litres
|
||||||
double heat = 0; // celcius
|
double heat = 0; // celsius
|
||||||
double steam = 0; // grams
|
double steam = 0; // grams
|
||||||
double steam_suspended = 0; // grams
|
double steam_suspended = 0; // grams
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public:
|
||||||
vessel(double height, double diameter, double level, sim::coolant::fluid_t fluid);
|
vessel(double height, double diameter, double level, sim::coolant::fluid_t fluid);
|
||||||
|
|
||||||
void update(double secs);
|
void update(double secs);
|
||||||
double add_heat(double amount);
|
double add_heat(double m, double t);
|
||||||
double add_fluid(double amount, double heat);
|
double add_fluid(double amount, double heat);
|
||||||
double extract_steam(double dt, double a, double p2);
|
double extract_steam(double dt, double a, double p2);
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,87 @@
|
||||||
|
|
||||||
#include "fuel_rod.hpp"
|
#include "fuel_rod.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
using namespace sim::reactor::fuel;
|
using namespace sim::reactor::fuel;
|
||||||
|
|
||||||
fuel_rod::fuel_rod(double fuel, double mass) : s(fuel, mass)
|
constexpr double fuel_density = 19100000; // g/m^3
|
||||||
|
constexpr double fuel_molar_mass = 238.029; // g/mol
|
||||||
|
constexpr double fuel_molar_density = fuel_density / fuel_molar_mass; // mol/m^3
|
||||||
|
constexpr double energy_density = 165e11; // J/mol
|
||||||
|
|
||||||
|
fuel_rod::fuel_rod(double fuel) : s(fuel)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuel_rod::display(std::ostream& o) const
|
void fuel_rod::display(std::ostream& o) const
|
||||||
{
|
{
|
||||||
o << "Fuel: " << s.get_fuel() << " / " << s.get_mass() << " mol\n";
|
double mol = fuel_molar_density * get_volume();
|
||||||
|
|
||||||
|
o << "Fuel: " << (s.get_fuel() * mol) << " / " << (s.get_mass() * mol) << " mol\n";
|
||||||
o << "Efficiency: " << (s.get_efficiency() * 100) << " %\n";
|
o << "Efficiency: " << (s.get_efficiency() * 100) << " %\n";
|
||||||
o << "Output: " << s.get_energy() << " W/s\n";
|
o << "Output: " << (s.get_energy() * mol * energy_density) << " W/s\n";
|
||||||
o << "Iodine: " << s.get_i_135() << " mol\n";
|
o << "Iodine: " << (s.get_i_135() * mol) << " mol\n";
|
||||||
o << "Xenon: " << s.get_xe_135() << " mol\n";
|
o << "Xenon: " << (s.get_xe_135() * mol) << " mol\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static float map(float v, float imin, float imax, float omin, float omax)
|
||||||
|
{
|
||||||
|
return (v - imin) * (omax - omin) / (imax - imin) + omin;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec4 fuel_rod::get_colour() const
|
||||||
|
{
|
||||||
|
double temp = vals[val_t::HEAT];
|
||||||
|
|
||||||
|
if(temp < 0)
|
||||||
|
{
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should not happen
|
||||||
|
if(std::isnan(temp))
|
||||||
|
{
|
||||||
|
return {1, 0, 1, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp < 120)
|
||||||
|
{
|
||||||
|
return {0, map(temp, 0, 120, 0, 1), 1, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp < 240)
|
||||||
|
{
|
||||||
|
return {0, 1, map(temp, 120, 240, 1, 0), 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp < 280)
|
||||||
|
{
|
||||||
|
return {map(temp, 240, 280, 0, 1), 1, 0, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp < 320)
|
||||||
|
{
|
||||||
|
return {1, map(temp, 280, 320, 1, 0), 0, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {1, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuel_rod::update(double secs)
|
void fuel_rod::update(double secs)
|
||||||
{
|
{
|
||||||
update_rod(secs);
|
update_rod(secs);
|
||||||
|
|
||||||
|
double mol = fuel_molar_density * get_volume();
|
||||||
|
|
||||||
s.clear_energy();
|
s.clear_energy();
|
||||||
s.clear_fast_neutrons();
|
s.clear_fast_neutrons();
|
||||||
s.add_slow_neutrons(vals[val_t::N_SLOW]);
|
s.add_slow_neutrons(vals[val_t::N_SLOW] / mol);
|
||||||
s.update(secs);
|
s.update(secs);
|
||||||
|
|
||||||
vals[val_t::HEAT] += s.get_energy() * secs;
|
vals[val_t::HEAT] += s.get_energy() * mol * energy_density * secs;
|
||||||
vals[val_t::N_FAST] += s.get_fast_neutrons();
|
vals[val_t::N_FAST] += s.get_fast_neutrons() * mol;
|
||||||
vals[val_t::N_SLOW] = 0;
|
vals[val_t::N_SLOW] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,17 @@ class fuel_rod : public sim::reactor::rod
|
||||||
virtual double get_k(val_t type) const { return 0.5; }
|
virtual double get_k(val_t type) const { return 0.5; }
|
||||||
virtual void display(std::ostream& o) const;
|
virtual void display(std::ostream& o) const;
|
||||||
|
|
||||||
|
virtual bool has_sensors(val_t t) const { return true; }
|
||||||
virtual const char* get_name() const { return "Fuel"; }
|
virtual const char* get_name() const { return "Fuel"; }
|
||||||
virtual rod* clone() const { return new fuel_rod(*this); };
|
virtual rod* clone() const { return new fuel_rod(*this); };
|
||||||
|
virtual int get_id() const { return 1; }
|
||||||
|
virtual glm::vec4 get_colour() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
fuel_rod(double fuel, double mass);
|
fuel_rod(double fuel);
|
||||||
|
|
||||||
virtual bool should_display() const { return true; }
|
virtual bool should_display() const { return true; }
|
||||||
|
|
||||||
virtual void update(double secs);
|
virtual void update(double secs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
|
|
||||||
using namespace sim::reactor::fuel;
|
using namespace sim::reactor::fuel;
|
||||||
|
|
||||||
static const double NEUTRON_BG = 1e-10;
|
static const double NEUTRON_BG = 1e-25;
|
||||||
|
|
||||||
sample::sample(double fuel, double mass)
|
sample::sample(double fuel)
|
||||||
{
|
{
|
||||||
this->fuel = fuel;
|
this->fuel = fuel;
|
||||||
this->mass = mass;
|
this->mass = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sample::update(double secs)
|
void sample::update(double secs)
|
||||||
|
@ -21,7 +21,7 @@ void sample::update(double secs)
|
||||||
// decay waste and extract products
|
// decay waste and extract products
|
||||||
waste.update(secs);
|
waste.update(secs);
|
||||||
fast_neutrons += waste.extract_neutrons();
|
fast_neutrons += waste.extract_neutrons();
|
||||||
energy += waste.extract_energy();
|
energy += waste.extract_energy() * (1.0 / 30.0);
|
||||||
|
|
||||||
// decay Xe-135
|
// decay Xe-135
|
||||||
m = half_life::get(secs, half_life::Xe_135);
|
m = half_life::get(secs, half_life::Xe_135);
|
||||||
|
@ -59,7 +59,7 @@ void sample::update(double secs)
|
||||||
efficiency = neutrons_fuel / neutrons_total;
|
efficiency = neutrons_fuel / neutrons_total;
|
||||||
|
|
||||||
// simulate fuel use
|
// simulate fuel use
|
||||||
energy += neutrons_fuel / secs;
|
energy += neutrons_fuel / secs * 0.8;
|
||||||
waste.add_fissile(neutrons_fuel * 6);
|
waste.add_fissile(neutrons_fuel * 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class sample
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
sample(double fuel, double mass);
|
sample(double fuel);
|
||||||
|
|
||||||
void update(double secs);
|
void update(double secs);
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,25 @@
|
||||||
|
|
||||||
using namespace sim::reactor;
|
using namespace sim::reactor;
|
||||||
|
|
||||||
reactor::reactor(std::unique_ptr<rod>* rods, int width, int height) : width(width), height(height), size(width * height)
|
reactor::reactor(std::unique_ptr<rod>* rods, int w, int h, double cw, double ch) : cell_width(cw), cell_height(ch), width(w), height(h), size(w * h)
|
||||||
{
|
{
|
||||||
this->rods = new std::unique_ptr<rod>[width * height];
|
this->rods = new std::unique_ptr<rod>[width * height];
|
||||||
|
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
this->rods[i] = std::move(rods[i]);
|
this->rods[i] = std::move(rods[i]);
|
||||||
|
this->rods[i]->reactor = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reactor::reactor(reactor&& o) : width(o.width), height(o.height), size(o.size)
|
reactor::reactor(reactor&& o) : cell_width(o.cell_width), cell_height(o.cell_height), width(o.width), height(o.height), size(o.size)
|
||||||
{
|
{
|
||||||
rods = o.rods;
|
rods = o.rods;
|
||||||
cursor = o.cursor;
|
cursor = o.cursor;
|
||||||
o.rods = nullptr;
|
o.rods = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
reactor::reactor(const reactor& o) : width(o.width), height(o.height), size(o.size)
|
reactor::reactor(const reactor& o) : cell_width(o.cell_width), cell_height(o.cell_height), width(o.width), height(o.height), size(o.size)
|
||||||
{
|
{
|
||||||
rods = new std::unique_ptr<rod>[width * height];
|
rods = new std::unique_ptr<rod>[width * height];
|
||||||
|
|
||||||
|
@ -132,3 +133,35 @@ void reactor::update_interactions(int* rods_lookup, double secs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double reactor::get_total(rod::val_t type)
|
||||||
|
{
|
||||||
|
double v = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
v += rods[i]->get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reactor::get_stats(rod::val_t type, double& min, double& max)
|
||||||
|
{
|
||||||
|
min = INFINITY;
|
||||||
|
max = -INFINITY;
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if(!rods[i]->has_sensors(type))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double v = rods[i]->get(type);
|
||||||
|
|
||||||
|
if(v > max) max = v;
|
||||||
|
if(v < min) min = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace sim::reactor
|
||||||
|
|
||||||
struct reactor
|
struct reactor
|
||||||
{
|
{
|
||||||
|
const double cell_width;
|
||||||
|
const double cell_height;
|
||||||
const int width;
|
const int width;
|
||||||
const int height;
|
const int height;
|
||||||
const int size;
|
const int size;
|
||||||
|
@ -19,13 +21,16 @@ struct reactor
|
||||||
std::unique_ptr<rod>* rods;
|
std::unique_ptr<rod>* rods;
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
|
|
||||||
reactor(std::unique_ptr<rod>* rods, int width, int height);
|
reactor(std::unique_ptr<rod>* rods, int width, int height, double cell_width, double cell_height);
|
||||||
reactor(const reactor& r);
|
reactor(const reactor& r);
|
||||||
reactor(reactor&& r);
|
reactor(reactor&& r);
|
||||||
~reactor();
|
~reactor();
|
||||||
|
|
||||||
void update(double secs);
|
void update(double secs);
|
||||||
void update_selected(int v);
|
void update_selected(int v);
|
||||||
|
void get_stats(rod::val_t type, double& min, double& max);
|
||||||
|
void get_rod_stats(int type, double& min, double& max);
|
||||||
|
double get_total(rod::val_t type);
|
||||||
int move_cursor(int d);
|
int move_cursor(int d);
|
||||||
void toggle_selected();
|
void toggle_selected();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "rod.hpp"
|
#include "rod.hpp"
|
||||||
|
#include "reactor.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -48,6 +49,12 @@ double rod::get_speed() const
|
||||||
return motion == 0 ? 0 : (std::pow(10, std::abs(motion)) * 1e-6 * m);
|
return motion == 0 ? 0 : (std::pow(10, std::abs(motion)) * 1e-6 * m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double rod::get_volume() const
|
||||||
|
{
|
||||||
|
auto r = (sim::reactor::reactor*)reactor;
|
||||||
|
return r->cell_width * r->cell_width * r->cell_height;
|
||||||
|
}
|
||||||
|
|
||||||
void rod::update_rod(double secs)
|
void rod::update_rod(double secs)
|
||||||
{
|
{
|
||||||
// decay the free neutrons
|
// decay the free neutrons
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
namespace sim::reactor
|
namespace sim::reactor
|
||||||
{
|
{
|
||||||
|
@ -9,7 +10,8 @@ namespace sim::reactor
|
||||||
class rod
|
class rod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void* reactor = nullptr;
|
||||||
static const int VAL_N = 3;
|
static const int VAL_N = 3;
|
||||||
|
|
||||||
enum val_t
|
enum val_t
|
||||||
|
@ -20,15 +22,19 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void interact(rod* o, double secs);
|
virtual void interact(rod* o, double secs);
|
||||||
virtual void update(double secs) { };
|
virtual void update(double secs) { }
|
||||||
virtual void add(val_t type, double v);
|
virtual void add(val_t type, double v);
|
||||||
virtual double extract(val_t type, double s, double k, double o);
|
virtual double extract(val_t type, double s, double k, double o);
|
||||||
virtual double get(val_t type) const;
|
virtual double get(val_t type) const;
|
||||||
virtual rod* clone() const { return new rod(*this); };
|
virtual rod* clone() const { return new rod(*this); }
|
||||||
|
virtual glm::vec4 get_colour() const { return {0, 0, 0, 0}; }
|
||||||
|
virtual int get_id() const { return 0; }
|
||||||
|
|
||||||
|
virtual bool has_sensors(val_t t) const { return false; }
|
||||||
virtual bool should_display() const { return false; }
|
virtual bool should_display() const { return false; }
|
||||||
virtual bool should_select() const { return false; }
|
virtual bool should_select() const { return false; }
|
||||||
void update_rod_selected(int m);
|
void update_rod_selected(int m);
|
||||||
|
double get_volume() const;
|
||||||
|
|
||||||
constexpr void toggle_selected() { selected = !selected; }
|
constexpr void toggle_selected() { selected = !selected; }
|
||||||
constexpr bool is_selected() const { return selected; }
|
constexpr bool is_selected() const { return selected; }
|
||||||
|
|
|
@ -2,46 +2,74 @@
|
||||||
#include "system.hpp"
|
#include "system.hpp"
|
||||||
|
|
||||||
#include "reactor/builder.hpp"
|
#include "reactor/builder.hpp"
|
||||||
#include "reactor/control/control_rod.hpp"
|
#include "reactor/control/boron_rod.hpp"
|
||||||
#include "reactor/fuel/fuel_rod.hpp"
|
#include "reactor/fuel/fuel_rod.hpp"
|
||||||
#include "reactor/coolant/pipe.hpp"
|
#include "reactor/coolant/pipe.hpp"
|
||||||
#include "reactor/coolant/heater.hpp"
|
#include "reactor/coolant/heater.hpp"
|
||||||
|
|
||||||
using namespace sim;
|
using namespace sim;
|
||||||
|
|
||||||
sim::system sim::system::generate()
|
system::system()
|
||||||
{
|
{
|
||||||
const char* layout[] = {
|
const char* layout[] = {
|
||||||
"#C#C#",
|
" C C C C ",
|
||||||
"CFCFC",
|
" C CFCFCFCFC C ",
|
||||||
"#C#C#",
|
" CFCFCFCFCFCFCFC ",
|
||||||
"CFCFC",
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
"#C#C#"
|
" CFCFCFCFCFCFCFC ",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
"CFCFCFCFCFCFCFCFCFC",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
"CFCFCFCFCFCFCFCFCFC",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
"CFCFCFCFCFCFCFCFCFC",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
"CFCFCFCFCFCFCFCFCFC",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
" CFCFCFCFCFCFCFC ",
|
||||||
|
" CFCFCFCFCFCFCFCFC ",
|
||||||
|
" CFCFCFCFCFCFCFC ",
|
||||||
|
" C CFCFCFCFC C ",
|
||||||
|
" C C C C "
|
||||||
};
|
};
|
||||||
|
|
||||||
reactor::coolant::vessel vessel(8, 10, 300, sim::coolant::WATER);
|
vessel = new reactor::coolant::vessel(8, 10, 300, sim::coolant::WATER);
|
||||||
sim::reactor::reactor reactor(sim::reactor::builder(5, 5,
|
reactor = new sim::reactor::reactor(sim::reactor::builder(19, 19, 0.25, 8,
|
||||||
reactor::fuel::fuel_rod(2000, 4000),
|
reactor::fuel::fuel_rod(0.5),
|
||||||
reactor::control::control_rod(vessel, 10000, 1),
|
reactor::control::boron_rod(*vessel, 1),
|
||||||
reactor::coolant::pipe(vessel),
|
*vessel, layout));
|
||||||
layout));
|
|
||||||
|
|
||||||
coolant::valve<reactor::coolant::vessel> valve(vessel, 1, 500);
|
valve = new coolant::valve<reactor::coolant::vessel>(*vessel, 1, 500);
|
||||||
coolant::pump<reactor::coolant::vessel> pump(vessel, 1e4, 15);
|
pump = new coolant::pump<reactor::coolant::vessel>(*vessel, 1e4, 15);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
system::system(system&& o)
|
||||||
.reactor = reactor,
|
{
|
||||||
.vessel = vessel,
|
vessel = o.vessel;
|
||||||
.valve = valve,
|
reactor = o.reactor;
|
||||||
.pump = pump
|
valve = o.valve;
|
||||||
};
|
pump = o.pump;
|
||||||
|
|
||||||
|
o.vessel = nullptr;
|
||||||
|
o.reactor = nullptr;
|
||||||
|
o.valve = nullptr;
|
||||||
|
o.pump = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
system::~system()
|
||||||
|
{
|
||||||
|
if(vessel != nullptr) delete vessel;
|
||||||
|
if(reactor != nullptr) delete reactor;
|
||||||
|
if(valve != nullptr) delete valve;
|
||||||
|
if(pump != nullptr) delete pump;
|
||||||
}
|
}
|
||||||
|
|
||||||
void system::update(double dt)
|
void system::update(double dt)
|
||||||
{
|
{
|
||||||
vessel.update(dt);
|
dt *= 10;
|
||||||
reactor.update(dt);
|
vessel->update(dt);
|
||||||
valve.update(dt);
|
reactor->update(dt);
|
||||||
pump.update(dt);
|
valve->update(dt);
|
||||||
|
pump->update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "reactor/coolant/vessel.hpp"
|
#include "reactor/coolant/vessel.hpp"
|
||||||
#include "reactor/reactor.hpp"
|
#include "reactor/reactor.hpp"
|
||||||
#include "coolant/pump.hpp"
|
#include "coolant/pump.hpp"
|
||||||
|
@ -11,13 +13,17 @@ namespace sim
|
||||||
|
|
||||||
struct system
|
struct system
|
||||||
{
|
{
|
||||||
sim::reactor::reactor reactor;
|
sim::reactor::reactor* reactor;
|
||||||
sim::reactor::coolant::vessel vessel;
|
sim::reactor::coolant::vessel* vessel;
|
||||||
sim::coolant::valve<sim::reactor::coolant::vessel> valve;
|
sim::coolant::valve<sim::reactor::coolant::vessel>* valve;
|
||||||
sim::coolant::pump<sim::reactor::coolant::vessel> pump;
|
sim::coolant::pump<sim::reactor::coolant::vessel>* pump;
|
||||||
|
|
||||||
|
system();
|
||||||
|
system(system&& o);
|
||||||
|
system(const system& o) = delete;
|
||||||
|
~system();
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
static system generate();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue