summaryrefslogtreecommitdiff
path: root/src/main/SAPInteractor.h
blob: b85e2a994a426a70e6ef829b1e56120682d402c7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * SAPInteractor.h
 *
 *  Created on: May 29, 2011
 *      Author: jakob
 */

#ifndef SAPINTERACTOR_H_
#define SAPINTERACTOR_H_

#include <vector>
#include <map>
#include "Interactor.h"
#include "Particle.h"
#include "Element.h"

namespace vhc {

/** Sweep and Prune Interactor. Interacteur de particules qui utilise une methode de "sweep and prune" pour determiner
 *  les interactions entre particules. Cette methode consiste a:
 *  <ol>
 *  <li> Projetter les particules le long de l'accelerateur. </li>
 *  <li> Trier les particules en fonction de leur position lineaire, obtenue au point precedent. </li>
 *  <li> Parcourir les particules deux a deux et verifier si ils sont proches dans un rayon d'interaction.
 *       Bien que cette methode semble avoir une complexite de O(n^2), en realite il faut faire beaucoup moins de tests.
 *       Ceci car les particules sont tries en fonction de leur position lineaire et on peut donc arreter de tester des qu'on rencontre une
 *       particules qui est plus loin que la premiere. </li>
 *  </ol>
 *  La partie la plus couteuse de cet algorithme est le tri. Or en utilisant la methode de trie quicksort, on obtient une complexite de O(n log n).
 *  Une amelioration possible et assez facile serait d'utiliser un insert sort apres avoir utilise le quicksort quelues temps.
 *  L'idee est qu'un insert sort est presque de complexite lineaire pour une collection presque entierement triee. On ferait donc l'assomption que
 *  l'ordre des particules ne changerait plus beaucoup apres quelque temps dans l'accelerateur. Cette methode donnerait une complexite de presque O(n) */
class SAPInteractor: public Interactor {
protected:

	/** Contient une particule et sa position lineaire associee. */
	class LinearParticleContainer {
	private:
		Particle *const particle;
		double linear;
	public:
		LinearParticleContainer(Particle *const particle, double linear = 0);
		Particle *const getParticle() const;
		double getLinear() const;
		void setLinear(double value);
	};

	/** Particules geres par cet interacteur. */
	std::vector<LinearParticleContainer*> particles;

	/** Dictionnaire associant un element a sa position lineaire. */
	std::map<Element*, double> elementLinears;

	/** Projette tous les particules sur l'accelerateur afin de les lineariser. */
	void linearizeParticles();

	/** Compare la position lineaire de deux particules.
	 *  @return true si la position lineaire de la premiere particules est plus petite que la deuxieme */
	static bool compare(LinearParticleContainer *const p1, LinearParticleContainer *const p2);

	/** Rayon d'interaction. */
	double interactionRadius;

public:

	/** Rayon d'interaction par defaut. */
	static const double DEFAULT_INTERACTION_RADIUS;

	SAPInteractor();
	virtual ~SAPInteractor();

	/** Retourne le rayon d'interaction. L'interaction entre particules separes de plus de deux fois ce rayon,
	 *  selon leur projection, est neglige. */
	double getInteractionRadius() const;

	/** Affect le rayon d'interaction. */
	void setInteractionRadius(double value);

	/** Appelee quand l'accelerateur contenant cet interacteur est ferme. */
	virtual void acceleratorClosed(const Accelerator& acc);

	/** Appelee lors de l'ajout d'une particule. Ajoute la particule au particules simules par cet interacteur. */
	virtual void react(const ParticleAddedEvent& event);

	/** Appelee lors de l'enlevement d'une particule. Enleve la particule des particules simules par cet interacteur. */
	virtual void react(const ParticleRemovedEvent& event);

	virtual void applyInteractions();
};

}

#endif /* SAPINTERACTOR_H_ */