138 * #include <deal.II/base/
numbers.h>
139 * #include <deal.II/base/thread_management.h>
140 * #include <deal.II/grid/tria.h>
141 * #include <deal.II/dofs/dof_handler.h>
142 * #include <deal.II/grid/grid_generator.h>
143 * #include <deal.II/grid/tria_accessor.h>
144 * #include <deal.II/grid/tria_iterator.h>
145 * #include <deal.II/dofs/dof_accessor.h>
146 * #include <deal.II/dofs/dof_renumbering.h>
147 * #include <deal.II/fe/fe_q.h>
148 * #include <deal.II/fe/fe_dgq.h>
149 * #include <deal.II/fe/fe_system.h>
150 * #include <deal.II/dofs/dof_tools.h>
151 * #include <deal.II/fe/fe_values.h>
152 * #include <deal.II/base/quadrature_lib.h>
153 * #include <deal.II/base/function.h>
154 * #include <deal.II/numerics/vector_tools.h>
155 * #include <deal.II/numerics/matrix_tools.h>
156 * #include <deal.II/numerics/derivative_approximation.h>
157 * #include <deal.II/lac/block_vector.h>
158 * #include <deal.II/lac/full_matrix.h>
159 * #include <deal.II/lac/block_sparse_matrix.h>
160 * #include <deal.II/lac/block_sparsity_pattern.h>
161 * #include <deal.II/lac/sparse_direct.h>
162 * #include <deal.II/particles/particle_handler.h>
163 * #include <deal.II/particles/data_out.h>
165 * #include <deal.II/numerics/data_out.h>
167 * #include <iostream>
169 * #include <deal.II/base/logstream.h>
170 * #include <deal.II/grid/grid_refinement.h>
177 * The following is the main
class. It resembles a variation of the @ref step_6
"step-6"
178 * principal
class, with the addition of information-specific stuff. It also
179 * has to deal with solving a vector-valued problem
for (c,lambda,f) as
180 * primal variable, dual variable, and right hand side, as explained
185 *
class InformationDensityMeshRefinement
188 * InformationDensityMeshRefinement ();
192 *
void compute_synthetic_measurements();
193 *
void bounce_measurement_points_to_cell_centers ();
194 *
void setup_system();
195 *
void assemble_system ();
197 *
void compute_information_content ();
198 *
void output_results (
const unsigned int cycle)
const;
199 *
void refine_grid ();
202 *
const double source_radius;
204 * std::vector<Point<dim>> detector_locations;
206 *
const double regularization_parameter;
223 * std::vector<Point<dim>> detector_locations_on_mesh;
224 * std::vector<double> measurement_values;
225 * std::vector<double> noise_level;
232 * InformationDensityMeshRefinement<dim>::InformationDensityMeshRefinement ()
235 * source_radius (0.2),
236 * regularization_parameter (10000),
246 * We have 50 detector points on an outer ring...
249 *
for (
unsigned int i=0; i<50; ++i)
253 * detector_locations.push_back (p);
258 * ...and another 50 detector points on an innner ring:
261 *
for (
unsigned int i=0; i<50; ++i)
265 * detector_locations.push_back (p);
270 * Generate the grid we will work on:
278 * The detector locations are
static, so we can already here
279 * generate a file that contains their locations. We use the
280 * particle framework to
do this,
using detector locations as
281 * particle locations.
287 *
for (
const auto &loc : detector_locations)
290 * new_particle.set_location(loc);
293 * Insert the particle. It is a lie that the particle is in
294 * the
first cell, but
nothing we
do actually cares about the
295 * cell a particle is in.
298 * particle_handler.insert_particle(new_particle,
304 * std::ofstream output(
"detector_locations.vtu");
305 * particle_out.write_vtu(output);
310 * While we
're generating output, also output the source location. Do this
311 * by outputting many (1000) points that indicate the perimeter of the source
315 * Particles::ParticleHandler<dim> particle_handler(triangulation,
316 * StaticMappingQ1<dim>::mapping);
318 * const unsigned int n_points = 1000;
319 * for (unsigned int i=0; i<n_points; ++i)
321 * Point<dim> loc = source_location;
322 * loc[0] += source_radius * std::cos(2*numbers::PI*i/n_points);
323 * loc[1] += source_radius * std::sin(2*numbers::PI*i/n_points);
325 * Particles::Particle<dim> new_particle;
326 * new_particle.set_location(loc);
327 * particle_handler.insert_particle(new_particle,
328 * triangulation.begin_active());
331 * Particles::DataOut<dim> particle_out;
332 * particle_out.build_patches(particle_handler);
333 * std::ofstream output("source_locations.vtu");
334 * particle_out.write_vtu(output);
342 * The following function solves a forward problem on a twice
343 * refined mesh to compute "synthetic data". Refining the mesh
344 * beyond the mesh used for the inverse problem avoids an
349 * void InformationDensityMeshRefinement<dim>::compute_synthetic_measurements ()
351 * std::cout << "Computing synthetic data by solving the forward problem..."
356 * Create a triangulation and DoFHandler that corresponds to a
357 * twice-refined mesh so that we obtain the synthetic data with
358 * higher accuracy than we do on the regular mesh used for all other
362 * Triangulation<dim> forward_triangulation;
363 * forward_triangulation.copy_triangulation (triangulation);
364 * forward_triangulation.refine_global (2);
366 * const FE_Q<dim> forward_fe (fe.base_element(0).degree);
367 * DoFHandler<dim> forward_dof_handler (forward_triangulation);
368 * forward_dof_handler.distribute_dofs (forward_fe);
370 * AffineConstraints<double> constraints;
371 * DoFTools::make_hanging_node_constraints(forward_dof_handler, constraints);
372 * constraints.close();
374 * SparsityPattern sparsity (forward_dof_handler.n_dofs(),
375 * forward_dof_handler.max_couplings_between_dofs());
376 * DoFTools::make_sparsity_pattern (forward_dof_handler, sparsity);
377 * constraints.condense (sparsity);
378 * sparsity.compress ();
380 * SparseMatrix<double> system_matrix (sparsity);
381 * Vector<double> system_rhs (forward_dof_handler.n_dofs());
383 * QGauss<dim> quadrature_formula(3);
384 * FEValues<dim> fe_values (forward_fe, quadrature_formula,
385 * update_values | update_gradients |
386 * update_quadrature_points | update_JxW_values);
388 * const unsigned int dofs_per_cell = forward_fe.dofs_per_cell;
389 * const unsigned int n_q_points = quadrature_formula.size();
393 * First assemble the system matrix and right hand side for the forward
398 * FullMatrix<double> cell_matrix (dofs_per_cell, dofs_per_cell);
399 * Vector<double> cell_rhs (dofs_per_cell);
400 * std::vector<unsigned int> local_dof_indices (dofs_per_cell);
402 * for (const auto &cell : forward_dof_handler.active_cell_iterators())
404 * fe_values.reinit (cell);
408 * for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
409 * for (unsigned int i=0; i<dofs_per_cell; ++i)
410 * for (unsigned int j=0; j<dofs_per_cell; ++j)
411 * cell_matrix(i,j) += (fe_values.shape_grad(i,q_point) *
412 * fe_values.shape_grad(j,q_point)
414 * fe_values.shape_value(i,q_point) *
415 * (velocity * fe_values.shape_grad(j,q_point))
418 * fe_values.JxW(q_point);
419 * for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
420 * if (fe_values.quadrature_point(q_point).distance (source_location)
422 * for (unsigned int i=0; i<dofs_per_cell; ++i)
425 * fe_values.shape_value (i, q_point) *
426 * fe_values.JxW(q_point);
428 * cell->get_dof_indices (local_dof_indices);
429 * constraints.distribute_local_to_global (cell_matrix,
436 * std::map<unsigned int, double> boundary_values;
437 * VectorTools::interpolate_boundary_values (forward_dof_handler,
439 * Functions::ZeroFunction<dim>(),
441 * Vector<double> tmp (forward_dof_handler.n_dofs());
442 * MatrixTools::apply_boundary_values (boundary_values,
450 * Solve the forward problem and output it into its own VTU file :
453 * SparseDirectUMFPACK A_inverse;
454 * Vector<double> forward_solution (forward_dof_handler.n_dofs());
455 * forward_solution = system_rhs;
456 * A_inverse.solve(system_matrix, forward_solution);
458 * const double max_forward_solution = forward_solution.linfty_norm();
461 * DataOut<dim> data_out;
462 * data_out.attach_dof_handler (forward_dof_handler);
463 * data_out.add_data_vector (forward_solution, "c");
464 * data_out.build_patches (4);
466 * std::ofstream out ("forward-solution.vtu");
467 * data_out.write_vtu (out);
472 * Now evaluate the forward solution at the measurement points:
475 * for (const auto &p : detector_locations)
479 * same 10% noise level for all points
482 * noise_level.push_back (0.1 * max_forward_solution);
484 * const double z_n = VectorTools::point_value(forward_dof_handler, forward_solution, p);
485 * const double eps_n = Utilities::generate_normal_random_number(0, noise_level.back());
487 * measurement_values.push_back (z_n + eps_n);
490 * std::cout << std::endl;
496 * It will make our lives easier if we can always assume that detector
497 * locations are at cell centers, because then we can evaluate the
498 * solution there using a quadrature formula whose sole quadrature
499 * point lies at the center of a cell. That's of course not where the
500 *
"real" detector locations are, but it does not introduce a large
505 *
void InformationDensityMeshRefinement<dim>::bounce_measurement_points_to_cell_centers ()
507 * detector_locations_on_mesh = detector_locations;
508 *
for (
auto &p : detector_locations_on_mesh)
510 * for (const auto &cell :
triangulation.active_cell_iterators())
511 * if (cell->point_inside (p))
522 * The following
functions are all quite standard by what we have
523 * shown in @ref step_4
"step-4", @ref step_6
"step-6", and @ref step_22
"step-22" (to name just a few of the
524 * more typical programs):
528 * void InformationDensityMeshRefinement<dim>::setup_system ()
530 *
std::cout <<
"Setting up the linear system for the inverse problem..."
533 * dof_handler.distribute_dofs (fe);
536 * hanging_node_constraints.clear ();
538 * hanging_node_constraints);
539 * hanging_node_constraints.close();
541 * std::cout <<
" Number of active cells: "
544 * std::cout <<
" Number of degrees of freedom: "
545 * << dof_handler.n_dofs()
548 *
const std::vector<types::global_dof_index> dofs_per_component =
552 * hanging_node_constraints.condense(c_sparsity);
553 * sparsity_pattern.copy_from(c_sparsity);
555 * system_matrix.reinit (sparsity_pattern);
557 * solution.reinit (dofs_per_component);
558 * system_rhs.reinit (dofs_per_component);
564 *
void InformationDensityMeshRefinement<dim>::assemble_system ()
566 * std::cout <<
"Assembling the linear system for the inverse problem..."
575 *
const unsigned int dofs_per_cell = fe.dofs_per_cell;
576 *
const unsigned int n_q_points = quadrature_formula.size();
581 * std::vector<unsigned int> local_dof_indices (dofs_per_cell);
585 *
for (
const auto &cell : dof_handler.active_cell_iterators())
587 * fe_values.
reinit (cell);
591 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
592 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
594 *
const Tensor<1,dim> grad_phi_i = fe_values[c].gradient (i,q_point);
597 *
const double phi_i = fe_values[c].value (i,q_point);
598 *
const double psi_i = fe_values[
lambda].value (i,q_point);
599 *
const double chi_i = fe_values[f].value (i,q_point);
601 *
for (
unsigned int j=0; j<dofs_per_cell; ++j)
603 *
const Tensor<1,dim> grad_phi_j = fe_values[c].gradient (j,q_point);
606 *
const double phi_j = fe_values[c].value (j,q_point);
607 *
const double psi_j= fe_values[
lambda].value (j,q_point);
608 *
const double chi_j = fe_values[f].value (j,q_point);
611 * ((grad_phi_i * grad_phi_j
613 * phi_i * (velocity * grad_phi_j)
617 * grad_psi_i * grad_psi_j
619 * psi_i * (velocity * grad_psi_j)
623 * regularization_parameter * chi_i * chi_j
625 * fe_values.JxW (q_point));
627 *
for (
unsigned int n=0; n< detector_locations_on_mesh.size(); ++n)
628 *
if (fe_values.quadrature_point(q_point).distance (detector_locations_on_mesh[n]) < 1e-12)
630 *
cell_matrix(i,j) += psi_i * phi_j / noise_level[n] / noise_level[n];
634 *
for (
unsigned int n=0; n< detector_locations_on_mesh.size(); ++n)
635 *
if (fe_values.quadrature_point(q_point).distance (detector_locations_on_mesh[n]) < 1e-12)
636 * cell_rhs(i) += psi_i * measurement_values[n] / noise_level[n] / noise_level[n];
639 * cell->get_dof_indices (local_dof_indices);
640 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
642 *
for (
unsigned int j=0; j<dofs_per_cell; ++j)
643 * system_matrix.add (local_dof_indices[i],
644 * local_dof_indices[j],
647 * system_rhs(local_dof_indices[i]) += cell_rhs(i);
651 * hanging_node_constraints.condense (system_matrix);
652 * hanging_node_constraints.condense (system_rhs);
654 * std::map<unsigned int,double> boundary_values;
655 * std::vector<bool> component_mask (3);
656 * component_mask[0] = component_mask[1] =
true;
657 * component_mask[2] =
false;
668 * std::cout << std::endl;
674 *
void InformationDensityMeshRefinement<dim>::solve ()
676 * std::cout <<
"Solving the linear system for the inverse problem..."
680 * solution = system_rhs;
681 * A_direct.
solve(system_matrix, solution);
683 * hanging_node_constraints.distribute (solution);
685 * std::cout << std::endl;
692 * This is really the only interesting function of
this program. It
693 * computes the
functions @f$h_K = A^{-1} s_K@f$
for each source function
694 * (corresponding to each cell of the mesh). To
do so, it
first
696 *
class to build an LU decomposition
for this matrix. Then it loops
697 * over all cells @f$K@f$ and computes the corresponding @f$h_K@f$ by applying
698 * the LU decomposition to a right hand side vector
for each @f$s_K@f$.
702 * The actual information content is then computed by evaluating these
703 * functions @f$h_K@f$ at measurement locations.
707 *
void InformationDensityMeshRefinement<dim>::compute_information_content ()
709 * std::cout <<
"Computing the information content..."
714 *
const FE_Q<dim> information_fe (fe.base_element(0).degree);
716 * information_dof_handler.distribute_dofs (information_fe);
720 * constraints.close();
723 * information_dof_handler.max_couplings_between_dofs());
725 * constraints.condense (sparsity);
726 * sparsity.compress ();
732 *
const unsigned int dofs_per_cell = information_fe.dofs_per_cell;
733 *
const unsigned int n_q_points = quadrature_formula.size();
737 * First build the forward
operator
741 *
FEValues<dim> fe_values (information_fe, quadrature_formula,
746 * std::vector<unsigned int> local_dof_indices (dofs_per_cell);
748 *
for (
const auto &cell : information_dof_handler.active_cell_iterators())
750 * fe_values.
reinit (cell);
753 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
754 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
755 *
for (
unsigned int j=0; j<dofs_per_cell; ++j)
756 *
cell_matrix(i,j) += (fe_values.shape_grad (i,q_point) *
757 * fe_values.shape_grad(j,q_point)
759 * fe_values.shape_value(i,q_point) *
760 * (velocity * fe_values.shape_grad(j,q_point))) *
761 * fe_values.JxW(q_point);
763 * cell->distribute_local_to_global (cell_matrix,
767 * constraints.condense (system_matrix);
769 * std::map<unsigned int, double> boundary_values;
791 * Now compute the solutions corresponding to the possible
792 * sources. Each source is active on exactly one cell.
796 * As mentioned in the paper,
this is a trivially
parallel job, so
797 * we send the computations
for each of these cells onto a separate
798 * task and let the OS schedule them onto individual processor
809 * std::vector<unsigned int> local_dof_indices (dofs_per_cell);
812 * cell = information_dof_handler.begin_active();
813 * std::advance (cell, K);
815 *
FEValues<dim> fe_values (information_fe, quadrature_formula,
819 * fe_values.reinit (cell);
822 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
823 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
824 * cell_rhs(i) += fe_values.shape_value (i,q_point) *
825 * fe_values.JxW(q_point);
827 * cell->distribute_local_to_global (cell_rhs,
830 * constraints.condense (rhs);
832 * A_inverse.solve(rhs);
834 * constraints.distribute (rhs);
838 * Having computed the forward solutions
839 * corresponding to
this source term, evaluate its
840 * contribution to the information content on all
841 * cells of the mesh by taking into account the
842 * detector locations. We add these into global
843 * objects, so we have to guard access to the
847 *
static std::mutex m;
848 * std::lock_guard<std::mutex> g(m);
851 * information_content(K) = regularization_parameter * cell->measure() * cell->measure();
852 * std::vector<double> local_h_K_values (n_q_points);
853 *
for (
const auto &cell : information_dof_handler.active_cell_iterators())
855 * fe_values.
reinit (cell);
856 * fe_values.get_function_values (rhs, local_h_K_values);
858 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
859 *
for (
unsigned int n=0; n< detector_locations_on_mesh.size(); ++n)
860 *
if (fe_values.quadrature_point(q_point).distance (detector_locations_on_mesh[n]) < 1e-12)
861 * information_content(K) += local_h_K_values[q_point]
862 * * local_h_K_values[q_point]
863 * / noise_level[n] / noise_level[n];
875 * std::cout << std::endl;
882 * Create graphical output
for all of the principal variables of the
883 * problem (c,lambda,f) as well as
for the information content and
884 * density. Then also output the various blocks of the
matrix so we
889 *
void InformationDensityMeshRefinement<dim>::output_results (
const unsigned int cycle)
const
891 * std::cout <<
"Outputting solutions..." << std::flush;
895 * std::vector<std::string> names;
896 * names.push_back (
"forward_solution");
897 * names.push_back (
"adjoint_solution");
898 * names.push_back (
"recovered_parameter");
901 * data_out.add_data_vector (solution, names);
902 * data_out.add_data_vector (information_content,
"information_content");
905 *
for (
const auto &cell :
triangulation.active_cell_iterators())
906 * information_density(cell->active_cell_index())
907 * =
std::
sqrt(information_content(cell->active_cell_index())) / cell->measure();
908 * data_out.add_data_vector (information_density,
"information_density");
910 * data_out.build_patches ();
912 * std::string filename =
"solution-";
913 * filename += (
'0'+cycle);
914 * filename +=
".vtu";
916 * std::ofstream output (filename.c_str());
917 * data_out.write_vtu (output);
922 * Now output the individual blocks of the
matrix into files.
925 *
auto write_block = [&](
const unsigned int block_i,
926 *
const unsigned int block_j,
927 *
const std::string &filename)
929 * std::ofstream o(filename);
930 * system_matrix.block(block_i,block_j).print (o);
932 * write_block(0,0,
"matrix-" + std::to_string(cycle) +
"-A.txt");
933 * write_block(0,2,
"matrix-" + std::to_string(cycle) +
"-B.txt");
934 * write_block(1,0,
"matrix-" + std::to_string(cycle) +
"-C.txt");
935 * write_block(2,2,
"matrix-" + std::to_string(cycle) +
"-M.txt");
937 * std::cout << std::endl;
944 * The following is then a function that refines the mesh based on the
945 * refinement criteria described in the paper. Which criterion to use
946 * is determined by which
value the `refinement_criterion` variable
951 *
void InformationDensityMeshRefinement<dim>::refine_grid ()
953 * std::cout <<
"Refining the mesh..." << std::endl;
955 *
enum RefinementCriterion
958 * information_content,
962 *
const RefinementCriterion refinement_criterion = information_content;
964 *
switch (refinement_criterion)
972 *
case information_content:
975 * this->information_content,
990 * std::vector<double> lambda_values (quadrature.size());
991 * std::vector<double> f_values (quadrature.size());
993 *
for (
const auto &cell : dof_handler.active_cell_iterators())
995 * fe_values.
reinit (cell);
996 * fe_values[
lambda].get_function_values (solution, lambda_values);
997 * fe_values[f].get_function_values (solution, f_values);
999 *
for (
unsigned int q=0; q<quadrature.size(); ++q)
1000 * refinement_indicators(cell->active_cell_index())
1001 * += (std::fabs (regularization_parameter * f_values[q]
1004 * * fe_values.JxW(q));
1008 * refinement_indicators,
1021 * refinement_indicators,
1025 * and
scale it to obtain an error indicator.
1028 *
for (
const auto &cell :
triangulation.active_cell_iterators())
1029 * refinement_indicators[cell->active_cell_index()] *=
1034 * refinement_indicators,
1041 *
Assert (
false, ExcInternalError());
1044 * bounce_measurement_points_to_cell_centers ();
1047 * std::cout << std::endl;
1053 *
template <
int dim>
1054 *
void InformationDensityMeshRefinement<dim>::run ()
1056 * std::cout <<
"Solving problem in " << dim <<
" space dimensions." << std::endl;
1058 * compute_synthetic_measurements ();
1059 * bounce_measurement_points_to_cell_centers ();
1061 *
for (
unsigned int cycle=0; cycle<7; ++cycle)
1063 * std::cout <<
"---------- Cycle " << cycle <<
" ------------" << std::endl;
1066 * assemble_system ();
1068 * compute_information_content ();
1069 * output_results (cycle);
1082 * InformationDensityMeshRefinement<2> information_density_mesh_refinement;
1083 * information_density_mesh_refinement.run ();
1085 *
catch (std::exception &exc)
1087 * std::cerr << std::endl << std::endl
1088 * <<
"----------------------------------------------------"
1090 * std::cerr <<
"Exception on processing: " << std::endl
1091 * << exc.what() << std::endl
1092 * <<
"Aborting!" << std::endl
1093 * <<
"----------------------------------------------------"
1100 * std::cerr << std::endl << std::endl
1101 * <<
"----------------------------------------------------"
1103 * std::cerr <<
"Unknown exception!" << std::endl
1104 * <<
"Aborting!" << std::endl
1105 * <<
"----------------------------------------------------"
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
unsigned int depth_console(const unsigned int n)
void build_patches(const Particles::ParticleHandler< dim, spacedim > &particles, const std::vector< std::string > &data_component_names={}, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretations={})
void solve(Vector< double > &rhs_and_solution, const bool transpose=false) const
void factorize(const Matrix &matrix)
unsigned int n_active_cells() const
void refine_global(const unsigned int times=1)
active_cell_iterator begin_active(const unsigned int level=0) const
virtual void execute_coarsening_and_refinement() override
__global__ void set(Number *val, const Number s, const size_type N)
#define Assert(cond, exc)
typename ActiveSelector::active_cell_iterator active_cell_iterator
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
Task< RT > new_task(const std::function< RT()> &function)
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
void approximate_gradient(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const InputVector &solution, Vector< float > &derivative_norm, const unsigned int component=0)
void component_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void refine_and_coarsen_fixed_number(Triangulation< dim, spacedim > &triangulation, const Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max())
@ matrix
Contents is actually a matrix.
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
int(& functions)(const void *v1, const void *v2)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
static constexpr double PI
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)