template <class Scalar_T> std::vector<Scalar_T> normalize_solution( const Scalar_T grid_length_x, const size_t grid_size_x, const size_t grid_size_y, const size_t grid_size_z, const std::vector<Scalar_T>& solution ) { Scalar_T avg_analytic = 0; for ( const auto i: get_analytic_solution( grid_length_x, grid_size_x, grid_size_y, grid_size_z ) ) { avg_analytic += i; } avg_analytic /= solution.size(); Scalar_T avg_solution = 0; for (const auto i: solution) { avg_solution += i; } avg_solution /= solution.size(); std::vector<Scalar_T> ret_val; ret_val.reserve(solution.size()); for (const auto i: solution) { ret_val.push_back(i - avg_solution + avg_analytic); } return ret_val; }
int main() { using scalar_type = double; constexpr double grid_length_x = 4 * M_PI, grid_length_y = 1 * M_PI, grid_length_z = 2 * M_PI; constexpr size_t grid_size_x = 32, grid_size_y = 32, grid_size_z = 32; const auto rhs = get_rhs<scalar_type>( grid_length_x, grid_length_y, grid_length_z, grid_size_x, grid_size_y, grid_size_z ); auto solution = pamhd::poisson::solve_bicgstab( grid_size_x, grid_size_y, grid_size_z, grid_length_x / grid_size_x, grid_length_y / grid_size_y, grid_length_z / grid_size_z, rhs ); solution = normalize_solution( grid_length_x, grid_length_y, grid_length_z, grid_size_x, grid_size_y, grid_size_z, solution ); const auto analytic = get_analytic_solution( grid_length_x, grid_length_y, grid_length_z, grid_size_x, grid_size_y, grid_size_z ); const double diff_l1_norm = get_diff_lp_norm(solution, analytic, scalar_type(1)), diff_l2_norm = get_diff_lp_norm(solution, analytic, scalar_type(2)), diff_linf_norm = get_diff_lp_norm(solution, analytic, scalar_type(0)); if (diff_l1_norm > 30) { std::cerr << __FILE__ << "(" << __LINE__ << "): " << "L1 norm too large: " << diff_l1_norm << std::endl; abort(); } if (diff_l2_norm > 0.3) { std::cerr << __FILE__ << "(" << __LINE__ << "): " << "L2 norm too large: " << diff_l2_norm << std::endl; abort(); } if (diff_linf_norm > 0.01) { std::cerr << __FILE__ << "(" << __LINE__ << "): " << "Infinite L norm too large: " << diff_linf_norm << std::endl; abort(); } return EXIT_SUCCESS; }