include/meltpooldg/linear_algebra/predictor.hpp Source File

Developer Documentation: include/meltpooldg/linear_algebra/predictor.hpp Source File
Developer Documentation
predictor.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/exceptions.h>
4#include <deal.II/base/numbers.h>
5
6#include <deal.II/lac/full_matrix.h>
7
12
13#include <vector>
14
15
16namespace MeltPoolDG
17{
18 template <typename VectorType, typename number = double>
20 {
21 public:
23 const std::vector<VectorType> &solution_history,
24 const unsigned int n_old_solutions = dealii::numbers::invalid_unsigned_int)
25 : old_solution(n_old_solutions == dealii::numbers::invalid_unsigned_int ?
26 solution_history.size() :
27 n_old_solutions)
28 {
29 Assert(n_old_solutions <= solution_history.size(), dealii::ExcInternalError());
30
31 for (unsigned int i = 0; i < old_solution.size(); ++i)
32 old_solution[i] = &solution_history[i];
33 }
34
35 template <typename MatrixType>
36 void
37 vmult(const MatrixType &matrix, VectorType &solution, const VectorType &rhs) const
38 {
39 const unsigned int n_old_solutions = old_solution.size();
40 internal_vectors.resize(n_old_solutions);
41 dealii::FullMatrix<number> projection_matrix(n_old_solutions, n_old_solutions);
42 unsigned int step = 0;
43 for (; step < n_old_solutions; ++step)
44 {
45 internal_vectors[step].reinit(rhs, true);
46 matrix.vmult(internal_vectors[step], *old_solution[step]);
47 // modified Gram-Schmidt
48 projection_matrix(0, step) = internal_vectors[step] * internal_vectors[0];
49 for (unsigned int j = 0; j < step; ++j)
50 {
51 projection_matrix(j + 1, step) = internal_vectors[step].add_and_dot(
52 -projection_matrix(j, step) /
53 projection_matrix(j, j), // TODO: check for division by zero?
55 internal_vectors[j + 1]);
56 }
57
58 if (projection_matrix(step, step) < 1e-16 * projection_matrix(0, 0))
59 break;
60 }
61
62 // Solve least-squares system
63 std::vector<number> project_sol(step);
64 for (unsigned int s = 0; s < step; ++s)
65 project_sol[s] = internal_vectors[s] * rhs;
66
67 for (int s = step - 1; s >= 0; --s)
68 {
69 number sum = project_sol[s];
70 for (unsigned int j = s + 1; j < step; ++j)
71 sum -= project_sol[j] * projection_matrix(s, j);
72 project_sol[s] = sum / projection_matrix(s, s); // TODO check for division by zero?
73 }
74
75 // extrapolate solution from old values
76 solution.reinit(rhs, true);
77 solution.equ(project_sol[0], *old_solution[0]);
78 for (unsigned int s = 1; s < step; ++s)
79 solution.add(project_sol[s], *old_solution[s]);
80 }
81
82 private:
83 std::vector<const VectorType *> old_solution;
84
85 mutable std::vector<VectorType> internal_vectors;
86 };
87
88 template <typename VectorType, typename number = double>
90 {
91 private:
92 const PredictorData data;
96
97 mutable unsigned int n_calls = 0;
98
99 public:
100 Predictor(const PredictorData data,
103 : data(data)
104 , solution_history(solution_history_in)
106 , lsp(solution_history_in.get_all_solutions(), data.n_old_solution_vectors)
107 {
108 Assert(solution_history.size() >= 1, dealii::ExcInternalError());
109 Assert(solution_history.size() >= 2 || data.type != PredictorType::linear_extrapolation,
110 dealii::ExcInternalError());
111
112 // TODO: extend for BlockVectors
113 AssertThrow(!dealii::internal::is_block_vector<VectorType> ||
114 data.type != PredictorType::least_squares_projection,
115 dealii::ExcNotImplemented());
116 }
117
118 template <typename MatrixType>
119 void
120 vmult(const MatrixType &matrix, VectorType &solution, const VectorType &rhs) const
121 {
122 switch (data.type)
123 {
124 case PredictorType::none: {
125 solution = solution_history.get_current_solution();
126 break;
127 }
128 case PredictorType::zero: {
129 solution = 0;
130 break;
131 }
132 case PredictorType::linear_extrapolation: {
133 compute_linear_predictor(solution_history.get_current_solution(),
134 solution_history.get_recent_old_solution(),
135 solution,
136 time_iterator ? time_iterator->get_current_time_increment() :
137 1.0,
138 time_iterator ? time_iterator->get_old_time_increment() :
139 1.0);
140 solution.update_ghost_values();
141 break;
142 }
143 case PredictorType::least_squares_projection: {
144 // use LSP only if n_old_solution_vectors are stored
145 if (n_calls >= data.n_old_solution_vectors)
146 lsp.vmult(matrix, solution, rhs);
147 else
148 // use const predictor
149 solution.swap(solution_history.get_current_solution());
150 break;
151 }
152 default:
153 DEAL_II_NOT_IMPLEMENTED();
154 }
155
156 solution_history.commit_old_solutions();
157 solution_history.get_current_solution().swap(solution);
158
159 n_calls += 1;
160 }
161 };
162} // namespace MeltPoolDG
Definition predictor.hpp:20
std::vector< VectorType > internal_vectors
Definition predictor.hpp:85
std::vector< const VectorType * > old_solution
Definition predictor.hpp:83
LeastSquaresProjection(const std::vector< VectorType > &solution_history, const unsigned int n_old_solutions=dealii::numbers::invalid_unsigned_int)
Definition predictor.hpp:22
void vmult(const MatrixType &matrix, VectorType &solution, const VectorType &rhs) const
Definition predictor.hpp:37
Definition predictor.hpp:90
void vmult(const MatrixType &matrix, VectorType &solution, const VectorType &rhs) const
Definition predictor.hpp:120
TimeIntegration::SolutionHistory< VectorType > & solution_history
Definition predictor.hpp:93
const TimeIntegration::TimeIterator< number > * time_iterator
Definition predictor.hpp:94
const LeastSquaresProjection< VectorType > lsp
Definition predictor.hpp:95
const PredictorData data
Definition predictor.hpp:92
Predictor(const PredictorData data, TimeIntegration::SolutionHistory< VectorType > &solution_history_in, const TimeIntegration::TimeIterator< number > *time_iterator=nullptr)
Definition predictor.hpp:100
unsigned int n_calls
Definition predictor.hpp:97
Definition solution_history.hpp:21
Definition time_iterator.hpp:15
Interface for a general preconditioner.
Definition boundary_condition_functions.hpp:17
void compute_linear_predictor(const VectorType &old_vec, const VectorType &old_old_vec, VectorType &predictor, const number current_time_increment, const number old_time_increment)
Definition predictor_linear.cpp:76
Definition dealii_tensor.hpp:10