DiFfRG
Loading...
Searching...
No Matches
KurganovTadmor.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4
5// DiFfRG
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>
21#include <tbb/tbb.h>
22
25
27
28namespace DiFfRG
29{
30 namespace FV
31 {
32 namespace KurganovTadmor
33 {
34 using namespace dealii;
35
36 namespace internal
37 {
42 template <typename Discretization> struct ScratchData {
43 static constexpr int dim = Discretization::dim;
45 using VectorType = Vector<NumberType>;
46
47 ScratchData(const Mapping<dim> &mapping, const FiniteElement<dim> &fe, const Quadrature<dim> &quadrature,
48 const UpdateFlags update_flags = update_values | update_gradients | update_quadrature_points |
49 update_JxW_values)
50 : n_components(fe.n_components()), fe_values(mapping, fe, quadrature, update_flags)
51 {
52 solution.resize(quadrature.size(), VectorType(n_components));
53 solution_dot.resize(quadrature.size(), VectorType(n_components));
54 }
55
57 : n_components(scratch_data.fe_values.get_fe().n_components()),
58 fe_values(scratch_data.fe_values.get_mapping(), scratch_data.fe_values.get_fe(),
59 scratch_data.fe_values.get_quadrature(), scratch_data.fe_values.get_update_flags())
60 {
61 solution.resize(scratch_data.fe_values.get_quadrature().size(), VectorType(n_components));
62 solution_dot.resize(scratch_data.fe_values.get_quadrature().size(), VectorType(n_components));
63 }
64
66
67 FEValues<dim> fe_values;
68
69 std::vector<VectorType> solution;
70 std::vector<VectorType> solution_dot;
71 };
72
73 // TODO fewer memory allocations
74 template <typename NumberType> struct CopyData_R {
76 Vector<NumberType> cell_residual;
77 std::vector<types::global_dof_index> joint_dof_indices;
78
79 template <int dim> void reinit(const FEInterfaceValues<dim> &fe_iv)
80 {
81 cell_residual.reinit(fe_iv.n_current_interface_dofs());
82 joint_dof_indices = fe_iv.get_interface_dof_indices();
83 }
84 };
85
86 Vector<NumberType> cell_residual;
87 Vector<NumberType> cell_mass;
88 std::vector<types::global_dof_index> local_dof_indices;
89 std::vector<CopyDataFace_R> face_data;
90
91 template <class Iterator> void reinit(const Iterator &cell, uint dofs_per_cell)
92 {
93 cell_residual.reinit(dofs_per_cell);
94 cell_mass.reinit(dofs_per_cell);
95 local_dof_indices.resize(dofs_per_cell);
96 cell->get_dof_indices(local_dof_indices);
97 }
98 };
99
100 // TODO fewer memory allocations
101 template <typename NumberType> struct CopyData_J {
103 FullMatrix<NumberType> cell_jacobian;
104 FullMatrix<NumberType> extractor_cell_jacobian;
105 std::vector<types::global_dof_index> joint_dof_indices;
106
107 template <int dim> void reinit(const FEInterfaceValues<dim> &fe_iv, uint n_extractors)
108 {
109 uint dofs_per_cell = fe_iv.n_current_interface_dofs();
110 cell_jacobian.reinit(dofs_per_cell, dofs_per_cell);
111 if (n_extractors > 0) extractor_cell_jacobian.reinit(dofs_per_cell, n_extractors);
112 joint_dof_indices = fe_iv.get_interface_dof_indices();
113 }
114 };
115
116 FullMatrix<NumberType> cell_jacobian;
117 FullMatrix<NumberType> extractor_cell_jacobian;
118 FullMatrix<NumberType> cell_mass_jacobian;
119 std::vector<types::global_dof_index> local_dof_indices;
120 std::vector<CopyDataFace_J> face_data;
121
122 template <class Iterator> void reinit(const Iterator &cell, uint dofs_per_cell, uint n_extractors)
123 {
124 cell_jacobian.reinit(dofs_per_cell, dofs_per_cell);
125 if (n_extractors > 0) extractor_cell_jacobian.reinit(dofs_per_cell, n_extractors);
126 cell_mass_jacobian.reinit(dofs_per_cell, dofs_per_cell);
127 local_dof_indices.resize(dofs_per_cell);
128 cell->get_dof_indices(local_dof_indices);
129 }
130 };
131
132 template <typename NumberType> struct CopyData_I {
134 std::array<uint, 2> cell_indices;
135 std::array<double, 2> values;
136 };
137 std::vector<CopyFaceData_I> face_data;
138 double value;
140 };
141 } // namespace internal
142
143 template <typename Discretization_, typename Model_>
145 class Assembler : public AbstractAssembler<typename Discretization_::VectorType,
146 typename Discretization_::SparseMatrixType, Discretization_::dim>
147 {
148 protected:
149 template <typename... T> auto fv_tie(T &&...t)
150 {
151 return named_tuple<std::tuple<T &...>, "fe_functions">(std::tie(t...));
152 }
153
154 template <typename... T> static constexpr auto v_tie(T &&...t)
155 {
156 return named_tuple<std::tuple<T &...>, "variables", "extractors">(std::tie(t...));
157 }
158
159 template <typename... T> static constexpr auto e_tie(T &&...t)
160 {
161 return named_tuple<std::tuple<T &...>, "fe_functions", "fe_derivatives", "fe_hessians", "extractors",
162 "variables">(std::tie(t...));
163 }
164
165 public:
166 using Discretization = Discretization_;
167 using Model = Model_;
170
172 static constexpr uint dim = Discretization::dim;
173 static constexpr uint n_components = Components::count_fe_functions(0);
174
177 mapping(discretization.get_mapping()), triangulation(discretization.get_triangulation()), json(json),
178 threads(json.get_uint("/discretization/threads")),
179 batch_size(json.get_uint("/discretization/batch_size")),
180 EoM_abs_tol(json.get_double("/discretization/EoM_abs_tol")),
181 EoM_max_iter(json.get_uint("/discretization/EoM_max_iter")),
182 quadrature(1 + json.get_uint("/discretization/overintegration"))
183 {
184 if (this->threads == 0) this->threads = dealii::MultithreadInfo::n_threads() / 2;
185 spdlog::get("log")->info("FV: Using {} threads for assembly.", threads);
186
187 reinit();
188 }
189
190 virtual void reinit_vector(VectorType &vec) const override
191 {
192 const auto block_structure = discretization.get_block_structure();
193 vec.reinit(block_structure[0]);
194 }
195
196 virtual IndexSet get_differential_indices() const override { return IndexSet(); }
197
198 virtual void attach_data_output(DataOutput<dim, VectorType> &data_out, const VectorType &solution,
199 const VectorType &variables, const VectorType &dt_solution = VectorType(),
200 const VectorType &residual = VectorType())
201 {
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");
209
210 auto &fe_out = data_out.fe_output();
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);
213 if (residual.size() > 0) fe_out.attach(dof_handler, residual, fe_function_names_residual);
214
215 // readouts(data_out, solution, variables);
216 }
217
218 virtual void reinit() override
219 {
220 Timer timer;
221
222 // Mass sparsity pattern is diagonal
223 auto dynamic_sparsity_pattern_mass = DynamicSparsityPattern(dof_handler.n_dofs());
224 for (uint i = 0; i < dof_handler.n_dofs(); ++i)
225 dynamic_sparsity_pattern_mass.add(i, i);
226 sparsity_pattern_mass.copy_from(dynamic_sparsity_pattern_mass);
227
228 mass_matrix = SparseMatrix<NumberType>(sparsity_pattern_mass, IdentityMatrix(dof_handler.n_dofs()));
229
230 constexpr uint stencil = 1;
232
233 timings_reinit.push_back(timer.wall_time());
234 }
235
236 virtual void set_time(double t) override { model.set_time(t); }
237
238 virtual const SparsityPattern &get_sparsity_pattern_jacobian() const override
239 {
241 }
242 virtual const SparseMatrix<NumberType> &get_mass_matrix() const override { return mass_matrix; }
243
244 virtual void residual_variables(VectorType &residual, const VectorType &variables, const VectorType &) override
245 {
246 model.dt_variables(residual, fv_tie(variables));
247 };
248
249 virtual void jacobian_variables(FullMatrix<NumberType> &jacobian, const VectorType &variables,
250 const VectorType &) override
251 {
252 model.template jacobian_variables<0>(jacobian, fv_tie(variables));
253 };
254
255 void readouts(DataOutput<dim, VectorType> &data_out, const VectorType &, const VectorType &variables) const
256 {
257 auto helper = [&](auto EoMfun, auto outputter) {
258 (void)EoMfun;
259 outputter(data_out, Point<0>(), fv_tie(variables));
260 };
261 model.template readouts_multiple(helper, data_out);
262 }
263
264 virtual void mass(VectorType &mass, const VectorType &solution_global, const VectorType &solution_global_dot,
265 NumberType weight) override
266 {
267 using Iterator = typename DoFHandler<dim>::active_cell_iterator;
269 using CopyData = internal::CopyData_R<NumberType>;
270 const auto &constraints = discretization.get_constraints();
271
272 const auto cell_worker = [&](const Iterator &cell, Scratch &scratch_data, CopyData &copy_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();
276
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();
281
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);
286
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]);
291
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) *
296 mass[component_i]; // +phi_i(x_q) * mass(x_q, u_q)
297 }
298 }
299 };
300 const auto copier = [&](const CopyData &c) {
301 constraints.distribute_local_to_global(c.cell_residual, c.local_dof_indices, mass);
302 };
303
304 Scratch scratch_data(mapping, discretization.get_fe(), quadrature);
305 CopyData copy_data;
306 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
307
308 MeshWorker::mesh_loop(dof_handler.begin_active(), dof_handler.end(), cell_worker, copier, scratch_data,
309 copy_data, flags, nullptr, nullptr, threads, batch_size);
310 }
311
312 virtual void residual(VectorType &residual, const VectorType &solution_global, NumberType weight,
313 const VectorType &solution_global_dot, NumberType weight_mass,
314 const VectorType &variables = VectorType()) override
315 {
316 using Iterator = typename DoFHandler<dim>::active_cell_iterator;
318 using CopyData = internal::CopyData_R<NumberType>;
319 const auto &constraints = discretization.get_constraints();
320
321 const auto cell_worker = [&](const Iterator &cell, Scratch &scratch_data, CopyData &copy_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();
325
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();
330
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);
335
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]));
342
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) *
347 mass[component_i]; // +phi_i(x_q) * mass(x_q, u_q)
348 copy_data.cell_residual(i) += JxW[q_index] * weight * // dx *
349 (fe_v.shape_value_component(i, q_index, component_i) *
350 source[component_i]); // -phi_i(x_q) * source(x_q, u_q)
351 }
352 }
353 };
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);
357 };
358
359 Scratch scratch_data(mapping, discretization.get_fe(), quadrature);
360 CopyData copy_data;
361 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
362
363 Timer timer;
364 MeshWorker::mesh_loop(dof_handler.begin_active(), dof_handler.end(), cell_worker, copier, scratch_data,
365 copy_data, flags, nullptr, nullptr, threads, batch_size);
366 timings_residual.push_back(timer.wall_time());
367 }
368
369 virtual void jacobian_mass(SparseMatrix<NumberType> &jacobian, const VectorType &solution_global,
370 const VectorType &solution_global_dot, NumberType alpha = 1.,
371 NumberType beta = 1.) override
372 {
373 using Iterator = typename DoFHandler<dim>::active_cell_iterator;
375 using CopyData = internal::CopyData_J<NumberType>;
376 const auto &constraints = discretization.get_constraints();
377
378 const auto cell_worker = [&](const Iterator &cell, Scratch &scratch_data, CopyData &copy_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();
382
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();
387
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);
392
395 for (const auto &q_index : q_indices) {
396 const auto &x_q = q_points[q_index];
397 model.template jacobian_mass<0>(j_mass, x_q, solution[q_index], solution_dot[q_index]);
398 model.template jacobian_mass<1>(j_mass_dot, x_q, solution[q_index], solution_dot[q_index]);
399
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));
408 }
409 }
410 }
411 };
412 const auto copier = [&](const CopyData &c) {
413 constraints.distribute_local_to_global(c.cell_jacobian, c.local_dof_indices, jacobian);
414 };
415
416 Scratch scratch_data(mapping, discretization.get_fe(), quadrature);
417 CopyData copy_data;
418 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
419
420 Timer timer;
421 MeshWorker::mesh_loop(dof_handler.begin_active(), dof_handler.end(), cell_worker, copier, scratch_data,
422 copy_data, flags, nullptr, nullptr, threads, batch_size);
423 timings_jacobian.push_back(timer.wall_time());
424 }
425
426 virtual void jacobian(SparseMatrix<NumberType> &jacobian, const VectorType &solution_global, NumberType weight,
427 const VectorType &solution_global_dot, NumberType alpha, NumberType beta,
428 const VectorType &variables = VectorType()) override
429 {
430 using Iterator = typename DoFHandler<dim>::active_cell_iterator;
432 using CopyData = internal::CopyData_J<NumberType>;
433 const auto &constraints = discretization.get_constraints();
434
435 const auto cell_worker = [&](const Iterator &cell, Scratch &scratch_data, CopyData &copy_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();
439
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();
444
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);
449
453 for (const auto &q_index : q_indices) {
454 const auto &x_q = q_points[q_index];
455 model.template jacobian_mass<0>(j_mass, x_q, solution[q_index], solution_dot[q_index]);
456 model.template jacobian_mass<1>(j_mass_dot, x_q, solution[q_index], solution_dot[q_index]);
457 model.template jacobian_source<0, 0>(j_source, x_q, fv_tie(solution[q_index]));
458
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) * // dx * phi_j * (
465 (fe_v.shape_value_component(i, q_index, component_i) *
466 j_source(component_i, component_j)); // -phi_i * jsource)
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));
471 }
472 }
473 }
474 };
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);
478 };
479
480 Scratch scratch_data(mapping, discretization.get_fe(), quadrature);
481 CopyData copy_data;
482 MeshWorker::AssembleFlags flags = MeshWorker::assemble_own_cells;
483
484 Timer timer;
485 MeshWorker::mesh_loop(dof_handler.begin_active(), dof_handler.end(), cell_worker, copier, scratch_data,
486 copy_data, flags, nullptr, nullptr, threads, batch_size);
487 timings_jacobian.push_back(timer.wall_time());
488 }
489
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
493 {
494 const auto &triangulation = discretization.get_triangulation();
495
496 DynamicSparsityPattern dsp(dof_handler.n_dofs(), dof_handler.n_dofs());
497
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;
500
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);
508
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);
515
516 if (dim == 1)
517 while (neighbor_cell->has_children())
518 neighbor_cell = neighbor_cell->child(face_no == 0 ? 1 : 0);
519
520 // add all children
521 else if (neighbor_cell->has_children()) {
522 throw std::runtime_error("not yet implemented lol");
523 }
524
525 if (!neighbor_cell->is_active()) continue;
526
527 std::vector<types::global_dof_index> tmp(from_dofs_per_cell);
528 neighbor_cell->get_dof_indices(tmp);
529
530 from_dofs.insert(std::end(from_dofs), std::begin(tmp), std::end(tmp));
531
532 if (stencil_level < stencil) add_all_neighbor_dofs(neighbor_cell, stencil_level + 1);
533 }
534 }
535 };
536
537 add_all_neighbor_dofs(from_cell, 1);
538
539 for (const auto i : to_dofs)
540 for (const auto j : from_dofs)
541 dsp.add(i, j);
542 }
543
544 // if (add_extractor_dofs)
545 // for (uint row = 0; row < dsp.n_rows(); ++row)
546 // dsp.add_row_entries(row, extractor_dof_indices);
547 sparsity_pattern.copy_from(dsp);
548 }
549
550 void log(const std::string logger)
551 {
552 std::stringstream ss;
553 ss << "FV Assembler: " << std::endl;
554 ss << " Reinit: " << average_time_reinit() * 1000 << "ms (" << num_reinits() << ")" << std::endl;
555 ss << " Residual: " << average_time_residual_assembly() * 1000 << "ms (" << num_residuals() << ")"
556 << std::endl;
557 ss << " Jacobian: " << average_time_jacobian_assembly() * 1000 << "ms (" << num_jacobians() << ")"
558 << std::endl;
559 spdlog::get(logger)->info(ss.str());
560 }
561
562 double average_time_reinit() const
563 {
564 double t = 0.;
565 double n = timings_reinit.size();
566 for (const auto &t_ : timings_reinit)
567 t += t_ / n;
568 return t;
569 }
570 uint num_reinits() const { return timings_reinit.size(); }
571
573 {
574 double t = 0.;
575 double n = timings_residual.size();
576 for (const auto &t_ : timings_residual)
577 t += t_ / n;
578 return t;
579 }
580 uint num_residuals() const { return timings_residual.size(); }
581
583 {
584 double t = 0.;
585 double n = timings_jacobian.size();
586 for (const auto &t_ : timings_jacobian)
587 t += t_ / n;
588 return t;
589 }
590 uint num_jacobians() const { return timings_jacobian.size(); }
591
592 protected:
595 const DoFHandler<dim> &dof_handler;
596 const Mapping<dim> &mapping;
597 const Triangulation<dim> &triangulation;
598
600
603
604 mutable typename Triangulation<dim>::cell_iterator EoM_cell;
605 typename Triangulation<dim>::cell_iterator old_EoM_cell;
606 const double EoM_abs_tol;
608
609 const QGauss<dim> quadrature;
610
611 SparsityPattern sparsity_pattern_mass;
613 SparseMatrix<NumberType> mass_matrix;
614
615 std::vector<double> timings_reinit;
616 std::vector<double> timings_residual;
617 std::vector<double> timings_jacobian;
618 };
619 } // namespace KurganovTadmor
620 } // namespace FV
621} // namespace DiFfRG
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
size_t size() const
A simple NxM-matrix class, which is used for cell-wise Jacobians.
Definition tuples.hh:153
Definition types.hh:6
Definition complex_math.hh:14
unsigned int uint
Definition utils.hh:22
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
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
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
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