Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}