Template Deal.II Application
 
Loading...
Searching...
No Matches
laplacian.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2024 by Luca Heltai
4//
5// This file is part of the bare-dealii-app application, based on the
6// deal.II library.
7//
8// The bare-dealii-app application is free software; you can use it,
9// redistribute it, and/or modify it under the terms of the Apache-2.0 License
10// WITH LLVM-exception as published by the Free Software Foundation; either
11// version 3.0 of the License, or (at your option) any later version.
12// The full text of the license can be found in the file LICENSE.md
13// at the top level of the bare-dealii-app distribution.
14//
15// ---------------------------------------------------------------------
16
17#include "laplacian.h"
18
20
23
24#include <deal.II/fe/fe_q.h>
26
30#include <deal.II/grid/tria.h>
31
38#include <deal.II/lac/vector.h>
39
43
44#include <fstream>
45
46using namespace dealii;
47
48
49template <int dim>
50double
52{
53 if (p.square() < 0.5 * 0.5)
54 return 20;
55 else
56 return 1;
57}
58
59
60
61template <int dim>
63 : fe(2)
64 , dof_handler(triangulation)
65{}
66
67
68
69template <int dim>
70void
72{
73 dof_handler.distribute_dofs(fe);
74
75 solution.reinit(dof_handler.n_dofs());
76 system_rhs.reinit(dof_handler.n_dofs());
77
78 constraints.clear();
79 DoFTools::make_hanging_node_constraints(dof_handler, constraints);
80
81
83 0,
85 constraints);
86
87 constraints.close();
88
89 DynamicSparsityPattern dsp(dof_handler.n_dofs());
91 dsp,
92 constraints,
93 /*keep_constrained_dofs = */ false);
94
95 sparsity_pattern.copy_from(dsp);
96
97 system_matrix.reinit(sparsity_pattern);
98}
99
100
101
102template <int dim>
103void
105{
106 const QGauss<dim> quadrature_formula(fe.degree + 1);
107
108 FEValues<dim> fe_values(fe,
109 quadrature_formula,
112
113 const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
114
115 FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
116 Vector<double> cell_rhs(dofs_per_cell);
117
118 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
119
120 for (const auto &cell : dof_handler.active_cell_iterators())
121 {
122 cell_matrix = 0;
123 cell_rhs = 0;
124
125 fe_values.reinit(cell);
126
127 for (const unsigned int q_index : fe_values.quadrature_point_indices())
128 {
129 const double current_coefficient =
130 coefficient<dim>(fe_values.quadrature_point(q_index));
131 for (const unsigned int i : fe_values.dof_indices())
132 {
133 for (const unsigned int j : fe_values.dof_indices())
134 cell_matrix(i, j) +=
135 (current_coefficient * // a(x_q)
136 fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
137 fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
138 fe_values.JxW(q_index)); // dx
139
140 cell_rhs(i) += (1.0 * // f(x)
141 fe_values.shape_value(i, q_index) * // phi_i(x_q)
142 fe_values.JxW(q_index)); // dx
143 }
144 }
145
146 cell->get_dof_indices(local_dof_indices);
147 constraints.distribute_local_to_global(
148 cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs);
149 }
150}
151
152
153
154template <int dim>
155void
157{
158 SolverControl solver_control(1000, 1e-12);
159 SolverCG<Vector<double>> solver(solver_control);
160
162 preconditioner.initialize(system_matrix, 1.2);
163
164 solver.solve(system_matrix, solution, system_rhs, preconditioner);
165
166 constraints.distribute(solution);
167}
168
169
170
171template <int dim>
172void
174{
175 Vector<float> estimated_error_per_cell(triangulation.n_active_cells());
176
178 QGauss<dim - 1>(fe.degree + 1),
179 {},
180 solution,
181 estimated_error_per_cell);
182
184 estimated_error_per_cell,
185 0.3,
186 0.03);
187
188 triangulation.execute_coarsening_and_refinement();
189}
190
191
192
193template <int dim>
194void
195Laplacian<dim>::output_results(const unsigned int cycle) const
196{
197 {
198 GridOut grid_out;
199 std::ofstream output("grid-" + std::to_string(cycle) + ".gnuplot");
200 GridOutFlags::Gnuplot gnuplot_flags(false, 5);
201 grid_out.set_flags(gnuplot_flags);
202 MappingQGeneric<dim> mapping(3);
203 grid_out.write_gnuplot(triangulation, output, &mapping);
204 }
205
206 {
207 DataOut<dim> data_out;
208 data_out.attach_dof_handler(dof_handler);
209 data_out.add_data_vector(solution, "solution");
210 data_out.build_patches();
211
212 std::ofstream output("solution-" + std::to_string(cycle) + ".vtu");
213 data_out.write_vtu(output);
214 }
215}
216
217
218
219template <int dim>
220void
222{
223 for (unsigned int cycle = 0; cycle < 8; ++cycle)
224 {
225 std::cout << "Cycle " << cycle << ':' << std::endl;
226
227 if (cycle == 0)
228 {
230 triangulation.refine_global(1);
231 }
232 else
233 refine_grid();
234
235
236 std::cout << " Number of active cells: "
237 << triangulation.n_active_cells() << std::endl;
238
239 setup_system();
240
241 std::cout << " Number of degrees of freedom: " << dof_handler.n_dofs()
242 << std::endl;
243
244 assemble_system();
245 solve();
246 output_results(cycle);
247 }
248}
249
250
251template class Laplacian<DEAL_DIMENSION>;
void write_vtu(std::ostream &out) const
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
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={})
virtual void build_patches(const unsigned int n_subdivisions=0)
const Point< spacedim > & quadrature_point(const unsigned int q_point) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
const Tensor< 1, spacedim > & shape_grad(const unsigned int i, const unsigned int q_point) const
double JxW(const unsigned int q_point) const
const double & shape_value(const unsigned int i, const unsigned int q_point) const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
void set_flags(const GridOutFlags::DX &flags)
void write_gnuplot(const Triangulation< dim, spacedim > &tria, std::ostream &out, const Mapping< dim, spacedim > *mapping=nullptr) const
static void estimate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim - 1 > &quadrature, const std::map< types::boundary_id, const Function< spacedim, Number > * > &neumann_bc, const ReadVector< Number > &solution, Vector< float > &error, const ComponentMask &component_mask={}, const Function< spacedim > *coefficients=nullptr, const unsigned int n_threads=numbers::invalid_unsigned_int, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id, const types::material_id material_id=numbers::invalid_material_id, const Strategy strategy=cell_diameter_over_24)
constexpr numbers::NumberTraits< Number >::real_type square() const
void initialize(const MatrixType &A, const AdditionalData &parameters=AdditionalData())
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
void output_results(const unsigned int cycle) const
Definition laplacian.cc:195
void run()
Definition laplacian.cc:221
void assemble_system()
Definition laplacian.cc:104
void setup_system()
Definition laplacian.cc:71
void refine_grid()
Definition laplacian.cc:173
void solve()
Definition laplacian.cc:156
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
update_JxW_values
update_gradients
update_quadrature_points
double coefficient(const Point< dim > &p)
Definition laplacian.cc:51
void hyper_ball(Triangulation< dim > &tria, const Point< dim > &center=Point< dim >(), const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=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())
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
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={})
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation