summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2011-05-29 20:09:19 +0000
committerJakob Odersky <jodersky@gmail.com>2011-05-29 20:09:19 +0000
commit00d592af835e892902bdf6cc5db29a64f24ab9d3 (patch)
treec68991fb19735fcba7db6ffd7bc9a0767f453c39
parent3f28311fd6fb4830b4c64c59daa6a53f24953396 (diff)
downloadvhc-00d592af835e892902bdf6cc5db29a64f24ab9d3.tar.gz
vhc-00d592af835e892902bdf6cc5db29a64f24ab9d3.tar.bz2
vhc-00d592af835e892902bdf6cc5db29a64f24ab9d3.zip
*Ajoute interactions avancees
*Ecrit conception *Commentaires
-rw-r--r--Makefile2
-rw-r--r--src/gui/BeamRenderer.cc54
-rw-r--r--src/gui/BeamRenderer.h37
-rw-r--r--src/gui/EnergyBeamRenderer.cc23
-rw-r--r--src/gui/EnergyBeamRenderer.h25
-rw-r--r--src/gui/KeyManager.cc2
-rw-r--r--src/gui/Main.cc7
-rw-r--r--src/gui/Renderer.h12
-rw-r--r--src/gui/Stage.cc22
-rw-r--r--src/gui/Stage.h6
-rw-r--r--src/gui/gui.pro4
-rw-r--r--src/main/Accelerator.cc31
-rw-r--r--src/main/Accelerator.h8
-rw-r--r--src/main/Beam.cc2
-rw-r--r--src/main/Beam.h2
-rw-r--r--src/main/BruteForceInteractor.cc1
-rw-r--r--src/main/BruteForceInteractor.h1
-rw-r--r--src/main/Color.cc80
-rw-r--r--src/main/Color.h22
-rw-r--r--src/main/Interactor.cc4
-rw-r--r--src/main/Interactor.h4
-rw-r--r--src/main/Makefile2
-rw-r--r--src/main/SAP.cc21
-rw-r--r--src/main/SAP.h41
-rw-r--r--src/main/SAPInteractor.cc130
-rw-r--r--src/main/SAPInteractor.h93
-rw-r--r--src/test/AcceleratorBenchmarkTest.cc7
-rw-r--r--src/test/ElementsSimulationTest.cc4
-rw-r--r--src/test/P10ExerciceTest.cc81
-rw-r--r--src/test/exerciceP11Test.cc4
30 files changed, 456 insertions, 276 deletions
diff --git a/Makefile b/Makefile
index 72ab508..da10e0f 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ export BINDIR = $(BASEDIR)/bin
#
# CXXFLAGS += -Wall
# CXXFLAGS += -ansi -pedantic -Wall # pour les purs et durs
-CXXFLAGS += -g # pour debugger
+# CXXFLAGS += -g # pour debugger
# CXXFLAGS += -pg # pour profiler
# LDFLAGS += -pg # pour profiler
CXXFLAGS += -O2 # pour optimiser la vitesse
diff --git a/src/gui/BeamRenderer.cc b/src/gui/BeamRenderer.cc
new file mode 100644
index 0000000..c3aab57
--- /dev/null
+++ b/src/gui/BeamRenderer.cc
@@ -0,0 +1,54 @@
+/*
+ * BeamRenderer.cc
+ *
+ * Created on: May 27, 2011
+ * Author: jakob
+ */
+
+#include <QtOpenGL>
+#include "BeamRenderer.h"
+#include "util.h"
+
+namespace vhc {
+
+BeamRenderer::BeamRenderer() {
+ // TODO Auto-generated constructor stub
+
+}
+
+BeamRenderer::~BeamRenderer() {
+ // TODO Auto-generated destructor stub
+}
+
+void BeamRenderer::render(const Beam& beam) const {
+ const Beam::ParticleCollection& particles = beam.getParticles();
+
+ if (_spheres) {
+ for (Beam::ParticleCollection::const_iterator i = particles.begin(); i != particles.end(); ++i) {
+ double pos[] = {(**i).getPosition().getX(), (**i).getPosition().getY(), (**i).getPosition().getZ()};
+ glPushMatrix();
+ glTranslated(pos[0], pos[1], pos[2]);
+ util::sphere(0.01);
+ glPopMatrix();
+ }
+ } else {
+ glBegin(GL_POINTS);
+ for (Beam::ParticleCollection::const_iterator i = particles.begin(); i != particles.end(); ++i) {
+ double pos[] = {(**i).getPosition().getX(), (**i).getPosition().getY(), (**i).getPosition().getZ()};
+ glVertex3dv(pos);
+ }
+ glEnd();
+
+ }
+
+}
+
+void BeamRenderer::setSpheresEnabled(bool value) {
+ _spheres = value;
+}
+
+bool BeamRenderer::getSpheresEnabled() const {
+ return _spheres;
+}
+
+}
diff --git a/src/gui/BeamRenderer.h b/src/gui/BeamRenderer.h
new file mode 100644
index 0000000..f1ca98d
--- /dev/null
+++ b/src/gui/BeamRenderer.h
@@ -0,0 +1,37 @@
+/*
+ * BeamRenderer.h
+ *
+ * Created on: May 27, 2011
+ * Author: jakob
+ */
+
+#ifndef BEAMRENDERER_H_
+#define BEAMRENDERER_H_
+
+#include "Renderer.h"
+#include "Beam.h"
+
+namespace vhc {
+
+/** Dessinateur standard de faisceaux. */
+class BeamRenderer: public Renderer<Beam> {
+private:
+ bool _spheres;
+
+public:
+ BeamRenderer();
+ virtual ~BeamRenderer();
+
+ /** Dessine un faisceau. */
+ virtual void render(const Beam& beam) const;
+
+ /** Change le mode de dessin des particules en spheres ou points. */
+ void setSpheresEnabled(bool value);
+
+ /** Retourne vrai si on dessine des spheres. */
+ bool getSpheresEnabled() const;
+};
+
+}
+
+#endif /* BEAMRENDERER_H_ */
diff --git a/src/gui/EnergyBeamRenderer.cc b/src/gui/EnergyBeamRenderer.cc
new file mode 100644
index 0000000..697af31
--- /dev/null
+++ b/src/gui/EnergyBeamRenderer.cc
@@ -0,0 +1,23 @@
+/*
+ * EnergyBeamRenderer.cc
+ *
+ * Created on: May 29, 2011
+ * Author: jakob
+ */
+
+#include "EnergyBeamRenderer.h"
+
+namespace vhc {
+
+EnergyBeamRenderer::EnergyBeamRenderer() {
+
+}
+
+EnergyBeamRenderer::~EnergyBeamRenderer() {
+}
+
+void EnergyBeamRenderer::render(const Beam& beam) const {
+
+}
+
+}
diff --git a/src/gui/EnergyBeamRenderer.h b/src/gui/EnergyBeamRenderer.h
new file mode 100644
index 0000000..7c04e9a
--- /dev/null
+++ b/src/gui/EnergyBeamRenderer.h
@@ -0,0 +1,25 @@
+/*
+ * EnergyBeamRenderer.h
+ *
+ * Created on: May 29, 2011
+ * Author: jakob
+ */
+
+#ifndef ENERGYBEAMRENDERER_H_
+#define ENERGYBEAMRENDERER_H_
+
+#include "BeamRenderer.h"
+
+namespace vhc {
+
+class EnergyBeamRenderer: BeamRenderer {
+public:
+ EnergyBeamRenderer();
+ virtual ~EnergyBeamRenderer();
+
+ virtual void render(const Beam& beam) const;
+};
+
+}
+
+#endif /* ENERGYBEAMRENDERER_H_ */
diff --git a/src/gui/KeyManager.cc b/src/gui/KeyManager.cc
index c7ccca0..1637bc2 100644
--- a/src/gui/KeyManager.cc
+++ b/src/gui/KeyManager.cc
@@ -43,7 +43,7 @@ void KeyManager::press(int key) {
stage.setRunning(!stage.isRunning());
break;
case Qt::Key_QuoteLeft:
- stage.getParticleRenderer().enableDrawSpheres(!stage.getParticleRenderer().isDrawSpheresEnabled());
+ stage.getBeamRenderer().setSpheresEnabled(! stage.getBeamRenderer().getSpheresEnabled());
break;
default:
break;
diff --git a/src/gui/Main.cc b/src/gui/Main.cc
index b3964d1..e89c378 100644
--- a/src/gui/Main.cc
+++ b/src/gui/Main.cc
@@ -24,6 +24,7 @@
#include "CircularBeam.h"
#include "Bunch.h"
#include "events.h"
+#include "SAPInteractor.h"
using namespace std;
using namespace vhc;
@@ -130,7 +131,7 @@ Une particule :
Dipole e6 = Dipole(Vector3D(-3, 2, 0), Vector3D(-2, 3, 0), 0.1, 1, Vector3D(0, 0, B));
Element** e7 = FODO(e6.getExitPosition(), Vector3D(2, 3, 0), 0.1, 1.0, b);
Dipole e8 = Dipole(Vector3D(2, 3, 0), Vector3D(3, 2, 0), 0.1, 1, Vector3D(0, 0, B));
- Accelerator* acc = new Accelerator();
+ Accelerator* acc = new Accelerator(new SAPInteractor);
//acc->add(e1);
for (int i = 0; i < 4; ++i) acc->add(e1[i][0]);
acc->add(e2);
@@ -168,8 +169,8 @@ Une particule :
Foo* foo = new Foo;
Bunch& bch = (Bunch&) acc->add(Bunch(ap1, 5, 1, stdDev, length, emittance, A_12, A_22));
- bch.Publisher<ParticleAddedEvent>::subscribe(foo);
- bch.Publisher<ParticleRemovedEvent>::subscribe(foo);
+ //bch.Publisher<ParticleAddedEvent>::subscribe(foo);
+ //bch.Publisher<ParticleRemovedEvent>::subscribe(foo);
acc->close();
diff --git a/src/gui/Renderer.h b/src/gui/Renderer.h
index 6be4373..f2141ec 100644
--- a/src/gui/Renderer.h
+++ b/src/gui/Renderer.h
@@ -11,24 +11,16 @@
namespace vhc {
template <typename T>
+/** Classe de base pour tout dessinateur. Un dessinateur peut dessiner un objet de son type. */
class Renderer {
public:
+
Renderer() {};
virtual ~Renderer() {};
- /** Methode qui doit etre appelee avant de dessiner une collection d'objets par <code>render</code>.
- * Cette methode gere des <code>glBegin()</code> en arriere-plan. */
- //virtual void begin() = 0;
-
/** Dessine un objet. */
virtual void render(const T& item) const = 0;
- //template <typename Container>
- //virtual void render(std::forward_iterator) const;
-
- /** Methode qui doit etre appelee avant de dessiner une collection d'objets par <code>render</code>.
- * Cette methode gere des <code>glBegin()</code> en arriere-plan. */
- //virtual void end() = 0;
};
}
diff --git a/src/gui/Stage.cc b/src/gui/Stage.cc
index 4c0328d..41c36a0 100644
--- a/src/gui/Stage.cc
+++ b/src/gui/Stage.cc
@@ -22,7 +22,7 @@ Stage::Stage(QWidget* parent):
keyManager(*this),
accelerator(NULL),
elementRenderer(),
- particleRenderer(),
+ beamRenderer(),
displayMode(FILL),
frameTime(0),
h(1E-12),
@@ -79,11 +79,11 @@ void Stage::paintGL() {
QString("heading: ") + QString::number(camera.getHeading()),
QString("pitch: ") + QString::number(camera.getPitch()),
QString("-----accelerator-----"),
- QString("Elements: ") + QString::number(accelerator->getElements().size()),
- QString("Particles: ") + QString::number(accelerator->getParticles().size()),
- QString("") + accelerator->getParticles().front()->toString().c_str()
+ QString("Elements: ") + QString::number(accelerator->getElements().size())
+ //QString("Particles: ") + QString::number(accelerator->getParticles().size()),
+ //QString("") + accelerator->getParticles().front()->toString().c_str()
};
- displayText(text, 11);
+ displayText(text, 9);
//renderText(0,60,QString("") + accelerator->getParticle(0)->getElement()->magneticFieldAt(accelerator->getParticle(0)->getPosition()).toString().c_str());
//renderText(0,72,QString("") + accelerator->getParticle(0)->toString().c_str());
axes();
@@ -127,9 +127,10 @@ void Stage::paintGL() {
glColor3d(0, 0, 1);
- Accelerator::ParticleCollection particles = accelerator->getParticles();
- for (Accelerator::ParticleCollection::const_iterator i = particles.begin(); i != particles.end(); ++i) {
- particleRenderer.render(**i);
+ const Accelerator::BeamCollection& beams = accelerator->getBeams();
+
+ for (Accelerator::BeamCollection::const_iterator i = beams.begin(); i != beams.end(); ++i) {
+ beamRenderer.render(**i);
}
}
@@ -194,8 +195,9 @@ ElementRenderer& Stage::getElementRenderer(){
return elementRenderer;
}
-ParticleRenderer& Stage::getParticleRenderer() {;
- return particleRenderer;
+
+BeamRenderer& Stage::getBeamRenderer() {;
+ return beamRenderer;
}
}
diff --git a/src/gui/Stage.h b/src/gui/Stage.h
index b3afdb9..cb46b7d 100644
--- a/src/gui/Stage.h
+++ b/src/gui/Stage.h
@@ -14,7 +14,7 @@
#include "Camera.h"
#include "KeyManager.h"
#include "ElementRenderer.h"
-#include "ParticleRenderer.h"
+#include "BeamRenderer.h"
#include "Element.h"
#include "Accelerator.h"
#include "util.h"
@@ -40,7 +40,7 @@ public:
void setRunning(bool value);
ElementRenderer& getElementRenderer();
- ParticleRenderer& getParticleRenderer();
+ BeamRenderer& getBeamRenderer();
//TODO !!! temporary
@@ -67,7 +67,7 @@ private:
//graphics
Camera camera;
ElementRenderer elementRenderer;
- ParticleRenderer particleRenderer;
+ BeamRenderer beamRenderer;
QPoint center;
util::DisplayMode displayMode;
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 03b954b..a0c883d 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -15,5 +15,5 @@ QT += opengl
# Input
-HEADERS += Camera.h ElementRenderer.h util.h KeyManager.h Stage.h ParticleRenderer.h Renderer.h
-SOURCES += Camera.cc ElementRenderer.cc util.cc KeyManager.cc Stage.cc ParticleRenderer.cc Main.cc
+HEADERS += Camera.h ElementRenderer.h util.h KeyManager.h Stage.h BeamRenderer.h Renderer.h
+SOURCES += Camera.cc ElementRenderer.cc util.cc KeyManager.cc Stage.cc BeamRenderer.cc Main.cc
diff --git a/src/main/Accelerator.cc b/src/main/Accelerator.cc
index 165d607..df0aa19 100644
--- a/src/main/Accelerator.cc
+++ b/src/main/Accelerator.cc
@@ -15,15 +15,14 @@ using namespace std;
namespace vhc {
-Accelerator::Accelerator():
+Accelerator::Accelerator(): elements(0), beams(0), allowLinear(false), closed(false), interactor(new BruteForceInteractor) {};
+
+Accelerator::Accelerator(Interactor* interactor):
elements(0),
beams(0),
allowLinear(false),
closed(false),
- interactor(NULL)
- {
- interactor = new BruteForceInteractor;
- };
+ interactor(interactor) {}
Accelerator::~Accelerator() {
clear();
@@ -105,13 +104,12 @@ const Accelerator::BeamCollection& Accelerator::getBeams() const {
return beams;
}
-//TODO the segmentation fault came from here! find a solution
-const Accelerator::ParticleCollection& Accelerator::getParticles() const {
- ParticleCollection* particles = new ParticleCollection(0);
+auto_ptr<Accelerator::ParticleCollection> Accelerator::getParticles() const {
+ auto_ptr<ParticleCollection> particles(new ParticleCollection(0));
for (BeamCollection::const_iterator i = beams.begin(); i != beams.end(); ++i) {
particles->insert(particles->end(), (**i).getParticles().begin(), (**i).getParticles().end());
}
- return *particles;
+ return particles;
}
void Accelerator::close() {
@@ -136,6 +134,7 @@ void Accelerator::close() {
}
initializeBeams();
+ interactor->acceleratorClosed(*this);
closed = true;
@@ -187,17 +186,17 @@ std::string Accelerator::toString() const {
}
}
- const ParticleCollection& particles = getParticles();
+ auto_ptr<ParticleCollection> particles = getParticles();
- if (particles.size() == 0) {
+ if (particles->size() == 0) {
s << "This accelerator doesn't contain any particle." << "\n";
- } else if (particles.size() == 1) {
+ } else if (particles->size() == 1) {
s << "This accelerator contains the following particle :" << "\n";
- s << particles.front()->toString() << "\n";
+ s << particles->front()->toString() << "\n";
}else{
- s << "This accelerator contains the " << particles.size() << " following particles :"<<"\n";
- for (ParticleCollection::const_iterator i = particles.begin(); i != particles.end(); ++i) {
- s << (*i)->toString() << "\n";
+ s << "This accelerator contains the " << particles->size() << " following particles :"<<"\n";
+ for (ParticleCollection::const_iterator i = particles->begin(); i != particles->end(); ++i) {
+ s << (**i).toString() << "\n";
}
}
diff --git a/src/main/Accelerator.h b/src/main/Accelerator.h
index 32889ff..dcf43ac 100644
--- a/src/main/Accelerator.h
+++ b/src/main/Accelerator.h
@@ -8,6 +8,7 @@
#ifndef ACCELERATOR_H_
#define ACCELERATOR_H_
#include <list>
+#include <memory>
#include "Vector3D.h"
#include "Particle.h"
#include "Beam.h"
@@ -29,9 +30,12 @@ public:
typedef ParticleCollection::iterator ParticleIterator;
typedef ElementCollection::iterator ElementIterator;
- /** Cree un nouveau accelerateur vide. */
+ /** Cree un nouveau accelerateur vide, avec un interacteur de particules a force brute. */
Accelerator ();
+ /** Cree un nouveau accelerateur vide.*/
+ Accelerator (Interactor* interactor);
+
virtual ~Accelerator();
/** Copie un élément dans l'accélérateur.
@@ -52,7 +56,7 @@ public:
/** Retourne la liste des particules contenus dans cet accelerateur.
* <b>ATTENTION:</b> les particules peuvent etre supprimes sans preavis par l'accelerateur! */
- const ParticleCollection & getParticles() const;
+ std::auto_ptr<ParticleCollection> getParticles() const;
/** Retourne tous les faisceaux de cet accelerateur. */
const BeamCollection& getBeams() const;
diff --git a/src/main/Beam.cc b/src/main/Beam.cc
index 3650bd9..5999e95 100644
--- a/src/main/Beam.cc
+++ b/src/main/Beam.cc
@@ -67,6 +67,8 @@ Particle& Beam::getReferenceParticle() {
Beam::ParticleCollection& Beam::getParticles() {return particles;}
+const Beam::ParticleCollection& Beam::getParticles() const {return particles;}
+
void Beam::updateParticles() {
for (ParticleCollection::iterator i = particles.begin(); i != particles.end(); ++i) {
Particle& particle = **i;
diff --git a/src/main/Beam.h b/src/main/Beam.h
index 1e71b15..4700b5c 100644
--- a/src/main/Beam.h
+++ b/src/main/Beam.h
@@ -35,6 +35,8 @@ public:
/** Retourne tous les particules contenus dans ce faisceau. */
ParticleCollection& getParticles();
+ const ParticleCollection& getParticles() const;
+
/** Met a jour les particules en leur attribuant l'element dans lequel ils sont contenus.
* Contrairement a <code>Accelerator::initializeBeams()</code>, les elements consideres sont:
* - l'element actuel de la particule
diff --git a/src/main/BruteForceInteractor.cc b/src/main/BruteForceInteractor.cc
index 7ad8374..6e19bd8 100644
--- a/src/main/BruteForceInteractor.cc
+++ b/src/main/BruteForceInteractor.cc
@@ -30,7 +30,6 @@ void BruteForceInteractor::applyInteractions() {
}
}
}
-void BruteForceInteractor::acceleratorClosed() {}
void BruteForceInteractor::react(const ParticleAddedEvent& event) {
particles.push_back(event.getParticle());
diff --git a/src/main/BruteForceInteractor.h b/src/main/BruteForceInteractor.h
index ba1688a..796d7db 100644
--- a/src/main/BruteForceInteractor.h
+++ b/src/main/BruteForceInteractor.h
@@ -28,7 +28,6 @@ public:
virtual ~BruteForceInteractor();
virtual void applyInteractions();
- virtual void acceleratorClosed();
/** Appelee lors de l'ajout d'une particule. Ajoute la particule au particules simules par cet interacteur. */
virtual void react(const ParticleAddedEvent& event);
diff --git a/src/main/Color.cc b/src/main/Color.cc
index 8564bb8..c45fb83 100644
--- a/src/main/Color.cc
+++ b/src/main/Color.cc
@@ -12,17 +12,17 @@ using namespace std;
namespace vhc {
//TODO comment importer le tableau statique depuis le header?
-double Color::red[4] = {1,0,0,1};
-double Color::green[4] = {0,1,0,1};
-double Color::blue[4] = {0,0,1,1};
-double Color::turquoise[4] = {0,1,1,1};
-double Color::purple[4] = {1,0,1,1};
-double Color::yellow[4] = {1,1,0,1};
-double Color::white[4] = {1,1,1,1};
-double Color::black[4] = {0,0,0,1};
-double Color::grey[4] = {0.6,0.6,0.6,1};
+const double Color::red[] = {1,0,0,1};
+const double Color::green[] = {0,1,0,1};
+const double Color::blue[] = {0,0,1,1};
+const double Color::turquoise[] = {0,1,1,1};
+const double Color::purple[] = {1,0,1,1};
+const double Color::yellow[] = {1,1,0,1};
+const double Color::white[] = {1,1,1,1};
+const double Color::black[] = {0,0,0,1};
+const double Color::grey[] = {0.6,0.6,0.6,1};
-vector<double> Color::convertTabToVector(double const& tab[4]) {
+vector<double> Color::convertTabToVector(const double tab[]) {
vector <double> tmp;
for (unsigned int i(0); i < 4; ++i) {
tmp.push_back(tab[i]);
@@ -34,35 +34,35 @@ void Color::setColor(vector<double> const& co){
color = co;
}
-void Color::setColor(string co) const {
+void Color::setColor(string co) {
switch(co){
case "red" :
- color = convertTabToVector(red[4]);
+ color = convertTabToVector(red);
break;
case "green" :
- color = convertTabToVector(green[4]);
+ color = convertTabToVector(green);
break;
case "blue" :
- color = convertTabToVector(blue[4]);
+ color = convertTabToVector(blue);
break;
case "turquoise" :
- color = convertTabToVector(turquoise[4]);
+ color = convertTabToVector(turquoise);
break;
case "purple" :
- color = convertTabToVector(purple[4]);
+ color = convertTabToVector(purple);
break;
case "yellow" :
- color = convertTabToVector(yellow[4]);
+ color = convertTabToVector(yellow);
break;
case "white" :
- color = convertTabToVector(white[4]);
+ color = convertTabToVector(white);
break;
case "black" :
- color = convertTabToVector(black[4]);
+ color = convertTabToVector(black);
break;
case "grey" :
- color = convertTabToVector(grey[4]);
+ color = convertTabToVector(grey);
break;
default:
throw IllegalArgumentException("Color is not defined.");
@@ -73,44 +73,4 @@ vector<double> Color::getColor() const {
return color;
}
-string Color::getStringColor() const {
-
- string tmp;
-
- switch(color){
- case convertTabToVector(red) :
- tmp="red";
- break;
- case convertTabToVector(green) :
- tmp="green";
- break;
- case convertTabToVector(blue) :
- tmp="blue";
- break;
- case convertTabToVector(turquoise) :
- break;
- tmp="turquoise";
- case convertTabToVector(purple) :
- tmp="purple";
- break;
- case convertTabToVector(yellow) :
- tmp="yellow";
- break;
- case convertTabToVector(white) :
- tmp="white";
- break;
- case convertTabToVector(black) :
- tmp="black";
- break;
- case convertTabToVector(grey) :
- tmp="grey";
- break;
- default :
- tmp="No valid color.";
- break;
- }
-
- return tmp;
-}
-
}
diff --git a/src/main/Color.h b/src/main/Color.h
index c952071..1e0e962 100644
--- a/src/main/Color.h
+++ b/src/main/Color.h
@@ -28,8 +28,6 @@ public:
/** Retourne (sous forme de vector<double>) la couleur de cet objet. **/
vector<double> getColor() const;
- /** Retourne (sous forme de string) la couleur de cet objet. **/
- string getStringColor() const;
/** Affecte la couleur de l'objet selon l'argument de la fonction.(Ici un string) **/
void setColor(string color = "white");
@@ -41,16 +39,16 @@ public:
protected:
vector<double> color;
private:
- vector<double> convertTabToVector(double const& tab[4]);
- static double red[4];
- static double green[4];
- static double blue[4];
- static double turquoise[4];
- static double purple[4];
- static double yellow[4];
- static double white[4];
- static double black[4];
- static double grey[4];
+ vector<double> convertTabToVector(double tab[]);
+ static const double red[4];
+ static const double green[4];
+ static const double blue[4];
+ static const double turquoise[4];
+ static const double purple[4];
+ static const double yellow[4];
+ static const double white[4];
+ static const double black[4];
+ static const double grey[4];
};
}
diff --git a/src/main/Interactor.cc b/src/main/Interactor.cc
index 9808b69..2891582 100644
--- a/src/main/Interactor.cc
+++ b/src/main/Interactor.cc
@@ -6,6 +6,7 @@
*/
#include "Interactor.h"
+#include "Accelerator.h"
namespace vhc {
@@ -13,4 +14,7 @@ Interactor::Interactor() {}
Interactor::~Interactor() {}
+//rien par defaut
+void Interactor::acceleratorClosed(const Accelerator& acc) {}
+
}
diff --git a/src/main/Interactor.h b/src/main/Interactor.h
index 59170c9..828dd03 100644
--- a/src/main/Interactor.h
+++ b/src/main/Interactor.h
@@ -12,6 +12,8 @@
namespace vhc {
+class Accelerator;
+
/** Classe de base representant un moyen d'inclure les forces inter-particules dans la simulation.
* D'abord on souscrit un interacteur a une source d'evenements de paticules (typiquement des faisceaux).
* Lors de l'ajout d'une particule, l'interacteur a donc la possibilite d'inclure la particule dans
@@ -28,7 +30,7 @@ public:
virtual void applyInteractions() = 0;
/** Appelee quand l'accelerateur contenant cet interacteur est ferme. */
- virtual void acceleratorClosed() = 0;
+ virtual void acceleratorClosed(const Accelerator& acc);
/** Appelee lors de l'ajout d'une particule. Ajoute typiquement la particule au particules simules par cet interacteur. */
virtual void react(const ParticleAddedEvent& event) = 0;
diff --git a/src/main/Makefile b/src/main/Makefile
index 0ba6a5e..680a0fe 100644
--- a/src/main/Makefile
+++ b/src/main/Makefile
@@ -16,7 +16,7 @@ LOCALDIR = main
LOCALOBJS = Vector3D.o Particle.o Printable.o Element.o CurvedElement.o StraightElement.o \
CompositeElement.o Dipole.o Quadrupole.o FODO.o ElementVisitor.o Cloneable.o \
Accelerator.o exceptions.o Beam.o SingleBeam.o CircularBeam.o \
- random.o Bunch.o events.o Interactor.o BruteForceInteractor.o Parser.o
+ random.o Bunch.o events.o Interactor.o BruteForceInteractor.o SAPInteractor.o
OBJS=$(addprefix $(BINDIR)/$(LOCALDIR)/,$(LOCALOBJS))
.PHONY = all checkdirs lib
diff --git a/src/main/SAP.cc b/src/main/SAP.cc
deleted file mode 100644
index 820ad47..0000000
--- a/src/main/SAP.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SAP.cc
- *
- * Created on: May 24, 2011
- * Author: jakob
- */
-
-#include "SAP.h"
-
-namespace vhc {
-
-SAP::SAP() {
- // TODO Auto-generated constructor stub
-
-}
-
-SAP::~SAP() {
- // TODO Auto-generated destructor stub
-}
-
-}
diff --git a/src/main/SAP.h b/src/main/SAP.h
deleted file mode 100644
index 8b0c1aa..0000000
--- a/src/main/SAP.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SAP.h
- *
- * Created on: May 24, 2011
- * Author: jakob
- */
-
-#ifndef SAP_H_
-#define SAP_H_
-
-#include <vector>
-#include "InteractionDetector.h"
-#include "Particle.h"
-#include "Element.h"
-
-namespace vhc {
-
-class SAP {
-
-private:
- vector<Particle*> particles;
- element->localpos
- particle->localpos
-
-public:
-
- //static const double THRESHOLD_RADIUS;
-
- SAP();
- virtual ~SAP();
-
- virtual void applyInteractions();
- virtual void acceleratorClosed();
-
- virtual void react(const ParticleAddedEvent& event) = 0;
- virtual void react(const ParticleRemovedEvent& event) = 0;
-};
-
-}
-
-#endif /* SAP_H_ */
diff --git a/src/main/SAPInteractor.cc b/src/main/SAPInteractor.cc
new file mode 100644
index 0000000..203dfa0
--- /dev/null
+++ b/src/main/SAPInteractor.cc
@@ -0,0 +1,130 @@
+/*
+ * SAPInteractor.cc
+ *
+ * Created on: May 29, 2011
+ * Author: jakob
+ */
+
+#include <iostream>
+#include <algorithm>
+#include <math.h>
+#include "SAPInteractor.h"
+#include "Accelerator.h"
+#include "Vector3D.h"
+
+using namespace std;
+
+namespace vhc {
+
+SAPInteractor::LinearParticleContainer::LinearParticleContainer(Particle *const particle, double linear): particle(particle), linear(linear) {};
+
+Particle *const SAPInteractor::LinearParticleContainer::getParticle() const {return particle;}
+
+void SAPInteractor::LinearParticleContainer::setLinear(double value) {linear = value;}
+
+double SAPInteractor::LinearParticleContainer::getLinear() const {return linear;}
+
+SAPInteractor::SAPInteractor() {}
+
+SAPInteractor::~SAPInteractor() {}
+
+const double SAPInteractor::DEFAULT_INTERACTION_RADIUS = 3E-6;
+
+double SAPInteractor::getInteractionRadius() const {return interactionRadius;}
+
+void SAPInteractor::setInteractionRadius(double value) {interactionRadius = value;}
+
+void SAPInteractor::acceleratorClosed(const Accelerator& acc) {
+ //compteur de position lineaire
+ double linear = 0;
+
+ //elements
+ const Accelerator::ElementCollection& elements = acc.getElements();
+
+ //linearistaion des elements
+ for (Accelerator::ElementCollection::const_iterator i = elements.begin(); i != elements.end(); ++i) {
+ elementLinears.insert(pair<Element*, double>(*i, linear));
+ linear += (**i).getDiagonal().norm();
+ }
+}
+
+
+void SAPInteractor::react(const ParticleAddedEvent& event) {
+ particles.push_back(new LinearParticleContainer(event.getParticle()));
+}
+
+void SAPInteractor::react(const ParticleRemovedEvent& event) {
+ for (int i = 0; i < particles.size(); ++i) {
+ if (particles[i]->getParticle() == event.getParticle()) {
+ LinearParticleContainer* p = particles[i];
+ particles[i] = particles.back();
+ particles[particles.size() - 1] = p;
+ delete particles.back();
+ particles.pop_back();
+ break;
+ }
+ }
+}
+
+void SAPInteractor::applyInteractions() {
+
+ if (particles.size() == 0) return;
+
+ //les particules sont linearises
+ linearizeParticles();
+
+ //les particules sont tries selon leur position lineaire [complexite O(N log N)]
+ sort(particles.begin(), particles.end(), vhc::SAPInteractor::compare);
+
+ for (int i = 0; i < particles.size(); ++i) {
+ for (int j = i + i; j < particles.size(); ++j) {
+
+ //comme les particules sont tries selon leur projection, si la deuxieme est plus loin de la premiere,
+ //on sait que tous les autres le seront aussi, on arrete donc la recherche ici
+ if (particles[j]->getLinear() + interactionRadius > particles[i]->getLinear() - interactionRadius) break;
+
+ //sinon, si leur distance est plus petite que le rayon d'interaction, on applique un force d'interaction
+ else if (fabs(particles[j]->getLinear() - particles[i]->getLinear()) <= interactionRadius) {
+ Particle& p1 = *(particles[i]->getParticle());
+ Particle& p2 = *(particles[j]->getParticle());
+
+ double r = (p2.getPosition() - p1.getPosition()).norm();
+ if (r != 0) {
+ Vector3D d = (p2.getPosition() - p1.getPosition()).unit();
+ Vector3D force = d * p1.getCharge() * p1.getCharge() /
+ (4 * M_PI * constants::EPSILON_ZERO * r * r * r * p1.getGamma() * p1.getGamma());
+ p1.applyForce(force);
+ p2.applyForce(-force);
+ }
+ }
+ }
+ }
+
+}
+
+void SAPInteractor::linearizeParticles() {
+ for (vector<LinearParticleContainer*>::iterator i = particles.begin(); i != particles.end(); ++i) {
+
+ //element de la particule
+ Element* element = (**i).getParticle()->getElement();
+
+ LinearParticleContainer* p = (*i);
+
+ //position locale de la particule a l'entree de son element
+ Vector3D local = (**i).getParticle()->getPosition() - element->getEntryPosition();
+
+ //projection de la particule sur la diagonale de l'element
+ double proj = (element->getDiagonal().unit()).dot(local);
+
+ //la position lineaire de l'element est donne par la projection locale plus la position lineaire de son element
+ (**i).setLinear(elementLinears.find(element)->second + proj);
+
+
+ }
+}
+
+bool SAPInteractor::compare(LinearParticleContainer *const p1, LinearParticleContainer *const p2) {
+ return p1->getLinear() < p2->getLinear();
+}
+
+}
diff --git a/src/main/SAPInteractor.h b/src/main/SAPInteractor.h
new file mode 100644
index 0000000..b85e2a9
--- /dev/null
+++ b/src/main/SAPInteractor.h
@@ -0,0 +1,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_ */
diff --git a/src/test/AcceleratorBenchmarkTest.cc b/src/test/AcceleratorBenchmarkTest.cc
index 520d3fe..be898b9 100644
--- a/src/test/AcceleratorBenchmarkTest.cc
+++ b/src/test/AcceleratorBenchmarkTest.cc
@@ -81,10 +81,7 @@ int main() {
int steps = 1000;
double dt = 1E-11;
- cout << "Simulating " << steps << " steps with " << accelerator->getParticles().size() << " particles in " << accelerator->getBeams().size() << " beams...";
- for (Accelerator::BeamCollection::const_iterator i = accelerator->getBeams().begin(); i != accelerator->getBeams().end(); ++i) {
- cout << (**i).getParticles().size();
- }
+ cout << "Simulating " << steps << " steps with " << accelerator->getParticles()->size() << " particles in " << accelerator->getBeams().size() << " beams...";
cout.flush();
int t0 = clock();
for (int i = 0; i < steps; ++i) {
@@ -95,7 +92,7 @@ int main() {
cout << "Time taken: " << t1 << " ticks @ " << CLOCKS_PER_SEC << " ticks/s ~ " << 1.0 * t1 / CLOCKS_PER_SEC << "s" << endl;
cout << "Average: " << 1.0 * t1 / CLOCKS_PER_SEC / steps << " s/step" << endl;
- cout << "Average: " << 1.0 * t1 / CLOCKS_PER_SEC / steps / accelerator->getParticles().size() << " s/step/particle" << endl;
+ cout << "Average: " << 1.0 * t1 / CLOCKS_PER_SEC / steps / accelerator->getParticles()->size() << " s/step/particle" << endl;
return 0;
}
diff --git a/src/test/ElementsSimulationTest.cc b/src/test/ElementsSimulationTest.cc
index 2406171..3ef0460 100644
--- a/src/test/ElementsSimulationTest.cc
+++ b/src/test/ElementsSimulationTest.cc
@@ -72,8 +72,8 @@ int main() {
//test de simulation
for(unsigned int j(0); j<it; ++j){
va[i]->step(10E-11);
- if(!(va[i]->getParticles().empty())){
- cout<<"after "<<j+1<<" step :"<<endl << (va[i]->getParticles().front()->toString())<<endl;
+ if(!(va[i]->getParticles()->empty())){
+ cout<<"after "<<j+1<<" step :"<<endl << (va[i]->getParticles()->front()->toString())<<endl;
}
}
diff --git a/src/test/P10ExerciceTest.cc b/src/test/P10ExerciceTest.cc
deleted file mode 100644
index dd54f6d..0000000
--- a/src/test/P10ExerciceTest.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * exerciceP10.cc
- *
- * Created on: 20 avr. 2011
- * Author: christian
- */
-#include "Accelerator.h"
-#include "Dipole.h"
-#include "StraightElement.h"
-#include "Quadrupole.h"
-#include "FODO.h"
-#include "exceptions.h"
-#include <iostream>
-#include <string>
-#include <vector>
-
-using namespace std;
-using namespace vhc;
-
-//TODO erreur sur l'affichage de p1 ===> "NAN" <========
-/** Affiche la réponse de l'exercice P.10 de l'étape 5 (semaine 6) du projet.*/
-int main() {
-
- Accelerator a;
-
- Dipole* d = new Dipole(
- Vector3D(1,0,0),
- Vector3D(0,-1,0),
- 0.1,
- 1,
- Vector3D(0,0,7),
- NULL);
-
- StraightElement* s = new StraightElement(
- Vector3D(0,-1,0),
- Vector3D(-1,-1,0),
- 0.1);
-
- Quadrupole* q = new Quadrupole(
- Vector3D(-1,-1,0),
- Vector3D(-1,-2,0),
- 0.1,
- 1.2);
-
- FODO* f = new FODO(
- Vector3D(-1,-2,0),
- Vector3D(-1,0,0),
- 0.1,
- 1,
- 1.2);
-
- Particle* p1 = new Particle(
- Vector3D( 1.00984,-0.191837,0 ),
- 0.938272,
- 1.60217653e-19,
- 2,
- Vector3D(-210200,-2.64754e+08,0));
-
- Particle* p2 = new Particle(
- Vector3D(0.99016,-0.191837,0),
- 0.938272,
- 1.60217653e-19,
- 2,
- Vector3D(210200,-2.64754e+08,0));
-
- a.add(*d);
- a.add(*s);
- a.add(*q);
- a.add(*f);
- a.add(*p1);
- a.add(*p2);
-
- a.enableLinear(true);
- a.close();
-
- cout << a << endl;
- a.clear();
-
-
- return 0;
-}
diff --git a/src/test/exerciceP11Test.cc b/src/test/exerciceP11Test.cc
index fcb7bb5..04af329 100644
--- a/src/test/exerciceP11Test.cc
+++ b/src/test/exerciceP11Test.cc
@@ -105,8 +105,8 @@ void makeTest(){
for(unsigned int j(0); j<it; ++j){
a->step(10E-11);
- cout<<"after "<<j+1<<" step :"<<endl<<"part 1 :"<< (a->getParticles().front()->toString()) <<endl;
- cout<<"after "<<j+1<<" step :"<<endl<<"part 2 :"<< (a->getParticles().back()->toString()) <<endl;
+ cout<<"after "<<j+1<<" step :"<<endl<<"part 1 :"<< (a->getParticles()->front()->toString()) <<endl;
+ cout<<"after "<<j+1<<" step :"<<endl<<"part 2 :"<< (a->getParticles()->back()->toString()) <<endl;
}
}