The finite element method using deal.II - 2021/2022
step-4.cc
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------
2  *
3  * Copyright (C) 1999 - 2020 by the deal.II authors
4  *
5  * This file is part of the deal.II library.
6  *
7  * The deal.II library is free software; you can use it, redistribute
8  * it, and/or modify it under the terms of the GNU Lesser General
9  * Public License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  * The full text of the license can be found in the file LICENSE.md at
12  * the top level directory of deal.II.
13  *
14  * ---------------------------------------------------------------------
15  *
16  * Author: Wolfgang Bangerth, University of Heidelberg, 1999
17  */
18 #include <deal.II/base/function.h>
19 #include <deal.II/base/logstream.h>
21 
24 #include <deal.II/dofs/dof_tools.h>
25 
26 #include <deal.II/fe/fe_q.h>
27 #include <deal.II/fe/fe_values.h>
28 
30 #include <deal.II/grid/tria.h>
33 
37 #include <deal.II/lac/solver_cg.h>
39 #include <deal.II/lac/vector.h>
40 
44 
45 #include <fstream>
46 #include <iostream>
47 using namespace dealii;
48 template <int dim>
49 class Step4
50 {
51 public:
52  Step4();
53  void
54  run();
55 
56 private:
57  void
58  make_grid();
59  void
60  setup_system();
61  void
62  assemble_system();
63  void
64  solve();
65  void
66  output_results() const;
74 };
75 
76 
77 template <int dim>
78 class RightHandSide : public Function<dim>
79 {
80 public:
81  virtual double
82  value(const Point<dim> &p, const unsigned int component = 0) const override;
83 };
84 
85 
86 template <int dim>
87 class BoundaryValues : public Function<dim>
88 {
89 public:
90  virtual double
91  value(const Point<dim> &p, const unsigned int component = 0) const override;
92 };
93 
94 
95 template <int dim>
96 double
98  const unsigned int /*component*/) const
99 {
100  double return_value = 0.0;
101  for (unsigned int i = 0; i < dim; ++i)
102  return_value += 4.0 * std::pow(p(i), 4.0);
103  return return_value;
104 }
105 
106 
107 template <int dim>
108 double
110  const unsigned int /*component*/) const
111 {
112  return p.square();
113 }
114 
115 
116 template <int dim>
118  : fe(1)
119  , dof_handler(triangulation)
120 {}
121 
122 
123 template <int dim>
124 void
126 {
128  triangulation.refine_global(4);
129  std::cout << " Number of active cells: " << triangulation.n_active_cells()
130  << std::endl
131  << " Total number of cells: " << triangulation.n_cells()
132  << std::endl;
133 }
134 
135 
136 template <int dim>
137 void
139 {
140  dof_handler.distribute_dofs(fe);
141  std::cout << " Number of degrees of freedom: " << dof_handler.n_dofs()
142  << std::endl;
143  DynamicSparsityPattern dsp(dof_handler.n_dofs());
144  DoFTools::make_sparsity_pattern(dof_handler, dsp);
146  system_matrix.reinit(sparsity_pattern);
147  solution.reinit(dof_handler.n_dofs());
148  system_rhs.reinit(dof_handler.n_dofs());
149 }
150 
151 
152 template <int dim>
153 void
155 {
156  QGauss<dim> quadrature_formula(fe.degree + 1);
157  RightHandSide<dim> right_hand_side;
158  FEValues<dim> fe_values(fe,
159  quadrature_formula,
162  const unsigned int dofs_per_cell = fe.dofs_per_cell;
163  FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
164  Vector<double> cell_rhs(dofs_per_cell);
165  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
166  for (const auto &cell : dof_handler.active_cell_iterators())
167  {
168  fe_values.reinit(cell);
169  cell_matrix = 0;
170  cell_rhs = 0;
171  for (const unsigned int q_index : fe_values.quadrature_point_indices())
172  for (const unsigned int i : fe_values.dof_indices())
173  {
174  for (const unsigned int j : fe_values.dof_indices())
175  cell_matrix(i, j) +=
176  (fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
177  fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
178  fe_values.JxW(q_index)); // dx
179  const auto x_q = fe_values.quadrature_point(q_index);
180  cell_rhs(i) += (fe_values.shape_value(i, q_index) * // phi_i(x_q)
181  right_hand_side.value(x_q) * // f(x_q)
182  fe_values.JxW(q_index)); // dx
183  }
184  cell->get_dof_indices(local_dof_indices);
185  for (const unsigned int i : fe_values.dof_indices())
186  {
187  for (const unsigned int j : fe_values.dof_indices())
188  system_matrix.add(local_dof_indices[i],
190  cell_matrix(i, j));
191  system_rhs(local_dof_indices[i]) += cell_rhs(i);
192  }
193  }
194  std::map<types::global_dof_index, double> boundary_values;
196  0,
198  boundary_values);
199  MatrixTools::apply_boundary_values(boundary_values,
200  system_matrix,
201  solution,
202  system_rhs);
203 }
204 
205 
206 template <int dim>
207 void
209 {
210  SolverControl solver_control(1000, 1e-12);
211  SolverCG<Vector<double>> solver(solver_control);
212  solver.solve(system_matrix, solution, system_rhs, PreconditionIdentity());
213  std::cout << " " << solver_control.last_step()
214  << " CG iterations needed to obtain convergence." << std::endl;
215 }
216 
217 
218 template <int dim>
219 void
221 {
222  DataOut<dim> data_out;
223  data_out.attach_dof_handler(dof_handler);
224  data_out.add_data_vector(solution, "solution");
225  data_out.build_patches();
226  std::ofstream output(dim == 2 ? "solution-2d.vtk" : "solution-3d.vtk");
227  data_out.write_vtk(output);
228 }
229 
230 
231 template <int dim>
232 void
234 {
235  std::cout << "Solving problem in " << dim << " space dimensions."
236  << std::endl;
237  make_grid();
238  setup_system();
239  assemble_system();
240  solve();
241  output_results();
242 }
243 
244 
245 int
247 {
249  {
250  Step4<2> laplace_problem_2d;
251  laplace_problem_2d.run();
252  }
253  {
254  Step4<3> laplace_problem_3d;
255  laplace_problem_3d.run();
256  }
257  return 0;
258 }
FEValues::shape_value
const double & shape_value(const unsigned int function_no, const unsigned int point_no) const
tria_accessor.h
Vector< double >::add
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
local_dof_indices
std::vector< types::global_dof_index > local_dof_indices
FEValues::reinit
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access >> &cell)
logstream.h
dynamic_sparsity_pattern.h
triangulation
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
update_quadrature_points
update_quadrature_points
SolverCG
PreconditionIdentity
PreconditionIdentity()
SolverCG::solve
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
FE_Q< dim >
SolverControl
dealii
FEValues::quadrature_point_indices
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
main
int main()
Definition: step-4.cc:246
grid_generator.h
Triangulation
RightHandSide::value
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition: step-4.cc:97
Step4::output_results
void output_results() const
Definition: step-4.cc:220
SparseMatrix< double >
MatrixTools::apply_boundary_values
void apply_boundary_values(const std::map< types::global_dof_index, number > &boundary_values, SparseMatrix< number > &matrix, Vector< number > &solution, Vector< number > &right_hand_side, const bool eliminate_columns=true)
e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
tria_iterator.h
DataOut::write_vtk
void write_vtk(std::ostream &out) const
RightHandSide
Definition: step-4.cc:78
cell_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.)
update_values
update_values
matrix_tools.h
DataOut::attach_dof_handler
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
DoFHandler< dim >
BoundaryValues
Definition: step-4.cc:87
fe_values.h
Step4::sparsity_pattern
SparsityPattern sparsity_pattern
Definition: step-4.cc:70
function.h
deallog
LogStream deallog
SolverControl::last_step
unsigned int last_step() const
FEValues< dim >
FEValues::shape_grad
const Tensor< 1, spacedim > & shape_grad(const unsigned int function_no, const unsigned int quadrature_point) const
sparse_matrix.h
DoFTools::make_sparsity_pattern
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternType &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
Step4::dof_handler
DoFHandler< dim > dof_handler
Definition: step-4.cc:69
vector_tools.h
Step4::solve
void solve()
Definition: step-4.cc:208
tria.h
DataOut::build_patches
virtual void build_patches(const unsigned int n_subdivisions=0)
Step4::fe
FE_Q< dim > fe
Definition: step-4.cc:68
update_gradients
update_gradients
sparsity_pattern
SparsityPattern sparsity_pattern
run
virtual void run(ParameterHandler &prm)=0
DynamicSparsityPattern
SparsityPattern
VectorTools::interpolate_boundary_values
void interpolate_boundary_values(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const std::map< types::boundary_id, const Function< spacedim, number > * > &function_map, std::map< types::global_dof_index, number > &boundary_values, const ComponentMask &component_mask=ComponentMask())
Step4::system_rhs
Vector< double > system_rhs
Definition: step-4.cc:73
FEValues::JxW
double JxW(const unsigned int quadrature_point) const
data_out.h
make_grid
void make_grid(Triangulation< 2 > &triangulation)
Definition: step-2.cc:41
output
output
QGauss
Step4::assemble_system
void assemble_system()
Definition: step-4.cc:154
LogStream::depth_console
unsigned int depth_console(const unsigned int n)
fe_q.h
update_JxW_values
update_JxW_values
value
number value
dof_tools.h
Step4::make_grid
void make_grid()
Definition: step-4.cc:125
SparsityPattern::copy_from
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
GridGenerator::hyper_cube
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
precondition.h
DataOut::add_data_vector
void add_data_vector(const VectorType &data, const std::vector< std::string > &names, const DataVectorType type=type_automatic, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretation={})
Step4::triangulation
Triangulation< dim > triangulation
Definition: step-4.cc:67
Step4::solution
Vector< double > solution
Definition: step-4.cc:72
Point< dim >
FEValues::quadrature_point
const Point< spacedim > & quadrature_point(const unsigned int q) const
FEValues::dof_indices
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
Step4::setup_system
void setup_system()
Definition: step-4.cc:138
Point::square
numbers::NumberTraits< Number >::real_type square() const
FullMatrix< double >
Step4
Definition: step-4.cc:49
Function
full_matrix.h
DataOut< dim >
Step4::Step4
Step4()
Definition: step-4.cc:117
dof_handler.h
Vector< double >
Step4::run
void run()
Definition: step-4.cc:233
vector.h
solver_cg.h
Step4::system_matrix
SparseMatrix< double > system_matrix
Definition: step-4.cc:71
BoundaryValues::value
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition: step-4.cc:109
quadrature_lib.h
dof_accessor.h