Beispiel #1
0
/*!
Returns maximum norm if p == 0
*/
template<class Grid_T> double get_diff_lp_norm(
	const std::vector<uint64_t>& cells,
	const Grid_T& grid,
	const double p,
	const double cell_volume,
	const size_t dimension
) {
	double local_norm = 0, global_norm = 0;
	for (const auto& cell: cells) {
		const auto* const cell_data = grid[cell];
		if (cell_data == NULL) {
			std::cerr << __FILE__ << ":" << __LINE__
				<< ": No data for cell " << cell
				<< std::endl;
			abort();
		}

		const auto center = grid.geometry.get_center(cell);

		if (p == 0) {
			local_norm = std::max(
				local_norm,
				std::fabs(
					(*cell_data)[Gradient()][dimension]
					- grad_of_function(center[dimension])
				)
			);
		} else {
			local_norm += std::pow(
				std::fabs(
					(*cell_data)[Gradient()][dimension]
					- grad_of_function(center[dimension])
				),
				p
			);
		}
	}
	local_norm *= cell_volume;

	if (p == 0) {
		MPI_Comm comm = grid.get_communicator();
		MPI_Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_MAX, comm);
		MPI_Comm_free(&comm);
		return global_norm;
	} else {
		MPI_Comm comm = grid.get_communicator();
		MPI_Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_SUM, comm);
		MPI_Comm_free(&comm);
		return std::pow(global_norm, 1.0 / p);
	}
}
Beispiel #2
0
/*!
Returns maximum norm
*/
template<class Grid_T> std::array<double, 3> get_max_norm(
	const std::vector<uint64_t>& cells,
	const Grid_T& grid
) {
	std::array<double, 3>
		local_norm{{0, 0, 0}},
		global_norm{{0, 0, 0}};

	for (const auto& cell: cells) {
		const auto* const cell_data = grid[cell];
		if (cell_data == NULL) {
			std::cerr << __FILE__ << ":" << __LINE__
				<< ": No data for cell " << cell
				<< std::endl;
			abort();
		}

		const auto center = grid.geometry.get_center(cell);

		const auto grad_of = grad_of_function(center);

		for (size_t i = 0; i < 3; i++) {
			local_norm[i] = std::max(
				local_norm[i],
				std::fabs((*cell_data)[Gradient()][i] - grad_of[i])
			);
		}
	}

	MPI_Comm comm = grid.get_communicator();
	MPI_Allreduce(
		local_norm.data(),
		global_norm.data(),
		3,
		MPI_DOUBLE,
		MPI_MAX,
		comm
	);
	MPI_Comm_free(&comm);

	return global_norm;
}