#pragma once #include "modules/mesh/mesh1d.h" #include "core/global_config.h" #include "utils/matrix.h" #include "utils/vector.h" namespace fluids { template struct Diffusion1D{ const core::Configs& cfg; const mesh::Mesh1D& mesh; T Gamma{1}; // Constructor Diffusion1D(const core::Configs& configs, const mesh::Mesh1D& Mesh, T Gamma_const=T(1)): cfg(configs), mesh(Mesh), Gamma(Gamma_const) {} void assemble(utils::Matrix& A, utils::Vector& b, utils::Vector& s){ uint64_t N = mesh.center_idx + 1; if (N < 3){ throw std::runtime_error("Diffusion1D: need N>=3"); } if (A.rows() != N || A.cols() != N){ A = utils::Matrix(N, N, T(0)); } if (b.size() != N){ b = utils::Vector(N, T(0)); } if (cfg.grid == core::GridKind::Uniform){ // Core of A if (cfg.fd == core::FDKind::Central){ uniform_central_finite_diffrence_2_order(A,b,s); } // Left BC of A if (cfg.left.kind == core::BCKind::Dirichlet){ BC_uniform_backward_finite_diffrence_2_order_Dirichlet(A,b,s); }else if (cfg.left.kind == core::BCKind::Neumann){ BC_uniform_backward_finite_diffrence_2_order_Neumann(A,b,s); } } } void uniform_central_finite_diffrence_2_order(utils::Matrix& A, utils::Vector& b, utils::Vector& s){ T xm, xc, xp; for (uint64_t i = 1; i < mesh.center_idx; ++i){ xm = mesh.center(i-1); xc = mesh.center(i); xp = mesh.center(i+1); A(i, i-1) = Gamma/(xc - xm); A(i, i) = -((Gamma/(xp - xc)) + (Gamma/(xc - xm))); A(i, i+1) = Gamma/(xp - xc); b[i] = -s[i]*mesh.dx(i); } } void BC_uniform_backward_finite_diffrence_2_order_Dirichlet(utils::Matrix& A, utils::Vector& b, utils::Vector& s){ T xm; T xw = mesh.vertice(0); T xc = mesh.center(0); T xp = mesh.center(1); T xe; uint64_t N = mesh.center_idx; A(0, 0) = -((Gamma/(xp - xc)) + (Gamma/(xc - xw))); A(0, 1) = Gamma/(xp - xc); b[0] = -s[0]*mesh.dx(0) - Gamma*(cfg.left.value/(xc - xw)); xm = mesh.center(N-1); xc = mesh.center(N); xe = mesh.vertice(N+1); A(N, N-1) = Gamma/(xc - xm); A(N, N) = -((Gamma/(xe - xc)) + (Gamma/(xc - xm))); b[N] = -s[N]*mesh.dx(N) - Gamma*(cfg.right.value/(xe - xc)); A.print(); b.print(); } void BC_uniform_backward_finite_diffrence_2_order_Neumann(utils::Matrix& A, utils::Vector& b, utils::Vector& s){ T xm; T xc = mesh.center(0); T xp = mesh.center(1); uint64_t N = mesh.center_idx; A(0, 0) = -Gamma/(xp - xc); A(0, 1) = Gamma/(xp - xc); b[0] = -s[0]*mesh.dx(0) - (Gamma*cfg.left.value); xm = mesh.center(N-1); xc = mesh.center(N); A(N, N-1) = Gamma/(xc - xm); A(N, N) = -Gamma/(xc - xm); b[N] = -s[N]*mesh.dx(N) - Gamma*(cfg.right.value); A.print(); b.print(); } }; } // end namespace fluids