numerics 0.1.0
Loading...
Searching...
No Matches
diffusion.hpp
Go to the documentation of this file.
1/// @file pde/diffusion.hpp
2/// @brief Diffusion operators and implicit system builders for 2D grids.
3#pragma once
4
5#include "core/policy.hpp"
6#include "core/vector.hpp"
7#include "fields/grid2d.hpp"
11#include "pde/stencil.hpp"
12
13namespace num::pde {
14
15inline void diffusion_step_2d(Vector& u, int N, double coeff, Backend b = best_backend) {
16 Vector lap(u.size());
18 axpy(coeff, lap, u, b);
19}
20
22 int N,
23 double coeff,
25 Vector lap(u.size());
26 laplacian_stencil_2d(u, lap, N);
27 axpy(coeff, lap, u, b);
28}
29
31 int N,
32 double coeff,
34 Vector lap(u.size());
35 laplacian_stencil_2d_4th(u, lap, N);
36 axpy(coeff, lap, u, b);
37}
38
40 double coeff,
42 diffusion_step_2d_dirichlet(g.vec(), g.N(), coeff, b);
43}
44
46 double coeff,
48 diffusion_step_2d_4th_dirichlet(g.vec(), g.N(), coeff, b);
49}
50
52 const int n = N * N;
53 std::vector<idx> rows, cols;
54 std::vector<real> vals;
55 rows.reserve(5 * n);
56 cols.reserve(5 * n);
57 vals.reserve(5 * n);
58 for (int i = 0; i < N; ++i) {
59 for (int j = 0; j < N; ++j) {
60 int k = i * N + j;
61 rows.push_back(k);
62 cols.push_back(k);
63 vals.push_back(-4.0);
64 if (i > 0) {
65 rows.push_back(k);
66 cols.push_back((i - 1) * N + j);
67 vals.push_back(1.0);
68 }
69 if (i < N - 1) {
70 rows.push_back(k);
71 cols.push_back((i + 1) * N + j);
72 vals.push_back(1.0);
73 }
74 if (j > 0) {
75 rows.push_back(k);
76 cols.push_back(i * N + (j - 1));
77 vals.push_back(1.0);
78 }
79 if (j < N - 1) {
80 rows.push_back(k);
81 cols.push_back(i * N + (j + 1));
82 vals.push_back(1.0);
83 }
84 }
85 }
86 return SparseMatrix::from_triplets(n, n, rows, cols, vals);
87}
88
89inline SparseMatrix backward_euler_matrix(int N, double coeff) {
90 const int n = N * N;
91 std::vector<idx> rows, cols;
92 std::vector<real> vals;
93 rows.reserve(5 * n);
94 cols.reserve(5 * n);
95 vals.reserve(5 * n);
96 for (int i = 0; i < N; ++i) {
97 for (int j = 0; j < N; ++j) {
98 int k = i * N + j;
99 rows.push_back(k);
100 cols.push_back(k);
101 vals.push_back(1.0 + 4.0 * coeff);
102 if (i > 0) {
103 rows.push_back(k);
104 cols.push_back((i - 1) * N + j);
105 vals.push_back(-coeff);
106 }
107 if (i < N - 1) {
108 rows.push_back(k);
109 cols.push_back((i + 1) * N + j);
110 vals.push_back(-coeff);
111 }
112 if (j > 0) {
113 rows.push_back(k);
114 cols.push_back(i * N + (j - 1));
115 vals.push_back(-coeff);
116 }
117 if (j < N - 1) {
118 rows.push_back(k);
119 cols.push_back(i * N + (j + 1));
120 vals.push_back(-coeff);
121 }
122 }
123 }
124 return SparseMatrix::from_triplets(n, n, rows, cols, vals);
125}
126
127inline SparseMatrix backward_euler_matrix(const Grid2D& grid, double coeff) {
128 return backward_euler_matrix(grid.N, coeff);
129}
130
131inline LinearSolver make_cg_solver(const SparseMatrix& A, real tol = 1e-6) {
132 return [&A, tol](const Vector& rhs, Vector& x) {
134 return cg(op, rhs, x, tol);
135 };
136}
137
138} // namespace num::pde
139
140namespace num {
142}
Conjugate gradient solvers.
constexpr idx size() const noexcept
Definition vector.hpp:83
Sparse matrix in Compressed Sparse Row (CSR) format.
Definition sparse.hpp:15
static SparseMatrix from_triplets(idx n_rows, idx n_cols, const std::vector< idx > &rows, const std::vector< idx > &cols, const std::vector< real > &vals)
Build from coordinate (COO / triplet) lists.
Definition sparse.cpp:25
Backend enum and default backend selection.
2D uniform interior grid: geometry only, no field data.
Compressed Sparse Row (CSR) matrix and operations.
Universal linear solver callable type.
SparseMatrix laplacian_sparse_2d(int N)
Definition diffusion.hpp:51
void diffusion_step_2d_4th_dirichlet(Vector &u, int N, double coeff, Backend b=best_backend)
Definition diffusion.hpp:30
void diffusion_step_2d_dirichlet(Vector &u, int N, double coeff, Backend b=best_backend)
Definition diffusion.hpp:21
void diffusion_step_2d(Vector &u, int N, double coeff, Backend b=best_backend)
Definition diffusion.hpp:15
SparseMatrix backward_euler_matrix(int N, double coeff)
Definition diffusion.hpp:89
LinearSolver make_cg_solver(const SparseMatrix &A, real tol=1e-6)
void laplacian_stencil_2d(const BasicVector< T > &x, BasicVector< T > &y, int N)
Definition stencil.hpp:22
double real
Definition types.hpp:10
Backend
Definition policy.hpp:7
std::function< SolverResult(const Vector &rhs, Vector &x)> LinearSolver
Callable that solves .
constexpr Backend best_backend
Definition policy.hpp:64
void laplacian_stencil_2d_4th(const BasicVector< T > &x, BasicVector< T > &y, int N)
Fourth-order 2D Laplacian cross stencil.
Definition stencil.hpp:66
void laplacian_stencil_2d_periodic(const BasicVector< T > &x, BasicVector< T > &y, int N)
Periodic second-order 2D Laplacian stencil.
Definition stencil.hpp:42
constexpr real e
Definition math.hpp:44
void axpy(real alpha, const Vector &x, Vector &y, Backend b=default_backend)
Compute .
Definition vector.cpp:44
SolverResult cg(const Matrix &A, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
Definition cg.cpp:8
Higher-order stencil and grid-sweep utilities.
int N
interior nodes per side
Definition grid2d.hpp:14
Adapt a SparseMatrix to the operator protocol.
Definition sparse.hpp:11
Dense vector storage and operations.