5#ifndef WAVESIMC_SOLVER_COMPLEX_HPP
6#define WAVESIMC_SOLVER_COMPLEX_HPP
8#include "CustomLibraries/np.hpp"
9#include "helper_func.hpp"
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)
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);
37 int dimensions_1[] = {nt, nx, nz};
38 boost::multi_array<double, 3> u = np::zeros<double>(dimensions_1);
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);
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);
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]);
54 for (
int n = 1; n < nt - 1; n++)
57 for (
int i = 0; i < nx; i++)
59 for (
int j = 0; j < nz; j++)
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];
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);
72 boost::multi_array<double, 2> dudx =
dfdx(u_n, dx);
73 boost::multi_array<double, 2> dudz =
dfdz(u_n, dz);
85 for (
int i = 0; i < nx; i++)
87 for (
int j = 0; j < nz; j++)
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];
94 for (
int i = 0; i < nx; i++)
96 for (
int j = 0; j < nz; j++)
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];
104 for (
int i = 0; i < nx; i++)
106 u[n + 1][i][0] = 0.0;
107 u[n + 1][i][nz - 1] = 0.0;
109 for (
int j = 0; j < nz; j++)
111 u[n + 1][0][j] = 0.0;
112 u[n + 1][nx - 1][j] = 0.0;
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.
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.
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.
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.
boost::multi_array< double, 2 > divergence(boost::multi_array< double, 2 > f1, boost::multi_array< double, 2 > f2, double dx, double dz)
::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.