12 #ifndef StaticVectorSolverII_H__
13 #define StaticVectorSolverII_H__
15 #include <deal.II/base/exceptions.h>
16 #include <deal.II/base/tensor.h>
17 #include <deal.II/base/thread_management.h>
18 #include <deal.II/base/timer.h>
19 #include <deal.II/base/types.h>
20 #include <deal.II/base/work_stream.h>
22 #include <deal.II/grid/tria.h>
24 #include <deal.II/dofs/dof_handler.h>
25 #include <deal.II/dofs/dof_renumbering.h>
26 #include <deal.II/dofs/dof_tools.h>
28 #include <deal.II/fe/fe_nedelec.h>
29 #include <deal.II/fe/fe_values.h>
31 #include <deal.II/lac/affine_constraints.h>
32 #include <deal.II/lac/dynamic_sparsity_pattern.h>
33 #include <deal.II/lac/precondition.h>
34 #include <deal.II/lac/solver_cg.h>
35 #include <deal.II/lac/solver_control.h>
36 #include <deal.II/lac/sparse_matrix.h>
37 #include <deal.II/lac/vector.h>
39 #include <deal.II/numerics/data_out.h>
40 #include <deal.II/numerics/vector_tools.h>
41 #include <deal.II/numerics/vector_tools_common.h>
42 #include <deal.II/numerics/vector_tools_project.h>
50 #include "constants.hpp"
51 #include "settings.hpp"
52 #include "static_vector_input.hpp"
54 #define VE scratch_data.ve
55 #define SE scratch_data.se
57 #define TMR(__name) TimerOutput::Scope timer_section(timer, __name)
59 using namespace dealii;
61 namespace StaticVectorSolver {
222 template<
int dim,
int stage = 1>
266 unsigned int mapping_degree,
267 const Triangulation<dim>& triangulation_T,
268 const DoFHandler<dim>& dof_handler_T,
269 const Vector<double>& solution_T,
270 unsigned int type_of_pde_rhs = 0,
271 double eta_squared = 0.0,
272 std::string fname =
"data",
273 const Function<dim>* exact_solution =
nullptr,
274 bool print_time_tables =
false,
275 bool project_exact_solution =
false,
276 bool write_higher_order_cells =
false)
277 : triangulation_T(triangulation_T)
278 , dof_handler_T(dof_handler_T)
279 , solution_T(solution_T)
288 , mapping_degree(mapping_degree)
289 , type_of_pde_rhs(type_of_pde_rhs)
290 , eta_squared(eta_squared)
292 , exact_solution(exact_solution)
293 , print_time_tables(print_time_tables)
294 , project_exact_solution(project_exact_solution)
295 , write_higher_order_cells(write_higher_order_cells)
425 system_matrix.clear();
426 system_rhs.reinit(0);
444 return static_cast<unsigned int>(triangulation_T.n_active_cells());
452 return static_cast<unsigned int>(dof_handler.n_dofs());
480 TimerOutput::OutputFrequency tf =
481 (print_time_tables) ? TimerOutput::summary : TimerOutput::never;
483 TimerOutput timer(std::cout, tf, TimerOutput::cpu_and_wall_times_grouped);
486 TMR(
"Fill Dirichlet stack");
487 fill_dirichlet_stack();
502 if (exact_solution) {
503 if (project_exact_solution) {
504 TMR(
"Project exact solution");
505 project_exact_solution_fcn();
509 TMR(
"Compute error norms");
510 compute_error_norms();
549 const FE_Nedelec<dim>
fe;
598 const unsigned int mapping_degree;
599 const unsigned int type_of_pde_rhs;
600 const double eta_squared;
601 const std::string fname;
602 const Function<dim>* exact_solution;
603 const bool print_time_tables;
604 const bool project_exact_solution;
605 const bool write_higher_order_cells;
607 Vector<float> L2_per_cell;
608 Vector<float> Linfty_per_cell;
617 using IteratorTuple =
618 std::tuple<typename DoFHandler<dim>::active_cell_iterator,
619 typename DoFHandler<dim>::active_cell_iterator>;
621 using IteratorPair = SynchronousIterators<IteratorTuple>;
623 struct AssemblyScratchData
625 AssemblyScratchData(
const FiniteElement<dim>& fe,
626 const DoFHandler<dim>& dof_hand_T,
627 const Vector<double>& dofs_T,
628 unsigned int mapping_degree,
629 unsigned int type_of_pde_rhs,
632 AssemblyScratchData(
const AssemblyScratchData& scratch_data);
639 MappingQ<dim> mapping;
641 FEValues<dim> fe_values;
642 FEFaceValues<dim> fe_face_values;
644 FEValues<dim> fe_values_T;
645 FEFaceValues<dim> fe_face_values_T;
647 const unsigned int dofs_per_cell;
648 const unsigned int n_q_points;
649 const unsigned int n_q_points_face;
651 std::vector<double> the_coefficient_list;
652 std::vector<Tensor<1, dim>> vector_values;
653 std::vector<Tensor<1, dim>> vector_values_face;
654 std::vector<double> values;
655 std::vector<double> values_face;
656 std::vector<double> gamma_list;
657 std::vector<Tensor<1, dim>> robin_rhs_list;
658 std::vector<Tensor<1, dim>> free_surface_current_list;
660 const DoFHandler<dim>& dof_hand_T;
661 const Vector<double>& dofs_T;
663 const unsigned int type_of_pde_rhs;
664 const double eta_squared;
665 const FEValuesExtractors::Vector ve;
666 const FEValuesExtractors::Scalar se;
669 bool do_T_on_boundary;
672 struct AssemblyCopyData
674 FullMatrix<double> cell_matrix;
675 Vector<double> cell_rhs;
676 std::vector<types::global_dof_index> local_dof_indices;
679 void system_matrix_local(
const IteratorPair& IP,
680 AssemblyScratchData& scratch_data,
681 AssemblyCopyData& copy_data);
683 void copy_local_to_global(
const AssemblyCopyData& copy_data);
689 template<
int dim,
int stage>
693 dof_handler.reinit(triangulation_T);
694 dof_handler.distribute_dofs(fe);
697 DoFTools::make_hanging_node_constraints(dof_handler, constraints);
699 #pragma GCC diagnostic push
700 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
701 for (
auto item : dirichlet_stack) {
702 Assert(item.first % 2 == 1, ExcInternalError());
704 #pragma GCC diagnostic pop
706 for (
auto item : dirichlet_stack)
707 VectorTools::project_boundary_values_curl_conforming_l2(
713 MappingQ<dim>(mapping_degree));
717 DynamicSparsityPattern dsp(dof_handler.n_dofs(), dof_handler.n_dofs());
718 DoFTools::make_sparsity_pattern(dof_handler, dsp, constraints,
false);
720 sparsity_pattern.copy_from(dsp);
721 system_matrix.reinit(sparsity_pattern);
722 solution.reinit(dof_handler.n_dofs());
723 system_rhs.reinit(dof_handler.n_dofs());
725 if (project_exact_solution)
726 projected_exact_solution.reinit(dof_handler.n_dofs());
728 if (exact_solution) {
729 L2_per_cell.reinit(triangulation_T.n_active_cells());
730 Linfty_per_cell.reinit(triangulation_T.n_active_cells());
734 template<
int dim,
int stage>
740 IteratorTuple(dof_handler.begin_active(), dof_handler_T.begin_active())),
741 IteratorPair(IteratorTuple(dof_handler.end(), dof_handler_T.end())),
743 &Solver2::system_matrix_local,
744 &Solver2::copy_local_to_global,
745 AssemblyScratchData(fe,
754 template<
int dim,
int stage>
756 const FiniteElement<dim>& fe,
757 const DoFHandler<dim>& dof_hand_T,
758 const Vector<double>& dofs_T,
759 unsigned int mapping_degree,
760 unsigned int type_of_pde_rhs,
762 : mapping(mapping_degree)
766 QGauss<dim>(qt.sim()),
767 update_gradients | update_values | update_quadrature_points |
769 , fe_face_values(mapping,
771 QGauss<dim - 1>(qt.sim()),
772 update_values | update_normal_vectors |
773 update_quadrature_points | update_JxW_values)
774 , fe_values_T(mapping,
776 QGauss<dim>(qt.sim()),
777 update_values | update_gradients)
778 , fe_face_values_T(mapping,
780 QGauss<dim - 1>(qt.sim()),
781 update_values | update_gradients)
782 , dofs_per_cell(fe_values.dofs_per_cell)
783 , n_q_points(fe_values.get_quadrature().size())
784 , n_q_points_face(fe_face_values.get_quadrature().size())
785 , the_coefficient_list(n_q_points)
786 , vector_values(n_q_points)
787 , vector_values_face(n_q_points_face)
789 , values_face(n_q_points_face)
790 , gamma_list(n_q_points_face)
791 , robin_rhs_list(n_q_points_face)
792 , free_surface_current_list(n_q_points_face)
793 , dof_hand_T(dof_hand_T)
795 , type_of_pde_rhs(type_of_pde_rhs)
796 , eta_squared(eta_squared)
802 template<
int dim,
int stage>
803 Solver2<dim, stage>::AssemblyScratchData::AssemblyScratchData(
804 const AssemblyScratchData& scratch_data)
805 : mapping(scratch_data.mapping.get_degree())
806 , qt(scratch_data.qt)
808 scratch_data.fe_values.get_fe(),
809 scratch_data.fe_values.get_quadrature(),
810 update_gradients | update_values | update_quadrature_points |
812 , fe_face_values(mapping,
813 scratch_data.fe_face_values.get_fe(),
814 scratch_data.fe_face_values.get_quadrature(),
815 update_values | update_normal_vectors |
816 update_quadrature_points | update_JxW_values)
817 , fe_values_T(mapping,
818 scratch_data.fe_values_T.get_fe(),
819 scratch_data.fe_values_T.get_quadrature(),
820 update_values | update_gradients)
821 , fe_face_values_T(mapping,
822 scratch_data.fe_face_values_T.get_fe(),
823 scratch_data.fe_face_values_T.get_quadrature(),
824 update_values | update_gradients)
825 , dofs_per_cell(fe_values.dofs_per_cell)
826 , n_q_points(fe_values.get_quadrature().size())
827 , n_q_points_face(fe_face_values.get_quadrature().size())
828 , the_coefficient_list(n_q_points)
829 , vector_values(n_q_points)
830 , vector_values_face(n_q_points_face)
832 , values_face(n_q_points_face)
833 , gamma_list(n_q_points_face)
834 , robin_rhs_list(n_q_points_face)
835 , free_surface_current_list(n_q_points_face)
836 , dof_hand_T(scratch_data.dof_hand_T)
837 , dofs_T(scratch_data.dofs_T)
838 , type_of_pde_rhs(scratch_data.type_of_pde_rhs)
839 , eta_squared(scratch_data.eta_squared)
845 template<
int dim,
int stage>
847 Solver2<dim, stage>::system_matrix_local(
const IteratorPair& IP,
848 AssemblyScratchData& scratch_data,
849 AssemblyCopyData& copy_data)
858 copy_data.cell_matrix.reinit(scratch_data.dofs_per_cell,
859 scratch_data.dofs_per_cell);
861 copy_data.cell_rhs.reinit(scratch_data.dofs_per_cell);
863 copy_data.local_dof_indices.resize(scratch_data.dofs_per_cell);
865 auto cell = std::get<0>(*IP);
866 auto cell_T = std::get<1>(*IP);
868 scratch_data.fe_values.reinit(cell);
869 scratch_data.fe_values_T.reinit(cell_T);
871 scratch_data.the_coefficient.value_list(
872 scratch_data.fe_values.get_quadrature_points(),
875 scratch_data.the_coefficient_list);
878 scratch_data.fe_values_T[SE].get_function_values(scratch_data.dofs_T,
879 scratch_data.values);
880 }
else if (dim == 3) {
881 scratch_data.fe_values_T[VE].get_function_values(
882 scratch_data.dofs_T, scratch_data.vector_values);
885 for (
unsigned int q_index = 0; q_index < scratch_data.n_q_points; ++q_index) {
886 for (
unsigned int i = 0; i < scratch_data.dofs_per_cell; ++i) {
887 for (
unsigned int j = 0; j < scratch_data.dofs_per_cell;
889 copy_data.cell_matrix(i, j) +=
890 ((1.0 / scratch_data.the_coefficient_list[q_index]) *
891 scratch_data.fe_values[VE].curl(i, q_index) *
892 scratch_data.fe_values[VE].curl(j, q_index)
893 + scratch_data.eta_squared *
894 scratch_data.fe_values[VE].value(i, q_index) *
895 scratch_data.fe_values[VE].value(j, q_index)
897 scratch_data.fe_values.JxW(q_index);
901 copy_data.cell_rhs(i) +=
902 scratch_data.values[q_index] *
903 scratch_data.fe_values[VE].curl(i, q_index)[0] *
904 scratch_data.fe_values.JxW(q_index);
905 }
else if (dim == 3) {
906 copy_data.cell_rhs(i) +=
907 (scratch_data.vector_values[q_index][0] *
908 scratch_data.fe_values[VE].curl(i, q_index)[0] +
909 scratch_data.vector_values[q_index][1] *
910 scratch_data.fe_values[VE].curl(i, q_index)[1] +
911 scratch_data.vector_values[q_index][2] *
912 scratch_data.fe_values[VE].curl(i, q_index)[2]
914 scratch_data.fe_values.JxW(q_index);
919 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f) {
920 scratch_data.do_robin = ((cell->face(f)->at_boundary()) &&
921 (cell->face(f)->boundary_id() % 2 == 0) &&
922 (cell->face(f)->boundary_id() != 0));
925 ((cell->user_index() > 0) && (cell->face(f)->user_index() > 0));
927 scratch_data.do_T_on_boundary =
928 ((cell->face(f)->at_boundary()) && (type_of_pde_rhs != 2));
930 Assert(!(scratch_data.do_robin && scratch_data.do_K), ExcInternalError());
932 if (scratch_data.do_robin || scratch_data.do_K ||
933 scratch_data.do_T_on_boundary) {
935 scratch_data.fe_face_values.reinit(cell, f);
936 scratch_data.fe_face_values_T.reinit(cell_T, f);
938 if (scratch_data.do_robin) {
939 scratch_data.gamma.value_list(
940 scratch_data.fe_face_values.get_quadrature_points(),
941 scratch_data.fe_face_values.get_normal_vectors(),
942 cell->face(f)->boundary_id(),
945 cell->face(f)->user_index(),
946 scratch_data.gamma_list);
948 scratch_data.robin_rhs.value_list(
949 scratch_data.fe_face_values.get_quadrature_points(),
950 scratch_data.fe_face_values.get_normal_vectors(),
951 cell->face(f)->boundary_id(),
954 cell->face(f)->user_index(),
955 scratch_data.robin_rhs_list);
958 if (scratch_data.do_K) {
959 scratch_data.free_surface_current.value_list(
960 scratch_data.fe_face_values.get_quadrature_points(),
961 scratch_data.fe_face_values.get_normal_vectors(),
964 cell->face(f)->user_index(),
965 scratch_data.free_surface_current_list);
968 if (scratch_data.do_T_on_boundary) {
970 scratch_data.fe_face_values_T[SE].get_function_values(
971 scratch_data.dofs_T, scratch_data.values_face);
972 }
else if (dim == 3) {
973 scratch_data.fe_face_values_T[VE].get_function_values(
974 scratch_data.dofs_T, scratch_data.vector_values_face);
978 for (
unsigned int q_index_face = 0;
979 q_index_face < scratch_data.n_q_points_face;
981 for (
unsigned int i = 0; i < scratch_data.dofs_per_cell; ++i) {
982 if (scratch_data.do_robin) {
983 for (
unsigned int j = 0; j < scratch_data.dofs_per_cell; ++j) {
985 copy_data.cell_matrix(i, j) +=
986 scratch_data.gamma_list[q_index_face] *
987 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
988 scratch_data.fe_face_values[VE].value(i, q_index_face)[1] -
989 scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
990 scratch_data.fe_face_values[VE].value(i,
992 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
993 scratch_data.fe_face_values[VE].value(j, q_index_face)[1] -
994 scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
995 scratch_data.fe_face_values[VE].value(j,
997 scratch_data.fe_face_values.JxW(
999 }
else if (dim == 3) {
1000 copy_data.cell_matrix(i, j) +=
1001 scratch_data.gamma_list[q_index_face] *
1002 ((scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
1003 scratch_data.fe_face_values[VE].value(i,
1005 scratch_data.fe_face_values.normal_vector(q_index_face)[2] *
1006 scratch_data.fe_face_values[VE].value(i,
1008 (scratch_data.fe_face_values.normal_vector(
1010 scratch_data.fe_face_values[VE].value(j,
1012 scratch_data.fe_face_values.normal_vector(
1014 scratch_data.fe_face_values[VE].value(
1015 j, q_index_face)[1]) +
1016 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
1017 scratch_data.fe_face_values[VE].value(i,
1019 scratch_data.fe_face_values.normal_vector(q_index_face)[2] *
1020 scratch_data.fe_face_values[VE].value(i,
1022 (scratch_data.fe_face_values.normal_vector(
1024 scratch_data.fe_face_values[VE].value(j,
1026 scratch_data.fe_face_values.normal_vector(
1028 scratch_data.fe_face_values[VE].value(
1029 j, q_index_face)[0]) +
1030 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
1031 scratch_data.fe_face_values[VE].value(i,
1033 scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
1034 scratch_data.fe_face_values[VE].value(i,
1036 (scratch_data.fe_face_values.normal_vector(
1038 scratch_data.fe_face_values[VE].value(j,
1040 scratch_data.fe_face_values.normal_vector(
1042 scratch_data.fe_face_values[VE].value(
1043 j, q_index_face)[0]))
1044 * scratch_data.fe_face_values.JxW(q_index_face);
1046 Assert(
false, ExcInternalError());
1051 copy_data.cell_rhs(i) +=
1052 -scratch_data.robin_rhs_list[q_index_face] *
1053 scratch_data.fe_face_values[VE].value(i, q_index_face) *
1054 scratch_data.fe_face_values.JxW(q_index_face);
1057 if (scratch_data.do_K) {
1058 copy_data.cell_rhs(i) +=
1059 scratch_data.free_surface_current_list[q_index_face] *
1060 scratch_data.fe_face_values[VE].value(i, q_index_face) *
1061 scratch_data.fe_face_values.JxW(q_index_face);
1064 if (scratch_data.do_T_on_boundary) {
1066 copy_data.cell_rhs(i) -=
1067 scratch_data.values_face[q_index_face] *
1068 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
1069 scratch_data.fe_face_values[VE].value(i, q_index_face)[1] -
1070 scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
1071 scratch_data.fe_face_values[VE].value(
1072 i, q_index_face)[0]) *
1073 scratch_data.fe_face_values.JxW(q_index_face);
1074 }
else if (dim == 3) {
1075 copy_data.cell_rhs(i) -=
1076 (scratch_data.vector_values_face[q_index_face][0] *
1077 (scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
1078 scratch_data.fe_face_values[VE].value(i,
1080 scratch_data.fe_face_values.normal_vector(q_index_face)[2] *
1081 scratch_data.fe_face_values[VE].value(i,
1083 scratch_data.vector_values_face[q_index_face][1] *
1084 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
1085 scratch_data.fe_face_values[VE].value(i,
1087 scratch_data.fe_face_values.normal_vector(q_index_face)[2] *
1088 scratch_data.fe_face_values[VE].value(i,
1090 scratch_data.vector_values_face[q_index_face][2] *
1091 (scratch_data.fe_face_values.normal_vector(q_index_face)[0] *
1092 scratch_data.fe_face_values[VE].value(i,
1094 scratch_data.fe_face_values.normal_vector(q_index_face)[1] *
1095 scratch_data.fe_face_values[VE].value(
1096 i, q_index_face)[0])
1098 scratch_data.fe_face_values.JxW(q_index_face);
1100 Assert(
false, ExcInternalError());
1107 cell->get_dof_indices(copy_data.local_dof_indices);
1110 template<
int dim,
int stage>
1112 Solver2<dim, stage>::copy_local_to_global(
const AssemblyCopyData& copy_data)
1114 constraints.distribute_local_to_global(copy_data.cell_matrix,
1116 copy_data.local_dof_indices,
1121 template<
int dim,
int stage>
1126 const Function<dim, double>* mask = &weight;
1129 QGauss<dim> quadrature(qt.
enorm());
1131 VectorTools::integrate_difference(MappingQ<dim>(mapping_degree),
1137 VectorTools::L2_norm,
1140 L2_norm = VectorTools::compute_global_error(
1141 triangulation_T, L2_per_cell, VectorTools::L2_norm);
1143 VectorTools::integrate_difference(MappingQ<dim>(mapping_degree),
1149 VectorTools::Linfty_norm,
1152 Linfty_norm = Linfty_per_cell.linfty_norm();
1155 template<
int dim,
int stage>
1161 AffineConstraints<double> constraints_empty;
1162 constraints_empty.close();
1164 VectorTools::project(MappingQ<dim>(mapping_degree),
1167 QGauss<dim>(qt.
sim()),
1169 projected_exact_solution);
1172 template<
int dim,
int stage>
1176 std::vector<std::string> solution_names(dim,
"VectorField");
1177 std::vector<DataComponentInterpretation::DataComponentInterpretation>
1179 DataComponentInterpretation::component_is_part_of_vector);
1181 DataOut<dim> data_out;
1183 data_out.add_data_vector(
1184 dof_handler, solution, solution_names, interpretation);
1186 if (project_exact_solution && exact_solution) {
1187 std::vector<std::string> solution_names_ex(dim,
"VectorFieldExact");
1189 data_out.add_data_vector(
1190 dof_handler, projected_exact_solution, solution_names_ex, interpretation);
1193 if (exact_solution) {
1194 data_out.add_data_vector(L2_per_cell,
"L2norm");
1195 data_out.add_data_vector(Linfty_per_cell,
"LinftyNorm");
1200 if (write_higher_order_cells) {
1201 DataOutBase::VtkFlags flags;
1202 flags.write_higher_order_cells =
true;
1203 data_out.set_flags(flags);
1205 const MappingQ<dim> mapping(mapping_degree);
1207 data_out.build_patches(mapping,
1209 DataOut<dim>::CurvedCellRegion::curved_inner_cells);
1211 ofs.open(fname +
".vtu");
1212 data_out.write_vtu(ofs);
1216 data_out.build_patches();
1218 ofs.open(fname +
".vtk");
1219 data_out.write_vtk(ofs);
1225 template<
int dim,
int stage>
1229 std::ofstream ofs_matrix(fname +
"_matrix.csv");
1230 std::ofstream ofs_rhs(fname +
"_rhs.csv");
1232 for (
unsigned int i = 0; i < system_matrix.m(); ++i) {
1233 ofs_rhs << system_rhs(i);
1234 if (i < (system_matrix.m() - 1))
1237 for (
unsigned int j = 0; j < system_matrix.n(); ++j) {
1238 ofs_matrix << std::scientific << std::setprecision(16)
1239 << system_matrix.el(i, j);
1241 if (j < (system_matrix.m() - 1))
1244 if (i < (system_matrix.m() - 1))
The tables that contain the amount of quadrature points used in vector problems.
unsigned int enorm() const
Returns the amount of quadrature points used when calculating the error norms.
unsigned int sim() const
Returns the amount of quadrature points used when assembling system if linear equations.
Implements the coefficient on the left-hand side of the Robin boundary condition (iii) of the static...
Implements the vector field, , on the right-hand side of the Robin boundary condition (iii) of the st...
Solves static vector boundary value problem.
void save_matrix_and_rhs_to_csv(std::string fname) const
Saves the system matrix and the right-hand side into a csv file.
void assemble()
Assembles the system matrix and the right-hand side vector.
double Linfty_norm
The norm.
std::map< types::boundary_id, const Function< dim > * > dirichlet_stack
A map that contains pairs of boundary IDs and the corresponding Dirichlet boundary conditions....
void clear()
Releases computer memory associated with system matrix and right-hand side.
unsigned int get_mapping_degree() const
Returns degree of the interpolating Lagrange polynomials used for mapping from the reference cell to ...
const FE_Nedelec< dim > fe
The finite elements.
SparseMatrix< double > system_matrix
The system matrix.
const Vector< double > & get_solution() const
Returns a reference to solution.
virtual void solve()=0
Solves the system of linear equations.
DoFHandler< dim > dof_handler
The finite elements.
Vector< double > solution
The solution vector, that is, degrees of freedom yielded by the simulation.
Solver2(unsigned int p, unsigned int mapping_degree, const Triangulation< dim > &triangulation_T, const DoFHandler< dim > &dof_handler_T, const Vector< double > &solution_T, unsigned int type_of_pde_rhs=0, double eta_squared=0.0, std::string fname="data", const Function< dim > *exact_solution=nullptr, bool print_time_tables=false, bool project_exact_solution=false, bool write_higher_order_cells=false)
The only constructor.
Vector< double > system_rhs
The system right-hand side vector.
const Triangulation< dim > & triangulation_T
Reference to the mesh.
void compute_error_norms()
Computes error norms.
void project_exact_solution_fcn()
Projects exact solution.
void setup()
Initializes system matrix and the right-hand side vector.
unsigned int get_n_dofs() const
Returns the total amount of the degrees of freedom.
const DoFHandler< dim > & get_dof_handler() const
Returns a reference to a dof handler.
unsigned int get_n_cells() const
Returns the number of active cells in the mesh.
SparsityPattern sparsity_pattern
The sparsity pattern of the system matrix.
const Vector< double > & solution_T
Reference to the degrees of freedom that describe the current vector potential, .
double get_Linfty_norm() const
Returns error norm.
void run()
Runs the simulation.
void save() const
Saves simulation results into a vtk file.
const DoFHandler< dim > & dof_handler_T
Reference to the dof handler that describes the current vector potential, .
virtual void fill_dirichlet_stack()=0
Initializes the data member StaticVectorSolver::Solver2::dirichlet_stack.
Vector< double > projected_exact_solution
The projected exact solution vector.
AffineConstraints< double > constraints
The constraints associated with the Dirichlet boundary conditions.
double get_L2_norm() const
Returns error norm.
Implements the permeability, , in the partial differential equation (i) of the vector boundary value ...
Implements the weight function for calculating the and error norms.