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/// @todo Add real-valued diffusion ADI variants, variable coefficients, and
4/// boundary-condition parameterization.
5#pragma once
6
7#include "core/vector.hpp"
9#include "pde/stencil.hpp"
10#include <complex>
11#include <vector>
12
13namespace num {
14
16 int N = 0;
17 double dt = 0.0;
18 double h = 0.0;
19
20 CrankNicolsonADI() = default;
21
22 CrankNicolsonADI(int N_, double dt_, double h_)
23 : N(N_),
24 dt(dt_),
25 h(h_) {
26 using cplx = std::complex<double>;
27 auto factor = [&](double tau) {
28 double alpha = tau / (4.0 * h * h);
29 cplx a(0.0, -alpha);
30 cplx b(1.0, 2.0 * alpha);
32 td.factor(N, a, b, a);
33 return td;
34 };
35 td_half_ = factor(dt * 0.5);
36 td_full_ = factor(dt);
37 }
38
39 void sweep(CVector& psi, bool x_axis, double tau) const {
40 using cplx = std::complex<double>;
41 const ComplexTriDiag& td = (tau < dt * 0.75) ? td_half_ : td_full_;
42 const cplx ia(0.0, tau / (4.0 * h * h));
43 const cplx diag(1.0, -2.0 * tau / (4.0 * h * h));
44
45 auto apply = [&](std::vector<cplx>& fiber) {
46 std::vector<cplx> rhs(N);
47 for (int i = 0; i < N; ++i) {
48 cplx prev = (i > 0) ? fiber[i - 1] : cplx{};
49 cplx next = (i < N - 1) ? fiber[i + 1] : cplx{};
50 rhs[i] = ia * prev + diag * fiber[i] + ia * next;
51 }
52 td.solve(rhs);
53 fiber = std::move(rhs);
54 };
55
56 if (x_axis) {
57 col_fiber_sweep(psi, N, apply);
58 } else {
59 row_fiber_sweep(psi, N, apply);
60 }
61 }
62
63private:
64 ComplexTriDiag td_half_;
65 ComplexTriDiag td_full_;
66};
67
68} // 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:164
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:151
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:22
CrankNicolsonADI()=default
void sweep(CVector &psi, bool x_axis, double tau) const
Definition adi.hpp:39
Precomputed Thomas solver for constant-coefficient complex systems.
Dense vector storage and operations.