hummingbird
Solving the self-adjoint angular flux transport equation using spectral elements on Cartesian geometry
Loading...
Searching...
No Matches
problem_base.cc
Go to the documentation of this file.
2
3#include <format>
4#include <set>
5#include <stdexcept>
6
7namespace hummingbird {
8ProblemBase::ProblemBase(const size_t n_dofs, const size_t n_ordinates)
9 : n_dofs_(n_dofs) {
10 arma::SpMat<double> global_system_template(n_dofs, n_dofs);
11 arma::Col<double> global_vector_template(n_dofs, arma::fill::zeros);
12
13 global_system_matrices_.assign(n_ordinates, global_system_template);
14 global_forcing_vectors_.assign(n_ordinates, global_vector_template);
15 solution_vectors_.assign(n_ordinates, global_vector_template);
16}
17
19 const std::vector<GlobalMatrixData>& global_matrix_data,
20 const size_t ordinate_index) {
21 CheckGlobalMatrixData(global_matrix_data);
22
23 const auto n_dofs = global_system_matrices_.at(ordinate_index).n_rows;
24 auto n_vals = global_matrix_data.size();
25 arma::umat locations(2, n_vals);
26 arma::Col<double> values(n_vals);
27 for (auto i = 0; i < n_vals; i++) {
28 locations(0, i) = global_matrix_data[i].row_id;
29 locations(1, i) = global_matrix_data[i].col_id;
30 values[i] = global_matrix_data[i].value;
31 }
32 // add_values=true: sum duplicate (row,col) locations rather than
33 // erroring on them -- shared nodes between elements are expected to
34 // contribute more than one entry at the same location.
35 arma::SpMat<double> global_system_matrix(true, locations, values, n_dofs,
36 n_dofs);
37 global_system_matrices_.at(ordinate_index) = global_system_matrix;
38}
39
41 const std::vector<GlobalForcingData>& global_forcing_data,
42 const size_t ordinate_index) {
43 CheckGlobalForcingData(global_forcing_data);
44
45 const auto n_dofs = global_forcing_vectors_.at(ordinate_index).n_elem;
46 arma::Col<double> global_forcing_vector(n_dofs, arma::fill::zeros);
47 for (const auto& data : global_forcing_data)
48 global_forcing_vector(data.row_id) += data.value;
49 global_forcing_vectors_.at(ordinate_index) = std::move(global_forcing_vector);
50}
51
52void ProblemBase::Solve(const size_t ordinate_index) {
53 solution_vectors_.at(ordinate_index) =
54 arma::spsolve(global_system_matrices_.at(ordinate_index),
55 global_forcing_vectors_.at(ordinate_index));
56}
57
58void ProblemBase::ApplyBCs(const Mesh& mesh, const Ordinate& ordinate,
59 const BCBank& bc_bank, const size_t ordinate_index) {
60 switch (mesh.dimension()) {
61 case 1:
62 Apply1DBCs(mesh, ordinate, bc_bank, ordinate_index);
63 break;
64
65 default:
66 throw std::runtime_error(
67 "Invalid mesh ID passed in ProblemBase::ApplyBCs.");
68 break;
69 }
70}
71
73 const std::vector<GlobalMatrixData>& gmd) {
74 std::set<size_t> ids;
75 for (const auto& data : gmd) {
76 ids.insert(data.row_id);
77 ids.insert(data.col_id);
78 }
79
80 size_t expected_id = 0;
81 for (auto id : ids) {
82 if (id != expected_id)
83 throw std::runtime_error(std::format(
84 "Global matrix data is missing node ID {}. Node IDs referenced by "
85 "global matrix data must be contiguous starting from 0.",
86 expected_id));
87 expected_id++;
88 }
89}
90
92 const std::vector<GlobalForcingData>& gfd) {
93 std::set<size_t> ids;
94 for (const auto& data : gfd) ids.insert(data.row_id);
95
96 size_t expected_id = 0;
97 for (auto id : ids) {
98 if (id != expected_id)
99 throw std::runtime_error(std::format(
100 "Global forcing data is missing row ID {}. Row IDs referenced by "
101 "global forcing data must be contiguous starting from 0.",
102 expected_id));
103 expected_id++;
104 }
105}
106
107} // namespace hummingbird
Bank holding the boundary conditions defined in the input file.
Definition bc_bank.h:21
Class defing a mesh.
Definition mesh.h:27
unsigned int dimension() const
Get the spatial dimension of the mesh, derived from the elements it contains (e.g....
Definition mesh.h:116
Defines a solid angle, or ordinate, in spherical geometry.
Definition ordinate.h:15
virtual void Apply1DBCs(const Mesh &mesh, const Ordinate &Ordinate, const BCBank &bc_bank, const size_t ordinate_index)=0
Apply boundary conditions to a 1D problem.
std::vector< arma::SpMat< double > > global_system_matrices_
Global system matrices in order of ordinates in angular quadrature set.
std::vector< arma::Col< double > > solution_vectors_
Column vector of the angular flux at the nodes in order of ordinates in angular quadrature set.
std::vector< arma::Col< double > > global_forcing_vectors_
Global forcing vectors in order of ordinates in angular quadrature set.
void Solve(const size_t ordinate_index)
Solve the linear system using Armadillo's sparse matrix solver. Stores the results in the solution_ve...
ProblemBase(const size_t n_dofs, const size_t n_ordinates)
Construct a new Problem Base object.
void CheckGlobalMatrixData(const std::vector< GlobalMatrixData > &gmd)
Validate a vector of GlobalMatrixData before it is used to assemble the global system matrix....
const size_t n_dofs_
Number of degrees of freedom in simulation.
void ApplyBCs(const Mesh &mesh, const Ordinate &ordinate, const BCBank &bc_bank, const size_t ordinate_index)
Apply boundary conditions by adding in values needed at boundary nodes. Internally,...
size_t n_dofs() const
Get the number of degrees of freedom.
void CheckGlobalForcingData(const std::vector< GlobalForcingData > &gfd)
Validate a vector of GlobalForcingData before it is used to assemble the global forcing vector....
void AssembleGlobalSystem(const std::vector< GlobalMatrixData > &global_matrix_data, const size_t ordinate_index)
Assemble the global element system. That is, form the matrix in . This only should be called once pe...
void AssembleGlobalForcing(const std::vector< GlobalForcingData > &global_forcing_data, const size_t ordinate_index)
Assemble the global forcing vector for a given ordinate index. The global vector is sized from the n_...