Пример #1
0
	/*!
	Returns true if cell spanning given volume overlaps
	this sphere, false otherwise.
	*/
	bool overlaps(
		const Vector_T& cell_start,
		const Vector_T& cell_end
	) {
		for (size_t i = 0; i < size_t(cell_start.size()); i++) {
			if (cell_start[i] > cell_end[i]) {
				std::cerr <<  __FILE__ << "(" << __LINE__<< ") "
					<< "Starting coordinate of cell at index " << i
					<< " is larger than ending coordinate: "
					<< cell_start[i] << " > " << cell_end[i]
					<< std::endl;
				abort();
			}
		}

		// https://stackoverflow.com/questions/4578967
		Scalar_T distance2 = 0;
		for (size_t i = 0; i < size_t(cell_start.size()); i++) {
			if (this->center[i] < cell_start[i]) {
				distance2 += std::pow(this->center[i] - cell_start[i], 2);
			} else if (this->center[i] > cell_end[i]) {
				distance2 += std::pow(this->center[i] - cell_end[i], 2);
			}
		}

		return distance2 < std::pow(this->radius, 2);
	}
Пример #2
0
	/*!
	Returns true if cell spanning given volume overlaps
	this box, false otherwise.
	*/
	bool overlaps(
		const Vector_T& cell_start,
		const Vector_T& cell_end
	) {
		for (size_t i = 0; i < size_t(cell_start.size()); i++) {
			if (cell_start[i] > cell_end[i]) {
				std::cerr <<  __FILE__ << "(" << __LINE__<< ") "
					<< "Starting coordinate of cell at index " << i
					<< " is larger than ending coordinate: "
					<< cell_start[i] << " > " << cell_end[i]
					<< std::endl;
				abort();
			}
		}

		bool overlaps = true;
		for (size_t i = 0; i < size_t(cell_start.size()); i++) {
			if (
				cell_start[i] >= this->end[i]
				or cell_end[i] <= this->start[i]
			) {
				overlaps = false;
				break;
			}
		}

		return overlaps;
	}
Пример #3
0
	bool set_geometry(
		const Vector_T& given_start,
		const Vector_T& given_end
	) {
		for (size_t i = 0; i < size_t(given_start.size()); i++) {
			if (given_end[i] <= given_start[i]) {
				return false;
			}
		}

		this->start = given_start;
		this->end = given_end;
		return true;
	}
Пример #4
0
/*!
Returns magnetic field from a point dipole.

\param [dipole_moments_positions] List of dipole moments and
their corresponding positions
\param [field_position] Position of the returned total magnetic field

Assumes Vector_T is a 3d Eigen vector or similar.

Example usage:
\code
const Eigen::Vector3d field
	= background_B::get_dipole_field_0d(
		background_B::get_earth_dipole_moment<Eigen::Vector3d>(),
		{0, 0, 0},
		{6.3712e7, 0, 0} // at 10 Earth radii in +x
	);
\endcode

\see background_B::get_dipole_field()
*/
template <class Vector_T> Vector_T get_dipole_field_0d(
	const std::vector<std::pair<Vector_T, Vector_T>>& dipole_moments_positions,
	const Vector_T& field_position
) {
	static_assert(
		Vector_T::SizeAtCompileTime == 3,
		"ERROR: Only 3 component vectors supported"
	);

	Vector_T ret_val;
	ret_val.setZero();

	constexpr double vacuum_permeability = 1.256637061e-6;

	for (const auto dip_mom_pos: dipole_moments_positions) {

		const Vector_T r = field_position - dip_mom_pos.second;

		bool far_enough = false;
		for (size_t i = 0; i < size_t(r.size()); i++) {
			if (fabs(r[i]) > std::numeric_limits<typename Vector_T::Scalar>::epsilon()) {
				far_enough = true;
				break;
			}
		}
		if (not far_enough) {
			ret_val += 2.0 / 3.0 * vacuum_permeability * dip_mom_pos.first;
			continue;
		}

		const double r3 = r.norm() * r.squaredNorm();
		const Vector_T
			r_unit = r / r.norm(),
			projected_dip_mom = dip_mom_pos.first.dot(r_unit) * r_unit;

		ret_val += 1e-7 * (3 * projected_dip_mom - dip_mom_pos.first) / r3;

	}

	return ret_val;
}