diff --git a/libnufi_lib.a b/libnufi_lib.a index 5703b05..031c6a7 100644 Binary files a/libnufi_lib.a and b/libnufi_lib.a differ diff --git a/nufi/nufi_solver.h b/nufi/nufi_solver.h index f9a9d18..32de460 100644 --- a/nufi/nufi_solver.h +++ b/nufi/nufi_solver.h @@ -34,6 +34,12 @@ public: const std::vector> &grid_struct, const std::vector> &phi_history) const; + std::vector + eval_rho_points(unsigned int n, const std::vector> &points, + const std::vector> &grid_struct, + const std::vector> &phi_history, + const unsigned int Nv) const; + private: unsigned int Nt = std::floor(Parameters::TMAX / Parameters::DT); unsigned int Nx = Parameters::CALC_NX; diff --git a/nufi/poisson_problem.h b/nufi/poisson_problem.h index 4a2517f..35a4404 100644 --- a/nufi/poisson_problem.h +++ b/nufi/poisson_problem.h @@ -73,8 +73,9 @@ public: unsigned int get_rhs_size(); unsigned int get_dof_size(); - void set_rhs_function(std::function &)> f); - void set_rhs(const Vector &new_rhs) { rhs = new_rhs; } + void set_rhs_function( + std::function(const std::vector> &)> f); + // void set_rhs(const Vector &new_rhs) { rhs = new_rhs; } const Vector &get_solution() const { return solution; } const MappingQ &get_mapping() const { return mapping; } @@ -116,8 +117,9 @@ private: Vector solution; // phi Vector system_rhs; - std::function &)> rhs_function; - Vector rhs; + std::function(const std::vector> &)> + rhs_function; + // Vector rhs; MappingQ mapping; @@ -139,11 +141,11 @@ template unsigned int PoissonProblem::get_dof_size() { return dof_handler.n_dofs(); } -// template -// void PoissonProblem::set_rhs_function( -// std::function &)> f) { -// rhs_function = std::move(f); -// } +template +void PoissonProblem::set_rhs_function( + std::function(const std::vector> &)> f) { + rhs_function = std::move(f); +} template PoissonProblem::PoissonProblem(unsigned int degree) @@ -331,14 +333,14 @@ template void PoissonProblem::setup_system() { // update_gradients); } -// Paul template void PoissonProblem::assemble_system() { + Assert(system_matrix.m() == dof_handler.n_dofs(), ExcMessage("Matrix not initialized correctly")); system_matrix = 0; system_rhs = 0; - QGauss quadrature_formula(fe.degree + 1); + const QGauss quadrature_formula(fe.degree + 1); FEValues fe_values(fe, quadrature_formula, update_values | update_gradients | update_quadrature_points | update_JxW_values); @@ -347,32 +349,49 @@ template void PoissonProblem::assemble_system() { FullMatrix cell_matrix(dofs_per_cell, dofs_per_cell); Vector cell_rhs(dofs_per_cell); + std::vector local_dof_indices(dofs_per_cell); - std::vector rhs_values(quadrature_formula.size()); + // Eval rhs_function only once for all quadrature points + const unsigned int n_q_points = quadrature_formula.size(); + std::vector> all_q_points; + all_q_points.reserve(triangulation.n_active_cells() * n_q_points); + for (const auto &cell : dof_handler.active_cell_iterators()) { + fe_values.reinit(cell); + const auto &q_points = fe_values.get_quadrature_points(); + all_q_points.insert(all_q_points.end(), q_points.begin(), q_points.end()); + } + + Assert(rhs_function, + ExcMessage("Poisson RHS function has not been initialized.")); + + std::vector all_rho = rhs_function(all_q_points); + + Assert(all_rho.size() == all_q_points.size(), + ExcMessage("rhs_function returned wrong size")); + + // assemble system + unsigned int q_offset = 0; for (const auto &cell : dof_handler.active_cell_iterators()) { fe_values.reinit(cell); cell_matrix = 0; cell_rhs = 0; - fe_values.get_function_values(rhs, rhs_values); + for (size_t q = 0; q < n_q_points; ++q) { - for (const auto q : fe_values.quadrature_point_indices()) { - // const double rho = rhs_function( - // fe_values.quadrature_point(q)); // Eval rhs_function at q points - - for (const unsigned int i : fe_values.dof_indices()) - for (const unsigned int j : fe_values.dof_indices()) + for (const unsigned int i : fe_values.dof_indices()) { + for (const unsigned int j : fe_values.dof_indices()) { cell_matrix(i, j) += fe_values.shape_grad(i, q) * fe_values.shape_grad(j, q) * fe_values.JxW(q); + } - for (const unsigned int i : fe_values.dof_indices()) - // cell_rhs(i) += fe_values.shape_value(i, q) * rho * fe_values.JxW(q); - cell_rhs(i) += - fe_values.shape_value(i, q) * rhs_values[q] * fe_values.JxW(q); + cell_rhs(i) += fe_values.shape_value(i, q) * all_rho[q_offset + q] * + fe_values.JxW(q); + } } + q_offset += n_q_points; cell->get_dof_indices(local_dof_indices); diff --git a/src/nufi_solver.cc b/src/nufi_solver.cc index 84f68fe..be03cfb 100644 --- a/src/nufi_solver.cc +++ b/src/nufi_solver.cc @@ -158,6 +158,15 @@ NuFISolver::eval_rho(unsigned int n, std::vector &X, return integral; } +std::vector +NuFISolver::eval_rho_points(unsigned int n, const std::vector> &points, + const std::vector> &grid_struct, + const std::vector> &phi_history, + const unsigned int Nv) const { + std::vector point_vector = Point_vector_to_double_vector(points); + return NuFISolver::eval_rho(n, point_vector, grid_struct, phi_history, Nv); +} + void NuFISolver::run() { //====//====// @@ -167,12 +176,13 @@ void NuFISolver::run() { using std::abs; using std::max; - std::unique_ptr rho{ - reinterpret_cast(std::aligned_alloc(64, sizeof(double) * Nx)), - std::free}; - - if (rho == nullptr) - throw std::bad_alloc{}; + // std::unique_ptr rho{ + // reinterpret_cast(std::aligned_alloc(64, sizeof(double) * + // Nx)), + // std::free}; + // + // if (rho == nullptr) + // throw std::bad_alloc{}; std::vector int_E_squared; int_E_squared.reserve(Nt); @@ -234,15 +244,15 @@ void NuFISolver::run() { double compute_start = timer.elapsed(); // compute rho - std::vector x_eval = make_x_eval(poisson.get_dof_size()); - std::vector rho_values = - eval_rho(it, x_eval, grid_versions, phi_history, Parameters::NV); + // + poisson.set_rhs_function([&](const std::vector> &points) { + std::vector x(points.size()); - Vector rhs(x_eval.size()); - for (unsigned int i = 0; i < rhs.size(); ++i) - rhs[i] = rho_values[i]; + for (size_t i = 0; i < points.size(); ++i) + x[i] = points[i][0]; - poisson.set_rhs(rhs); + return eval_rho(it, x, grid_versions, phi_history, Parameters::NV); + }); poisson.solve_step();