Skip to content
Snippets Groups Projects
MethodOfImages.hpp 7.42 KiB
//
// Created by jstark on 01.06.21.
//

#ifndef OPENFPM_NUMERICS_BOUNDARYCONDITIONS_METHODOFIMAGES_HPP
#define OPENFPM_NUMERICS_BOUNDARYCONDITIONS_METHODOFIMAGES_HPP

#include <cmath>
// Include OpenFPM header files
#include "Vector/vector_dist_subset.hpp"

#define PID_VECTOR_TYPE openfpm::vector<aggregate<int>>
#define KEY_VECTOR_TYPE openfpm::vector<vect_dist_key_dx>

/**@brief Class for getting mirror particles to impose Neumann BCs
 *
 * @details Source refers to the particles close to the boundary that will we mirrored at the boundary. The source
 * particles do not form an individual subset because subsets mustn't overlap and source particles belong to the real
 * particles. Instead, store the keys of the desired source particles in a vector and pass them to the constructor.
 *
 * @tparam SurfaceNormal Index of property to which the surface normal should be written to.
 * @tparam vd_type Template type of input particle vector_dist.
 */
template <size_t SurfaceNormal, typename vd_type>
class MethodOfImages {

public:
	typedef vector_dist_subset<vd_type::dims, typename vd_type::stype, typename vd_type::value_type> vd_subset_type;
	typedef Point<vd_type::dims, typename vd_type::stype> point_type;
	
	/**@brief Constructor
	 *
	 * @param vd Input particle vector_dist of type vd_type.
	 * @param keys_source Vector containing keys of source particles (key-type: openfpm::vector<vect_dist_key_dx>).
	 * @param subset_id_mirror ID of subset containing the mirror particles (default=1).
	 */
	MethodOfImages(
			vd_type & vd,
			const KEY_VECTOR_TYPE & keys_source,
			const size_t subset_id_real = 0,
			const size_t subset_id_mirror = 1)
			: keys_source(keys_source)
			, subset_id_real(subset_id_real)
			, subset_id_mirror(subset_id_mirror)
			, Real(vd, subset_id_real)
			, Mirror(vd, subset_id_mirror)
	
	{
#ifdef SE_CLASS1
		check_if_ghost_isometric(vd);
#endif // SE_CLASS1
	}
	
	//	Member variables
	size_t subset_id_real; ///< ID of subset containing the real particles (default=0).
	size_t subset_id_mirror; ///< ID of subset containing the mirror particles (default=1).
	KEY_VECTOR_TYPE keys_source; ///< Vector containing keys of source particles.
	PID_VECTOR_TYPE pid_mirror; ///< Vector containing indices of mirror particles.
	vd_subset_type Mirror; ///< Subset containing the mirror particles.
	vd_subset_type Real;
	openfpm::vector<openfpm::vector<size_t>> key_map_source_mirror;
	
	/**@brief Place mirror particles along the surface normal.
	 *
	 * @param vd Input particle vector_dist of type vd_type.
	 */
	void get_mirror_particles(vd_type & vd)
	{
		auto lastReal = vd.size_local();
		for (int i = 0; i < keys_source.size(); i++)