From 00d592af835e892902bdf6cc5db29a64f24ab9d3 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sun, 29 May 2011 20:09:19 +0000 Subject: *Ajoute interactions avancees *Ecrit conception *Commentaires --- Makefile | 2 +- src/gui/BeamRenderer.cc | 54 +++++++++++++++ src/gui/BeamRenderer.h | 37 ++++++++++ src/gui/EnergyBeamRenderer.cc | 23 +++++++ src/gui/EnergyBeamRenderer.h | 25 +++++++ src/gui/KeyManager.cc | 2 +- src/gui/Main.cc | 7 +- src/gui/Renderer.h | 12 +--- src/gui/Stage.cc | 22 +++--- src/gui/Stage.h | 6 +- src/gui/gui.pro | 4 +- src/main/Accelerator.cc | 31 ++++----- src/main/Accelerator.h | 8 ++- src/main/Beam.cc | 2 + src/main/Beam.h | 2 + src/main/BruteForceInteractor.cc | 1 - src/main/BruteForceInteractor.h | 1 - src/main/Color.cc | 80 ++++++--------------- src/main/Color.h | 22 +++--- src/main/Interactor.cc | 4 ++ src/main/Interactor.h | 4 +- src/main/Makefile | 2 +- src/main/SAP.cc | 21 ------ src/main/SAP.h | 41 ----------- src/main/SAPInteractor.cc | 130 +++++++++++++++++++++++++++++++++++ src/main/SAPInteractor.h | 93 +++++++++++++++++++++++++ src/test/AcceleratorBenchmarkTest.cc | 7 +- src/test/ElementsSimulationTest.cc | 4 +- src/test/P10ExerciceTest.cc | 81 ---------------------- src/test/exerciceP11Test.cc | 4 +- 30 files changed, 456 insertions(+), 276 deletions(-) create mode 100644 src/gui/BeamRenderer.cc create mode 100644 src/gui/BeamRenderer.h create mode 100644 src/gui/EnergyBeamRenderer.cc create mode 100644 src/gui/EnergyBeamRenderer.h delete mode 100644 src/main/SAP.cc delete mode 100644 src/main/SAP.h create mode 100644 src/main/SAPInteractor.cc create mode 100644 src/main/SAPInteractor.h delete mode 100644 src/test/P10ExerciceTest.cc 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 +#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 { +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::subscribe(foo); - bch.Publisher::subscribe(foo); + //bch.Publisher::subscribe(foo); + //bch.Publisher::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 +/** 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 render. - * Cette methode gere des glBegin() en arriere-plan. */ - //virtual void begin() = 0; - /** Dessine un objet. */ virtual void render(const T& item) const = 0; - //template - //virtual void render(std::forward_iterator) const; - - /** Methode qui doit etre appelee avant de dessiner une collection d'objets par render. - * Cette methode gere des glBegin() 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::getParticles() const { + auto_ptr 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 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 +#include #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. * ATTENTION: les particules peuvent etre supprimes sans preavis par l'accelerateur! */ - const ParticleCollection & getParticles() const; + std::auto_ptr 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 Accelerator::initializeBeams(), 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 Color::convertTabToVector(double const& tab[4]) { +vector Color::convertTabToVector(const double tab[]) { vector tmp; for (unsigned int i(0); i < 4; ++i) { tmp.push_back(tab[i]); @@ -34,35 +34,35 @@ void Color::setColor(vector 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 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) la couleur de cet objet. **/ vector 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 color; private: - vector 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 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 -#include "InteractionDetector.h" -#include "Particle.h" -#include "Element.h" - -namespace vhc { - -class SAP { - -private: - vector 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 +#include +#include +#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(*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::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 +#include +#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: + *
    + *
  1. Projetter les particules le long de l'accelerateur.
  2. + *
  3. Trier les particules en fonction de leur position lineaire, obtenue au point precedent.
  4. + *
  5. 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.
  6. + *
+ * 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 particles; + + /** Dictionnaire associant un element a sa position lineaire. */ + std::map 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); jstep(10E-11); - if(!(va[i]->getParticles().empty())){ - cout<<"after "<getParticles().front()->toString())<getParticles()->empty())){ + cout<<"after "<getParticles()->front()->toString())< -#include -#include - -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); jstep(10E-11); - cout<<"after "<getParticles().front()->toString()) <getParticles().back()->toString()) <getParticles()->front()->toString()) <getParticles()->back()->toString()) <