WaveSimPP 1.0
A C library for solving the wave equation and reconstructing the wave field
All Classes Namespaces Functions Modules Pages
solver_complex.hpp
1//
2// Created by Yan Cheng on 11/28/22.
3//
4
5#ifndef WAVESIMC_SOLVER_COMPLEX_HPP
6#define WAVESIMC_SOLVER_COMPLEX_HPP
7
8#include "CustomLibraries/np.hpp"
9#include "helper_func.hpp"
10
11#include <cmath>
12
18namespace waveSimCore
19{
22 boost::multi_array<double, 3> wave_solver_complex(boost::multi_array<double, 2> c,
23 double dt, double dx, double dz, int nt, int nx, int nz,
24 boost::multi_array<double, 3> f,
25 boost::multi_array<double, 2> sigma_1, boost::multi_array<double, 2> sigma_2)
26 {
27
28 const boost::multi_array<double, 2> C1 = 1.0 + (dt * (sigma_1 + sigma_2) * 0.5);
29 const boost::multi_array<double, 2> C2 = (sigma_1 * sigma_2 * np::pow(dt, 2.0)) - 2.0;
30 const boost::multi_array<double, 2> C3 = 1.0 - (dt * (sigma_1 + sigma_2) * 0.5);
31 const boost::multi_array<double, 2> C4 = np::pow(dt * c, 2.0);
32 const boost::multi_array<double, 2> C5 = 1.0 + (dt * sigma_1 * 0.5);
33 const boost::multi_array<double, 2> C6 = 1.0 + (dt * sigma_2 * 0.5);
34 const boost::multi_array<double, 2> C7 = 1.0 - (dt * sigma_1 * 0.5);
35 const boost::multi_array<double, 2> C8 = 1.0 - (dt * sigma_2 * 0.5);
36
37 int dimensions_1[] = {nt, nx, nz};
38 boost::multi_array<double, 3> u = np::zeros<double>(dimensions_1);
39
40 int dimensions_2[] = {nx, nz};
41 boost::multi_array<double, 2> q_1 = np::zeros<double>(dimensions_2);
42 int dimensions_3[] = {nx, nz};
43 boost::multi_array<double, 2> q_2 = np::zeros<double>(dimensions_3);
44
45 int dimensions_4[] = {nx, nz};
46 boost::multi_array<double, 2> u_xx = np::zeros<double>(dimensions_4);
47 int dimensions_5[] = {nx, nz};
48 boost::multi_array<double, 2> u_zz = np::zeros<double>(dimensions_5);
49
50 boost::multi_array<double, 2> f_n(boost::extents[nx][nz]);
51 boost::multi_array<double, 2> u_n(boost::extents[nx][nz]);
52 boost::multi_array<double, 2> u_n_1(boost::extents[nx][nz]);
53
54 for (int n = 1; n < nt - 1; n++)
55 {
56
57 for (int i = 0; i < nx; i++)
58 {
59 for (int j = 0; j < nz; j++)
60 {
61 f_n[i][j] = f[n][i][j];
62 u_n[i][j] = u[n][i][j];
63 u_n_1[i][j] = u[n - 1][i][j];
64 }
65 }
66
67 boost::multi_array<double, 2> div = divergence(q_1 * sigma_1, q_2 * sigma_2, dx, dz);
68 boost::multi_array<double, 2> dq_1dx = dfdx(q_1, dx);
69 boost::multi_array<double, 2> dq_2dz = dfdz(q_2, dz);
70 u_xx = d2fdx2(u_n, dx); // (nx, nz)
71 u_zz = d2fdz2(u_n, dz); // (nx, nz)
72 boost::multi_array<double, 2> dudx = dfdx(u_n, dx);
73 boost::multi_array<double, 2> dudz = dfdz(u_n, dz);
74
75 // for (int i = 1; i < nx-1; i++)
76 // {
77 // for (int j = 1; j < nz-1; j++)
78 // {
79 // u_xx[i][j] = u_n[i+1][j] + u_n[i-1][j] - 2.0 * u_n[i][j];
80 // u_zz[i][j] = u_n[i][j+1] + u_n[i][j-1] - 2.0 * u_n[i][j];
81 // }
82 // }
83
84 // ! Update u
85 for (int i = 0; i < nx; i++)
86 {
87 for (int j = 0; j < nz; j++)
88 {
89 u[n + 1][i][j] = (C4[i][j] * ((u_xx[i][j] / np::pow(dx, 2.0)) + (u_zz[i][j] / np::pow(dz, 2.0)) - div[i][j] + sigma_2[i][j] * dq_1dx[i][j] + sigma_1[i][j] * dq_2dz[i][j] + f_n[i][j]) - (C2[i][j] * u_n[i][j]) - (C3[i][j] * u_n_1[i][j])) / C1[i][j];
90 }
91 }
92
93 // ! Update q_1, q_2
94 for (int i = 0; i < nx; i++)
95 {
96 for (int j = 0; j < nz; j++)
97 {
98 q_1[i][j] = (dt * dudx[i][j] + C7[i][j] * q_1[i][j]) / C5[i][j];
99 q_2[i][j] = (dt * dudz[i][j] + C8[i][j] * q_2[i][j]) / C6[i][j];
100 }
101 }
102 //
103 // Dirichlet boundary condition
104 for (int i = 0; i < nx; i++)
105 {
106 u[n + 1][i][0] = 0.0;
107 u[n + 1][i][nz - 1] = 0.0;
108 }
109 for (int j = 0; j < nz; j++)
110 {
111 u[n + 1][0][j] = 0.0;
112 u[n + 1][nx - 1][j] = 0.0;
113 }
114 }
115 return u;
116 }
117}
118#endif // WAVESIMC_SOLVER_HPP
boost::multi_array< double, 3 > wave_solver_complex(boost::multi_array< double, 2 > c, double dt, double dx, double dz, int nt, int nx, int nz, boost::multi_array< double, 3 > f, boost::multi_array< double, 2 > sigma_1, boost::multi_array< double, 2 > sigma_2)
boost::multi_array< double, 2 > dfdz(boost::multi_array< double, 2 > f, double dz)
Takes the partial derivative of a 2D matrix f with respect to z.
Definition: helper_func.hpp:25
boost::multi_array< double, 2 > dfdx(boost::multi_array< double, 2 > f, double dx)
Takes the partial derivative of a 2D matrix f with respect to x.
Definition: helper_func.hpp:18
boost::multi_array< double, 2 > d2fdx2(boost::multi_array< double, 2 > f, double dx)
Takes the second partial derivative of a 2D matrix f with respect to x.
Definition: helper_func.hpp:32
boost::multi_array< double, 2 > d2fdz2(boost::multi_array< double, 2 > f, double dz)
Takes the second partial derivative of a 2D matrix f with respect to z.
Definition: helper_func.hpp:40
boost::multi_array< double, 2 > divergence(boost::multi_array< double, 2 > f1, boost::multi_array< double, 2 > f2, double dx, double dz)
Definition: helper_func.hpp:49
::value constexpr boost::multi_array< T, ND > pow(const boost::multi_array< T, ND > &input_array, const T exponent)
Implements the numpy pow function on multi arrays.
Definition: np.hpp:319