6#include <deal.II/base/multithread_info.h>
7#include <deal.II/base/quadrature_lib.h>
8#include <deal.II/base/timer.h>
9#include <deal.II/dofs/dof_handler.h>
10#include <deal.II/dofs/dof_tools.h>
11#include <deal.II/fe/fe_interface_values.h>
12#include <deal.II/fe/fe_values.h>
13#include <deal.II/lac/full_matrix.h>
14#include <deal.II/lac/sparse_matrix.h>
15#include <deal.II/lac/vector.h>
16#include <deal.II/meshworker/mesh_loop.h>
17#include <deal.II/numerics/fe_field_function.h>
18#include <deal.II/numerics/matrix_tools.h>
19#include <deal.II/numerics/vector_tools.h>
20#include <spdlog/spdlog.h>
32 namespace KurganovTadmor
34 using namespace dealii;
48 const UpdateFlags update_flags = update_values | update_gradients | update_quadrature_points |
79 template <
int dim>
void reinit(
const FEInterfaceValues<dim> &fe_iv)
91 template <
class Iterator>
void reinit(
const Iterator &cell,
uint dofs_per_cell)
107 template <
int dim>
void reinit(
const FEInterfaceValues<dim> &fe_iv,
uint n_extractors)
109 uint dofs_per_cell = fe_iv.n_current_interface_dofs();
122 template <
class Iterator>
void reinit(
const Iterator &cell,
uint dofs_per_cell,
uint n_extractors)
143 template <
typename Discretization_,
typename Model_>
146 typename Discretization_::SparseMatrixType, Discretization_::dim>
149 template <
typename... T>
auto fv_tie(T &&...t)
151 return named_tuple<std::tuple<T &...>,
"fe_functions">(std::tie(t...));
154 template <
typename... T>
static constexpr auto v_tie(T &&...t)
156 return named_tuple<std::tuple<T &...>,
"variables",
"extractors">(std::tie(t...));
159 template <
typename... T>
static constexpr auto e_tie(T &&...t)
161 return named_tuple<std::tuple<T &...>,
"fe_functions",
"fe_derivatives",
"fe_hessians",
"extractors",
162 "variables">(std::tie(t...));
184 if (this->
threads == 0) this->
threads = dealii::MultithreadInfo::n_threads() / 2;
185 spdlog::get(
"log")->info(
"FV: Using {} threads for assembly.",
threads);
192 const auto block_structure =
discretization.get_block_structure();
193 vec.reinit(block_structure[0]);
202 const auto fe_function_names = Components::FEFunction_Descriptor::get_names_vector();
203 std::vector<std::string> fe_function_names_residual;
204 for (
const auto &name : fe_function_names)
205 fe_function_names_residual.push_back(name +
"_residual");
206 std::vector<std::string> fe_function_names_dot;
207 for (
const auto &name : fe_function_names)
208 fe_function_names_dot.push_back(name +
"_dot");
211 fe_out.attach(
dof_handler, solution, fe_function_names);
212 if (dt_solution.size() > 0) fe_out.attach(
dof_handler, dt_solution, fe_function_names_dot);
223 auto dynamic_sparsity_pattern_mass = DynamicSparsityPattern(
dof_handler.n_dofs());
225 dynamic_sparsity_pattern_mass.add(i, i);
230 constexpr uint stencil = 1;
257 auto helper = [&](
auto EoMfun,
auto outputter) {
259 outputter(data_out, Point<0>(),
fv_tie(variables));
261 model.template readouts_multiple(helper, data_out);
267 using Iterator =
typename DoFHandler<dim>::active_cell_iterator;
272 const auto cell_worker = [&](
const Iterator &cell, Scratch &scratch_data, CopyData ©_data) {
273 scratch_data.fe_values.reinit(cell);
274 const auto &fe_v = scratch_data.fe_values;
275 const uint n_dofs = fe_v.get_fe().n_dofs_per_cell();
277 copy_data.reinit(cell, n_dofs);
278 const auto &JxW = fe_v.get_JxW_values();
279 const auto &q_points = fe_v.get_quadrature_points();
280 const auto &q_indices = fe_v.quadrature_point_indices();
282 auto &solution = scratch_data.solution;
283 auto &solution_dot = scratch_data.solution_dot;
284 fe_v.get_function_values(solution_global, solution);
285 fe_v.get_function_values(solution_global_dot, solution_dot);
287 std::array<NumberType, n_components>
mass{};
288 for (
const auto &q_index : q_indices) {
289 const auto &x_q = q_points[q_index];
290 model.mass(
mass, x_q, solution[q_index], solution_dot[q_index]);
292 for (
uint i = 0; i < n_dofs; ++i) {
293 const auto component_i = fe_v.get_fe().system_to_component_index(i).first;
294 copy_data.cell_residual(i) += weight * JxW[q_index] *
295 fe_v.shape_value_component(i, q_index, component_i) *
300 const auto copier = [&](
const CopyData &c) {
301 constraints.distribute_local_to_global(c.cell_residual, c.local_dof_indices,
mass);
306 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
316 using Iterator =
typename DoFHandler<dim>::active_cell_iterator;
321 const auto cell_worker = [&](
const Iterator &cell, Scratch &scratch_data, CopyData ©_data) {
322 scratch_data.fe_values.reinit(cell);
323 const auto &fe_v = scratch_data.fe_values;
324 const uint n_dofs = fe_v.get_fe().n_dofs_per_cell();
326 copy_data.reinit(cell, n_dofs);
327 const auto &JxW = fe_v.get_JxW_values();
328 const auto &q_points = fe_v.get_quadrature_points();
329 const auto &q_indices = fe_v.quadrature_point_indices();
331 auto &solution = scratch_data.solution;
332 auto &solution_dot = scratch_data.solution_dot;
333 fe_v.get_function_values(solution_global, solution);
334 fe_v.get_function_values(solution_global_dot, solution_dot);
336 std::array<NumberType, n_components>
mass{};
337 std::array<NumberType, n_components> source{};
338 for (
const auto &q_index : q_indices) {
339 const auto &x_q = q_points[q_index];
340 model.mass(
mass, x_q, solution[q_index], solution_dot[q_index]);
341 model.source(source, x_q,
fv_tie(solution[q_index]));
343 for (
uint i = 0; i < n_dofs; ++i) {
344 const auto component_i = fe_v.get_fe().system_to_component_index(i).first;
345 copy_data.cell_mass(i) += weight_mass * JxW[q_index] *
346 fe_v.shape_value_component(i, q_index, component_i) *
348 copy_data.cell_residual(i) += JxW[q_index] * weight *
349 (fe_v.shape_value_component(i, q_index, component_i) *
350 source[component_i]);
354 const auto copier = [&](
const CopyData &c) {
355 constraints.distribute_local_to_global(c.cell_residual, c.local_dof_indices,
residual);
356 constraints.distribute_local_to_global(c.cell_mass, c.local_dof_indices,
residual);
361 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
373 using Iterator =
typename DoFHandler<dim>::active_cell_iterator;
378 const auto cell_worker = [&](
const Iterator &cell, Scratch &scratch_data, CopyData ©_data) {
379 scratch_data.fe_values.reinit(cell);
380 const auto &fe_v = scratch_data.fe_values;
381 const uint n_dofs = fe_v.get_fe().n_dofs_per_cell();
383 copy_data.reinit(cell, n_dofs, Components::count_extractors());
384 const auto &JxW = fe_v.get_JxW_values();
385 const auto &q_points = fe_v.get_quadrature_points();
386 const auto &q_indices = fe_v.quadrature_point_indices();
388 auto &solution = scratch_data.solution;
389 auto &solution_dot = scratch_data.solution_dot;
390 fe_v.get_function_values(solution_global, solution);
391 fe_v.get_function_values(solution_global_dot, solution_dot);
395 for (
const auto &q_index : q_indices) {
396 const auto &x_q = q_points[q_index];
400 for (
uint i = 0; i < n_dofs; ++i) {
401 const auto component_i = fe_v.get_fe().system_to_component_index(i).first;
402 for (
uint j = 0; j < n_dofs; ++j) {
403 const auto component_j = fe_v.get_fe().system_to_component_index(j).first;
404 copy_data.cell_jacobian(i, j) +=
405 JxW[q_index] * fe_v.shape_value_component(j, q_index, component_j) *
406 fe_v.shape_value_component(i, q_index, component_i) *
407 (alpha * j_mass_dot(component_i, component_j) + beta * j_mass(component_i, component_j));
412 const auto copier = [&](
const CopyData &c) {
413 constraints.distribute_local_to_global(c.cell_jacobian, c.local_dof_indices,
jacobian);
418 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
430 using Iterator =
typename DoFHandler<dim>::active_cell_iterator;
435 const auto cell_worker = [&](
const Iterator &cell, Scratch &scratch_data, CopyData ©_data) {
436 scratch_data.fe_values.reinit(cell);
437 const auto &fe_v = scratch_data.fe_values;
438 const uint n_dofs = fe_v.get_fe().n_dofs_per_cell();
440 copy_data.reinit(cell, n_dofs, Components::count_extractors());
441 const auto &JxW = fe_v.get_JxW_values();
442 const auto &q_points = fe_v.get_quadrature_points();
443 const auto &q_indices = fe_v.quadrature_point_indices();
445 auto &solution = scratch_data.solution;
446 auto &solution_dot = scratch_data.solution_dot;
447 fe_v.get_function_values(solution_global, solution);
448 fe_v.get_function_values(solution_global_dot, solution_dot);
453 for (
const auto &q_index : q_indices) {
454 const auto &x_q = q_points[q_index];
457 model.template jacobian_source<0, 0>(j_source, x_q,
fv_tie(solution[q_index]));
459 for (
uint i = 0; i < n_dofs; ++i) {
460 const auto component_i = fe_v.get_fe().system_to_component_index(i).first;
461 for (
uint j = 0; j < n_dofs; ++j) {
462 const auto component_j = fe_v.get_fe().system_to_component_index(j).first;
463 copy_data.cell_jacobian(i, j) +=
464 weight * JxW[q_index] * fe_v.shape_value_component(j, q_index, component_j) *
465 (fe_v.shape_value_component(i, q_index, component_i) *
466 j_source(component_i, component_j));
467 copy_data.cell_mass_jacobian(i, j) +=
468 JxW[q_index] * fe_v.shape_value_component(j, q_index, component_j) *
469 fe_v.shape_value_component(i, q_index, component_i) *
470 (alpha * j_mass_dot(component_i, component_j) + beta * j_mass(component_i, component_j));
475 const auto copier = [&](
const CopyData &c) {
476 constraints.distribute_local_to_global(c.cell_jacobian, c.local_dof_indices,
jacobian);
477 constraints.distribute_local_to_global(c.cell_mass_jacobian, c.local_dof_indices,
jacobian);
482 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
490 void build_sparsity(SparsityPattern &sparsity_pattern,
const DoFHandler<dim> &to_dofh,
491 const DoFHandler<dim> &from_dofh,
const int stencil = 1,
492 bool add_extractor_dofs =
false)
const
498 const auto to_dofs_per_cell = to_dofh.get_fe().dofs_per_cell;
499 const auto from_dofs_per_cell = from_dofh.get_fe().dofs_per_cell;
501 for (
const auto &t_cell :
triangulation.active_cell_iterators()) {
502 std::vector<types::global_dof_index> to_dofs(to_dofs_per_cell);
503 std::vector<types::global_dof_index> from_dofs(from_dofs_per_cell);
504 const auto to_cell = t_cell->as_dof_handler_iterator(to_dofh);
505 const auto from_cell = t_cell->as_dof_handler_iterator(from_dofh);
506 to_cell->get_dof_indices(to_dofs);
507 from_cell->get_dof_indices(from_dofs);
509 std::function<void(
decltype(from_cell) &,
const int)> add_all_neighbor_dofs = [&](
const auto &from_cell,
510 const int stencil_level) {
511 for (
const auto face_no : from_cell->face_indices()) {
512 const auto face = from_cell->face(face_no);
513 if (!face->at_boundary()) {
514 auto neighbor_cell = from_cell->neighbor(face_no);
517 while (neighbor_cell->has_children())
518 neighbor_cell = neighbor_cell->child(face_no == 0 ? 1 : 0);
521 else if (neighbor_cell->has_children()) {
522 throw std::runtime_error(
"not yet implemented lol");
525 if (!neighbor_cell->is_active())
continue;
527 std::vector<types::global_dof_index> tmp(from_dofs_per_cell);
528 neighbor_cell->get_dof_indices(tmp);
530 from_dofs.insert(std::end(from_dofs), std::begin(tmp), std::end(tmp));
532 if (stencil_level < stencil) add_all_neighbor_dofs(neighbor_cell, stencil_level + 1);
537 add_all_neighbor_dofs(from_cell, 1);
539 for (
const auto i : to_dofs)
540 for (
const auto j : from_dofs)
547 sparsity_pattern.copy_from(dsp);
550 void log(
const std::string logger)
552 std::stringstream ss;
553 ss <<
"FV Assembler: " << std::endl;
559 spdlog::get(logger)->info(ss.str());
604 mutable typename Triangulation<dim>::cell_iterator
EoM_cell;
This is the general assembler interface for any kind of discretization. An assembler is responsible f...
Definition abstract_assembler.hh:39
Class to manage writing to files. FEM functions are written to vtk files and other data is written to...
Definition data_output.hh:20
FEOutput< dim, VectorType > & fe_output()
Returns a reference to the FEOutput object used to write FEM functions to .vtu files and ....
static constexpr uint dim
Definition discretization.hh:37
Vector< NumberType > VectorType
Definition discretization.hh:34
NumberType_ NumberType
Definition discretization.hh:33
Components_ Components
Definition discretization.hh:32
Definition KurganovTadmor.hh:147
Assembler(Discretization &discretization, Model &model, const JSONValue &json)
Definition KurganovTadmor.hh:175
double average_time_jacobian_assembly() const
Definition KurganovTadmor.hh:582
uint num_residuals() const
Definition KurganovTadmor.hh:580
Triangulation< dim >::cell_iterator old_EoM_cell
Definition KurganovTadmor.hh:605
virtual void reinit() override
Reinitialize the assembler. This is necessary if the mesh has changed, e.g. after a mesh refinement.
Definition KurganovTadmor.hh:218
Model & model
Definition KurganovTadmor.hh:594
const DoFHandler< dim > & dof_handler
Definition KurganovTadmor.hh:595
virtual void set_time(double t) override
Set the current time. The assembler should usually just forward this to the numerical model.
Definition KurganovTadmor.hh:236
const QGauss< dim > quadrature
Definition KurganovTadmor.hh:609
const Mapping< dim > & mapping
Definition KurganovTadmor.hh:596
virtual void mass(VectorType &mass, const VectorType &solution_global, const VectorType &solution_global_dot, NumberType weight) override
Definition KurganovTadmor.hh:264
virtual void jacobian(SparseMatrix< NumberType > &jacobian, const VectorType &solution_global, NumberType weight, const VectorType &solution_global_dot, NumberType alpha, NumberType beta, const VectorType &variables=VectorType()) override
Definition KurganovTadmor.hh:426
const uint EoM_max_iter
Definition KurganovTadmor.hh:607
Model_ Model
Definition KurganovTadmor.hh:167
typename Discretization::VectorType VectorType
Definition KurganovTadmor.hh:169
double average_time_residual_assembly() const
Definition KurganovTadmor.hh:572
SparsityPattern sparsity_pattern_jacobian
Definition KurganovTadmor.hh:612
SparsityPattern sparsity_pattern_mass
Definition KurganovTadmor.hh:611
static constexpr auto e_tie(T &&...t)
Definition KurganovTadmor.hh:159
virtual void jacobian_mass(SparseMatrix< NumberType > &jacobian, const VectorType &solution_global, const VectorType &solution_global_dot, NumberType alpha=1., NumberType beta=1.) override
Definition KurganovTadmor.hh:369
static constexpr auto v_tie(T &&...t)
Definition KurganovTadmor.hh:154
const uint batch_size
Definition KurganovTadmor.hh:602
double average_time_reinit() const
Definition KurganovTadmor.hh:562
static constexpr uint n_components
Definition KurganovTadmor.hh:173
uint num_reinits() const
Definition KurganovTadmor.hh:570
uint num_jacobians() const
Definition KurganovTadmor.hh:590
typename Discretization::NumberType NumberType
Definition KurganovTadmor.hh:168
virtual void attach_data_output(DataOutput< dim, VectorType > &data_out, const VectorType &solution, const VectorType &variables, const VectorType &dt_solution=VectorType(), const VectorType &residual=VectorType())
Definition KurganovTadmor.hh:198
Triangulation< dim >::cell_iterator EoM_cell
Definition KurganovTadmor.hh:604
SparseMatrix< NumberType > mass_matrix
Definition KurganovTadmor.hh:613
virtual const SparseMatrix< NumberType > & get_mass_matrix() const override
Obtain the mass matrix.
Definition KurganovTadmor.hh:242
std::vector< double > timings_jacobian
Definition KurganovTadmor.hh:617
virtual void residual(VectorType &residual, const VectorType &solution_global, NumberType weight, const VectorType &solution_global_dot, NumberType weight_mass, const VectorType &variables=VectorType()) override
Definition KurganovTadmor.hh:312
Discretization & discretization
Definition KurganovTadmor.hh:593
uint threads
Definition KurganovTadmor.hh:601
void log(const std::string logger)
Definition KurganovTadmor.hh:550
typename Discretization::Components Components
Definition KurganovTadmor.hh:171
static constexpr uint dim
Definition KurganovTadmor.hh:172
virtual IndexSet get_differential_indices() const override
Obtain the dofs which contain time derivatives.
Definition KurganovTadmor.hh:196
virtual void reinit_vector(VectorType &vec) const override
Definition KurganovTadmor.hh:190
const double EoM_abs_tol
Definition KurganovTadmor.hh:606
virtual const SparsityPattern & get_sparsity_pattern_jacobian() const override
Obtain the sparsity pattern of the jacobian matrix.
Definition KurganovTadmor.hh:238
std::vector< double > timings_residual
Definition KurganovTadmor.hh:616
virtual void residual_variables(VectorType &residual, const VectorType &variables, const VectorType &) override
Definition KurganovTadmor.hh:244
void build_sparsity(SparsityPattern &sparsity_pattern, const DoFHandler< dim > &to_dofh, const DoFHandler< dim > &from_dofh, const int stencil=1, bool add_extractor_dofs=false) const
Definition KurganovTadmor.hh:490
const JSONValue & json
Definition KurganovTadmor.hh:599
Discretization_ Discretization
Definition KurganovTadmor.hh:166
std::vector< double > timings_reinit
Definition KurganovTadmor.hh:615
virtual void jacobian_variables(FullMatrix< NumberType > &jacobian, const VectorType &variables, const VectorType &) override
Definition KurganovTadmor.hh:249
auto fv_tie(T &&...t)
Definition KurganovTadmor.hh:149
const Triangulation< dim > & triangulation
Definition KurganovTadmor.hh:597
void readouts(DataOutput< dim, VectorType > &data_out, const VectorType &, const VectorType &variables) const
Definition KurganovTadmor.hh:255
A wrapper around the boost json value class.
Definition json.hh:19
Definition quadrature.hh:50
A simple NxM-matrix class, which is used for cell-wise Jacobians.
Definition tuples.hh:153
Definition complex_math.hh:14
unsigned int uint
Definition utils.hh:22
Definition KurganovTadmor.hh:133
std::array< double, 2 > values
Definition KurganovTadmor.hh:135
std::array< uint, 2 > cell_indices
Definition KurganovTadmor.hh:134
Definition KurganovTadmor.hh:132
std::vector< CopyFaceData_I > face_data
Definition KurganovTadmor.hh:137
uint cell_index
Definition KurganovTadmor.hh:139
double value
Definition KurganovTadmor.hh:138
Definition KurganovTadmor.hh:102
FullMatrix< NumberType > cell_jacobian
Definition KurganovTadmor.hh:103
void reinit(const FEInterfaceValues< dim > &fe_iv, uint n_extractors)
Definition KurganovTadmor.hh:107
std::vector< types::global_dof_index > joint_dof_indices
Definition KurganovTadmor.hh:105
FullMatrix< NumberType > extractor_cell_jacobian
Definition KurganovTadmor.hh:104
Definition KurganovTadmor.hh:101
FullMatrix< NumberType > extractor_cell_jacobian
Definition KurganovTadmor.hh:117
std::vector< CopyDataFace_J > face_data
Definition KurganovTadmor.hh:120
FullMatrix< NumberType > cell_jacobian
Definition KurganovTadmor.hh:116
FullMatrix< NumberType > cell_mass_jacobian
Definition KurganovTadmor.hh:118
std::vector< types::global_dof_index > local_dof_indices
Definition KurganovTadmor.hh:119
void reinit(const Iterator &cell, uint dofs_per_cell, uint n_extractors)
Definition KurganovTadmor.hh:122
Definition KurganovTadmor.hh:75
Vector< NumberType > cell_residual
Definition KurganovTadmor.hh:76
std::vector< types::global_dof_index > joint_dof_indices
Definition KurganovTadmor.hh:77
void reinit(const FEInterfaceValues< dim > &fe_iv)
Definition KurganovTadmor.hh:79
Definition KurganovTadmor.hh:74
void reinit(const Iterator &cell, uint dofs_per_cell)
Definition KurganovTadmor.hh:91
Vector< NumberType > cell_mass
Definition KurganovTadmor.hh:87
std::vector< CopyDataFace_R > face_data
Definition KurganovTadmor.hh:89
std::vector< types::global_dof_index > local_dof_indices
Definition KurganovTadmor.hh:88
Vector< NumberType > cell_residual
Definition KurganovTadmor.hh:86
Class to hold data for each assembly thread, i.e. FEValues for cells, interfaces, as well as pre-allo...
Definition KurganovTadmor.hh:42
typename Discretization::NumberType NumberType
Definition KurganovTadmor.hh:44
Vector< NumberType > VectorType
Definition KurganovTadmor.hh:45
const uint n_components
Definition KurganovTadmor.hh:65
std::vector< VectorType > solution
Definition KurganovTadmor.hh:69
std::vector< VectorType > solution_dot
Definition KurganovTadmor.hh:70
ScratchData(const ScratchData< Discretization > &scratch_data)
Definition KurganovTadmor.hh:56
ScratchData(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const Quadrature< dim > &quadrature, const UpdateFlags update_flags=update_values|update_gradients|update_quadrature_points|update_JxW_values)
Definition KurganovTadmor.hh:47
FEValues< dim > fe_values
Definition KurganovTadmor.hh:67
static constexpr int dim
Definition KurganovTadmor.hh:43
A class to store a tuple with elements that can be accessed by name. The names are stored as FixedStr...
Definition tuples.hh:27