numerics 0.1.0
Loading...
Searching...
No Matches
adi.hpp
Go to the documentation of this file.
1/// @file pde/adi.hpp
2/// @brief Crank-Nicolson ADI sweeps for 2D parabolic systems.
3#pragma once
4
5#include "core/vector.hpp"
7#include "pde/stencil.hpp"
8#include <complex>
9#include <vector>
10
11namespace num {
12
14 int N = 0;
15 double dt = 0.0;
16 double h = 0.0;
17
18 CrankNicolsonADI() = default;
19
20 CrankNicolsonADI(int N_, double dt_, double h_)
21 : N(N_),
22 dt(dt_),
23 h(h_) {
24 using cplx = std::complex<double>;
25 auto factor = [&](double tau) {
26 double alpha = tau / (4.0 * h * h);
27 cplx a(0.0, -alpha);
28 cplx b(1.0, 2.0 * alpha);
30 td.factor(N, a, b, a);
31 return td;
32 };
33 td_half_ = factor(dt * 0.5);
34 td_full_ = factor(dt);
35 }
36
37 void sweep(CVector& psi, bool x_axis, double tau) const {
38 using cplx = std::complex<double>;
39 const ComplexTriDiag& td = (tau < dt * 0.75) ? td_half_ : td_full_;
40 const cplx ia(0.0, tau / (4.0 * h * h));
41 const cplx diag(1.0, -2.0 * tau / (4.0 * h * h));
42
43 auto apply = [&](std::vector<cplx>& fiber) {
44 std::vector<cplx> rhs(N);
45 for (int i = 0; i < N; ++i) {
46 cplx prev = (i > 0) ? fiber[i - 1] : cplx{};
47 cplx next = (i < N - 1) ? fiber[i + 1] : cplx{};
48 rhs[i] = ia * prev + diag * fiber[i] + ia * next;
49 }
50 td.solve(rhs);
51 fiber = std::move(rhs);
52 };
53
54 if (x_axis)
55 col_fiber_sweep(psi, N, apply);
56 else
57 row_fiber_sweep(psi, N, apply);
58 }
59
60 private:
61 ComplexTriDiag td_half_;
62 ComplexTriDiag td_full_;
63};
64
65} // namespace num
Dense owning vector.
Definition vector.hpp:16
void row_fiber_sweep(BasicVector< T > &data, int N, F &&f)
Apply a mutable 1D operation to each row fiber.
Definition stencil.hpp:154
std::complex< real > cplx
Definition types.hpp:12
void col_fiber_sweep(BasicVector< T > &data, int N, F &&f)
Apply a mutable 1D operation to each column fiber.
Definition stencil.hpp:141
Higher-order stencil and grid-sweep utilities.
void solve(std::vector< cplx > &d) const
void factor(int n_, cplx a_, cplx b_, cplx c_)
CrankNicolsonADI(int N_, double dt_, double h_)
Definition adi.hpp:20
CrankNicolsonADI()=default
void sweep(CVector &psi, bool x_axis, double tau) const
Definition adi.hpp:37
Precomputed Thomas solver for constant-coefficient complex systems.
Dense vector storage and operations.