source: src/World.cpp@ 43f2278

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 43f2278 was 65d7ca, checked in by Michael Ankele <ankele@…>, 13 years ago

Fix: World::registerAtom() did not notify observers

  • Property mode set to 100644
File size: 22.3 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[bcf653]5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
[5d1611]8/*
9 * World.cpp
10 *
11 * Created on: Feb 3, 2010
12 * Author: crueger
13 */
14
[bf3817]15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[ad011c]20#include "CodePatterns/MemDebug.hpp"
[112b09]21
[5d1611]22#include "World.hpp"
23
[90c4280]24#include <functional>
[5d1611]25
[3139b2]26#include "Actions/ActionTrait.hpp"
[d297a3]27#include "Actions/ManipulateAtomsProcess.hpp"
[6f0841]28#include "Atom/atom.hpp"
[5dfabd]29#include "Atom/AtomObserver.hpp"
[d297a3]30#include "Box.hpp"
31#include "CodePatterns/Assert.hpp"
[8e1f7af]32#include "config.hpp"
[fc1b24]33#include "Descriptors/AtomDescriptor.hpp"
[865a945]34#include "Descriptors/AtomDescriptor_impl.hpp"
[ebc499]35#include "Descriptors/AtomSelectionDescriptor.hpp"
[1c51c8]36#include "Descriptors/MoleculeDescriptor.hpp"
37#include "Descriptors/MoleculeDescriptor_impl.hpp"
[ebc499]38#include "Descriptors/MoleculeSelectionDescriptor.hpp"
[6e97e5]39#include "Descriptors/SelectiveIterator_impl.hpp"
[42127c]40#include "Element/periodentafel.hpp"
[3139b2]41#include "Graph/BondGraph.hpp"
[4b8630]42#include "Graph/DepthFirstSearchAnalysis.hpp"
[e4fe8d]43#include "Helpers/defs.hpp"
[d297a3]44#include "LinearAlgebra/RealSpaceMatrix.hpp"
[4834f4]45#include "LinkedCell/LinkedCell_Controller.hpp"
46#include "LinkedCell/PointCloudAdaptor.hpp"
[d297a3]47#include "molecule.hpp"
[42127c]48#include "MoleculeListClass.hpp"
[ab26c3]49#include "Thermostats/ThermoStatContainer.hpp"
[d297a3]50#include "WorldTime.hpp"
[d346b6]51
[3e4fb6]52#include "IdPool_impl.hpp"
53
[4834f4]54#include "CodePatterns/IteratorAdaptors.hpp"
[ad011c]55#include "CodePatterns/Singleton_impl.hpp"
[02ce36]56#include "CodePatterns/Observer/Channels.hpp"
57#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
[23b547]58
[ce7fdc]59using namespace MoleCuilder;
[4d9c01]60
[7188b1]61/******************************* Notifications ************************/
62
63
64atom* World::_lastchangedatom = NULL;
65molecule* World::_lastchangedmol = NULL;
66
[5d1611]67/******************************* getter and setter ************************/
[f71baf]68periodentafel *&World::getPeriode()
69{
[5d1611]70 return periode;
71}
72
[f71baf]73BondGraph *&World::getBondGraph()
74{
75 return BG;
76}
77
78void World::setBondGraph(BondGraph *_BG){
79 delete (BG);
80 BG = _BG;
81}
82
[8e1f7af]83config *&World::getConfig(){
84 return configuration;
85}
86
[1c51c8]87// Atoms
88
[7a1ce5]89atom* World::getAtom(AtomDescriptor descriptor){
[fc1b24]90 return descriptor.find();
91}
92
[4d72e4]93World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
[fc1b24]94 return descriptor.findAll();
95}
96
[4d72e4]97World::AtomComposite World::getAllAtoms(){
[0e2a47]98 return getAllAtoms(AllAtoms());
99}
100
[354859]101int World::numAtoms(){
102 return atoms.size();
103}
104
[1c51c8]105// Molecules
106
107molecule *World::getMolecule(MoleculeDescriptor descriptor){
108 return descriptor.find();
109}
110
111std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
112 return descriptor.findAll();
113}
114
[97ebf8]115std::vector<molecule*> World::getAllMolecules(){
116 return getAllMolecules(AllMolecules());
117}
118
[354859]119int World::numMolecules(){
120 return molecules_deprecated->ListOfMolecules.size();
121}
122
[5f612ee]123// system
124
[84c494]125Box& World::getDomain() {
126 return *cell_size;
127}
128
[cca9ef]129void World::setDomain(const RealSpaceMatrix &mat){
[be97a8]130 OBSERVE;
[84c494]131 *cell_size = mat;
[5f612ee]132}
133
134void World::setDomain(double * matrix)
135{
[b9c847]136 OBSERVE;
[cca9ef]137 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
[84c494]138 cell_size->setM(M);
[5f612ee]139}
140
[4834f4]141LinkedCell::LinkedCell_View World::getLinkedCell(const double distance)
142{
143 // we have to grope past the ObservedContainer mechanism and transmorph the map
144 // into a traversable list for the adaptor
145 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
146 &(atoms.getContent()),
147 std::string("WorldsAtoms"));
148 return LCcontroller->getView(distance, atomset);
149}
150
[d297a3]151void World::setTime(const unsigned int _step)
152{
[76163d]153 if (_step != WorldTime::getTime()) {
154 // set new time
[040a5c]155 WorldTime::getInstance().setTime(_step);
[4b8630]156 // TODO: removed when BondGraph creates the adjacency
157 // 1. remove all of World's molecules
158 for (MoleculeIterator iter = getMoleculeIter();
159 getMoleculeIter() != moleculeEnd();
160 iter = getMoleculeIter()) {
161 getMolecules()->erase(*iter);
162 destroyMolecule(*iter);
163 }
164 // 2. (re-)create bondgraph
165 AtomComposite Set = getAllAtoms();
166 BG->CreateAdjacency(Set);
167
168 // 3. scan for connected subgraphs => molecules
169 DepthFirstSearchAnalysis DFS;
170 DFS();
171 DFS.UpdateMoleculeStructure();
[76163d]172 }
[d297a3]173}
174
[387b36]175std::string World::getDefaultName() {
[5f612ee]176 return defaultName;
177}
178
[387b36]179void World::setDefaultName(std::string name)
[5f612ee]180{
[be97a8]181 OBSERVE;
[387b36]182 defaultName = name;
[5f612ee]183};
184
[43dad6]185class ThermoStatContainer * World::getThermostats()
186{
187 return Thermostats;
188}
189
190
[e4b5de]191int World::getExitFlag() {
192 return ExitFlag;
193}
194
195void World::setExitFlag(int flag) {
196 if (ExitFlag < flag)
197 ExitFlag = flag;
198}
[5f612ee]199
[afb47f]200/******************** Methods to change World state *********************/
201
[354859]202molecule* World::createMolecule(){
203 OBSERVE;
204 molecule *mol = NULL;
[cbc5fb]205 mol = NewMolecule();
[3e4fb6]206 moleculeId_t id = moleculeIdPool.getNextId();
[127a8e]207 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
208 mol->setId(id);
[244d26]209 // store the molecule by ID
[cbc5fb]210 molecules[mol->getId()] = mol;
[354859]211 mol->signOn(this);
[7188b1]212 _lastchangedmol = mol;
213 NOTIFY(MoleculeInserted);
[354859]214 return mol;
215}
216
[cbc5fb]217void World::destroyMolecule(molecule* mol){
218 OBSERVE;
[fa7989]219 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
[cbc5fb]220 destroyMolecule(mol->getId());
221}
222
223void World::destroyMolecule(moleculeId_t id){
224 molecule *mol = molecules[id];
[6d574a]225 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
[38f991]226 // give notice about immediate removal
227 {
228 OBSERVE;
229 _lastchangedmol = mol;
230 NOTIFY(MoleculeRemoved);
231 }
[cbc5fb]232 DeleteMolecule(mol);
[38f991]233 if (isMoleculeSelected(id))
234 selectedMolecules.erase(id);
[cbc5fb]235 molecules.erase(id);
[3e4fb6]236 moleculeIdPool.releaseId(id);
[cbc5fb]237}
238
[46d958]239atom *World::createAtom(){
240 OBSERVE;
[3e4fb6]241 atomId_t id = atomIdPool.getNextId();
[127a8e]242 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
[88d586]243 atom *res = NewAtom(id);
[46d958]244 res->setWorld(this);
[5dfabd]245 // sign on to global atom change tracker
246 AtomObserver::getInstance().AtomInserted(res);
[244d26]247 // store the atom by ID
[46d958]248 atoms[res->getId()] = res;
[7188b1]249 _lastchangedatom = res;
250 NOTIFY(AtomInserted);
[46d958]251 return res;
252}
253
[5f612ee]254
[46d958]255int World::registerAtom(atom *atom){
256 OBSERVE;
[3e4fb6]257 atomId_t id = atomIdPool.getNextId();
[88d586]258 atom->setId(id);
[46d958]259 atom->setWorld(this);
260 atoms[atom->getId()] = atom;
[65d7ca]261 _lastchangedatom = atom;
262 NOTIFY(AtomInserted);
[46d958]263 return atom->getId();
264}
265
266void World::destroyAtom(atom* atom){
267 int id = atom->getId();
268 destroyAtom(id);
269}
270
[cbc5fb]271void World::destroyAtom(atomId_t id) {
[46d958]272 atom *atom = atoms[id];
[6d574a]273 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[ab4a33]274 // give notice about immediate removal
275 {
276 OBSERVE;
277 _lastchangedatom = atom;
278 NOTIFY(AtomRemoved);
279 }
[46d958]280 DeleteAtom(atom);
[38f991]281 if (isAtomSelected(id))
282 selectedAtoms.erase(id);
[46d958]283 atoms.erase(id);
[3e4fb6]284 atomIdPool.releaseId(id);
[88d586]285}
286
287bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
288 OBSERVE;
289 // in case this call did not originate from inside the atom, we redirect it,
290 // to also let it know that it has changed
291 if(!target){
292 target = atoms[oldId];
[6d574a]293 ASSERT(target,"Atom with that ID not found");
[88d586]294 return target->changeId(newId);
295 }
296 else{
[3e4fb6]297 if(atomIdPool.reserveId(newId)){
[88d586]298 atoms.erase(oldId);
299 atoms.insert(pair<atomId_t,atom*>(newId,target));
300 return true;
301 }
302 else{
303 return false;
304 }
305 }
[46d958]306}
307
[a7a087]308bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
309 OBSERVE;
310 // in case this call did not originate from inside the atom, we redirect it,
311 // to also let it know that it has changed
312 if(!target){
313 target = molecules[oldId];
314 ASSERT(target,"Molecule with that ID not found");
315 return target->changeId(newId);
316 }
317 else{
[3e4fb6]318 if(moleculeIdPool.reserveId(newId)){
[a7a087]319 molecules.erase(oldId);
320 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
321 return true;
322 }
323 else{
324 return false;
325 }
326 }
327}
328
[7c4e29]329ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[3139b2]330 ActionTrait manipulateTrait(name);
[e4afb4]331 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
[7c4e29]332}
333
[0e2a47]334ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
335 return manipulateAtoms(op,name,AllAtoms());
336}
337
[afb47f]338/********************* Internal Change methods for double Callback and Observer mechanism ********/
339
340void World::doManipulate(ManipulateAtomsProcess *proc){
341 proc->signOn(this);
342 {
343 OBSERVE;
344 proc->doManipulate(this);
345 }
346 proc->signOff(this);
347}
[865a945]348/******************************* Iterators ********************************/
349
[fa0b18]350// external parts with observers
351
[6e97e5]352CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
353
[fa0b18]354World::AtomIterator
355World::getAtomIter(AtomDescriptor descr){
356 return AtomIterator(descr,atoms);
357}
[865a945]358
[fa0b18]359World::AtomIterator
360World::getAtomIter(){
361 return AtomIterator(AllAtoms(),atoms);
[865a945]362}
[354859]363
[fa0b18]364World::AtomIterator
365World::atomEnd(){
[6e97e5]366 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]367}
368
[6e97e5]369CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
370
[5d880e]371World::MoleculeIterator
372World::getMoleculeIter(MoleculeDescriptor descr){
373 return MoleculeIterator(descr,molecules);
374}
375
376World::MoleculeIterator
377World::getMoleculeIter(){
378 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]379}
380
[5d880e]381World::MoleculeIterator
382World::moleculeEnd(){
[6e97e5]383 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]384}
385
[fa0b18]386// Internal parts, without observers
387
388// Build the AtomIterator from template
389CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
390
391
392World::internal_AtomIterator
393World::getAtomIter_internal(AtomDescriptor descr){
394 return internal_AtomIterator(descr,atoms.getContent());
395}
396
397World::internal_AtomIterator
398World::atomEnd_internal(){
399 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
400}
401
[6e97e5]402// build the MoleculeIterator from template
[e3d865]403CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]404
[e3d865]405World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
406 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]407}
408
[e3d865]409World::internal_MoleculeIterator World::moleculeEnd_internal(){
410 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]411}
412
[90c4280]413/************************** Selection of Atoms and molecules ******************/
414
415// Atoms
416
417void World::clearAtomSelection(){
[69643a]418 OBSERVE;
419 NOTIFY(SelectionChanged);
[90c4280]420 selectedAtoms.clear();
421}
422
[ebc499]423void World::invertAtomSelection(){
424 // get all atoms not selected
425 AtomComposite invertedSelection(getAllAtoms());
426 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
427 AtomComposite::iterator iter =
428 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
429 std::bind1st(std::mem_fun(predicate), this));
430 invertedSelection.erase(iter, invertedSelection.end());
431 // apply new selection
432 selectedAtoms.clear();
433 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
434 std::for_each(invertedSelection.begin(),invertedSelection.end(),
435 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
436}
437
[e4afb4]438void World::selectAtom(const atom *_atom){
[69643a]439 OBSERVE;
440 NOTIFY(SelectionChanged);
[e4afb4]441 // atom * is unchanged in this function, but we do store entity as changeable
442 ASSERT(_atom,"Invalid pointer in selection of atom");
443 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
[90c4280]444}
445
[e4afb4]446void World::selectAtom(const atomId_t id){
[69643a]447 OBSERVE;
448 NOTIFY(SelectionChanged);
[90c4280]449 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
450 selectedAtoms[id]=atoms[id];
451}
452
453void World::selectAllAtoms(AtomDescriptor descr){
[69643a]454 OBSERVE;
455 NOTIFY(SelectionChanged);
[90c4280]456 internal_AtomIterator begin = getAtomIter_internal(descr);
457 internal_AtomIterator end = atomEnd_internal();
[e4afb4]458 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]459 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
460}
461
[e4afb4]462void World::selectAtomsOfMolecule(const molecule *_mol){
[69643a]463 OBSERVE;
464 NOTIFY(SelectionChanged);
[90c4280]465 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
466 // need to make it const to get the fast iterators
467 const molecule *mol = _mol;
[e4afb4]468 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]469 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
470}
471
[e4afb4]472void World::selectAtomsOfMolecule(const moleculeId_t id){
[69643a]473 OBSERVE;
474 NOTIFY(SelectionChanged);
[90c4280]475 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
476 selectAtomsOfMolecule(molecules[id]);
477}
478
[e4afb4]479void World::unselectAtom(const atom *_atom){
[69643a]480 OBSERVE;
481 NOTIFY(SelectionChanged);
[e4afb4]482 ASSERT(_atom,"Invalid pointer in unselection of atom");
483 unselectAtom(_atom->getId());
[61d655e]484}
485
[e4afb4]486void World::unselectAtom(const atomId_t id){
[69643a]487 OBSERVE;
488 NOTIFY(SelectionChanged);
[61d655e]489 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
490 selectedAtoms.erase(id);
491}
492
493void World::unselectAllAtoms(AtomDescriptor descr){
[69643a]494 OBSERVE;
495 NOTIFY(SelectionChanged);
[61d655e]496 internal_AtomIterator begin = getAtomIter_internal(descr);
497 internal_AtomIterator end = atomEnd_internal();
[e4afb4]498 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]499 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
500}
501
[e4afb4]502void World::unselectAtomsOfMolecule(const molecule *_mol){
[69643a]503 OBSERVE;
504 NOTIFY(SelectionChanged);
[61d655e]505 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
506 // need to make it const to get the fast iterators
507 const molecule *mol = _mol;
[e4afb4]508 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[992bd5]509 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
[61d655e]510}
511
[e4afb4]512void World::unselectAtomsOfMolecule(const moleculeId_t id){
[69643a]513 OBSERVE;
514 NOTIFY(SelectionChanged);
[61d655e]515 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
516 unselectAtomsOfMolecule(molecules[id]);
517}
518
[e472eab]519size_t World::countSelectedAtoms() const {
[eacc3b]520 size_t count = 0;
[e472eab]521 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]522 count++;
523 return count;
524}
525
[e4afb4]526bool World::isSelected(const atom *_atom) const {
[89643d]527 return isAtomSelected(_atom->getId());
528}
529
530bool World::isAtomSelected(const atomId_t no) const {
531 return selectedAtoms.find(no) != selectedAtoms.end();
[e0e156]532}
533
[e472eab]534const std::vector<atom *> World::getSelectedAtoms() const {
535 std::vector<atom *> returnAtoms;
536 returnAtoms.resize(countSelectedAtoms());
537 int count = 0;
538 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
539 returnAtoms[count++] = iter->second;
540 return returnAtoms;
541}
542
543
[90c4280]544// Molecules
545
546void World::clearMoleculeSelection(){
[69643a]547 OBSERVE;
548 NOTIFY(SelectionChanged);
[90c4280]549 selectedMolecules.clear();
550}
551
[ebc499]552void World::invertMoleculeSelection(){
553 // get all molecules not selected
554 typedef std::vector<molecule *> MoleculeVector_t;
555 MoleculeVector_t invertedSelection(getAllMolecules());
556 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
557 MoleculeVector_t::iterator iter =
558 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
559 std::bind1st(std::mem_fun(predicate), this));
560 invertedSelection.erase(iter, invertedSelection.end());
561 // apply new selection
562 selectedMolecules.clear();
563 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
564 std::for_each(invertedSelection.begin(),invertedSelection.end(),
565 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
566}
567
[e4afb4]568void World::selectMolecule(const molecule *_mol){
[69643a]569 OBSERVE;
570 NOTIFY(SelectionChanged);
[e4afb4]571 // molecule * is unchanged in this function, but we do store entity as changeable
572 ASSERT(_mol,"Invalid pointer to molecule in selection");
573 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
[90c4280]574}
575
[e4afb4]576void World::selectMolecule(const moleculeId_t id){
[69643a]577 OBSERVE;
578 NOTIFY(SelectionChanged);
[90c4280]579 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
580 selectedMolecules[id]=molecules[id];
581}
582
[e472eab]583void World::selectAllMolecules(MoleculeDescriptor descr){
[69643a]584 OBSERVE;
585 NOTIFY(SelectionChanged);
[90c4280]586 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
587 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]588 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]589 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
590}
591
[e4afb4]592void World::selectMoleculeOfAtom(const atom *_atom){
[69643a]593 OBSERVE;
594 NOTIFY(SelectionChanged);
[e4afb4]595 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
596 molecule *mol=_atom->getMolecule();
[90c4280]597 // the atom might not be part of a molecule
598 if(mol){
599 selectMolecule(mol);
600 }
601}
602
[e4afb4]603void World::selectMoleculeOfAtom(const atomId_t id){
[69643a]604 OBSERVE;
605 NOTIFY(SelectionChanged);
[90c4280]606 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
607 selectMoleculeOfAtom(atoms[id]);
608}
609
[e4afb4]610void World::unselectMolecule(const molecule *_mol){
[69643a]611 OBSERVE;
612 NOTIFY(SelectionChanged);
[e4afb4]613 ASSERT(_mol,"invalid pointer in unselection of molecule");
614 unselectMolecule(_mol->getId());
[61d655e]615}
616
[e4afb4]617void World::unselectMolecule(const moleculeId_t id){
[69643a]618 OBSERVE;
619 NOTIFY(SelectionChanged);
[61d655e]620 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
621 selectedMolecules.erase(id);
622}
623
[e472eab]624void World::unselectAllMolecules(MoleculeDescriptor descr){
[69643a]625 OBSERVE;
626 NOTIFY(SelectionChanged);
[61d655e]627 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
628 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]629 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]630 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
631}
632
[e4afb4]633void World::unselectMoleculeOfAtom(const atom *_atom){
[69643a]634 OBSERVE;
635 NOTIFY(SelectionChanged);
[e4afb4]636 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
637 molecule *mol=_atom->getMolecule();
[61d655e]638 // the atom might not be part of a molecule
639 if(mol){
640 unselectMolecule(mol);
641 }
642}
643
[e4afb4]644void World::unselectMoleculeOfAtom(const atomId_t id){
[69643a]645 OBSERVE;
646 NOTIFY(SelectionChanged);
[61d655e]647 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
648 unselectMoleculeOfAtom(atoms[id]);
649}
650
[e472eab]651size_t World::countSelectedMolecules() const {
[eacc3b]652 size_t count = 0;
[e472eab]653 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]654 count++;
655 return count;
656}
657
[e4afb4]658bool World::isSelected(const molecule *_mol) const {
[89643d]659 return isMoleculeSelected(_mol->getId());
660}
661
662bool World::isMoleculeSelected(const moleculeId_t no) const {
663 return selectedMolecules.find(no) != selectedMolecules.end();
[e0e156]664}
665
[e472eab]666const std::vector<molecule *> World::getSelectedMolecules() const {
667 std::vector<molecule *> returnMolecules;
668 returnMolecules.resize(countSelectedMolecules());
669 int count = 0;
670 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
671 returnMolecules[count++] = iter->second;
672 return returnMolecules;
673}
674
[3839e5]675/******************* Iterators over Selection *****************************/
676World::AtomSelectionIterator World::beginAtomSelection(){
677 return selectedAtoms.begin();
678}
679
680World::AtomSelectionIterator World::endAtomSelection(){
681 return selectedAtoms.end();
682}
683
[38f991]684World::AtomSelectionConstIterator World::beginAtomSelection() const{
685 return selectedAtoms.begin();
686}
687
688World::AtomSelectionConstIterator World::endAtomSelection() const{
689 return selectedAtoms.end();
690}
691
[3839e5]692
693World::MoleculeSelectionIterator World::beginMoleculeSelection(){
694 return selectedMolecules.begin();
695}
696
697World::MoleculeSelectionIterator World::endMoleculeSelection(){
698 return selectedMolecules.end();
699}
700
[38f991]701World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
702 return selectedMolecules.begin();
703}
704
705World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
706 return selectedMolecules.end();
707}
708
[5d1611]709/******************************* Singleton Stuff **************************/
710
[7a1ce5]711World::World() :
[cd5047]712 Observable("World"),
[f71baf]713 BG(new BondGraph(true)), // assume Angstroem for the moment
[4ae823]714 periode(new periodentafel(true)),
[8e1f7af]715 configuration(new config),
[43dad6]716 Thermostats(new ThermoStatContainer),
[e4b5de]717 ExitFlag(0),
[fa0b18]718 atoms(this),
[90c4280]719 selectedAtoms(this),
[3e4fb6]720 atomIdPool(0, 20, 100),
[51be2a]721 molecules(this),
[90c4280]722 selectedMolecules(this),
[3e4fb6]723 moleculeIdPool(0, 20,100),
[24a5e0]724 molecules_deprecated(new MoleculeListClass(this))
[7dad10]725{
[84c494]726 cell_size = new Box;
[cca9ef]727 RealSpaceMatrix domain;
[84c494]728 domain.at(0,0) = 20;
729 domain.at(1,1) = 20;
730 domain.at(2,2) = 20;
731 cell_size->setM(domain);
[4834f4]732 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
[387b36]733 defaultName = "none";
[02ce36]734 Channels *OurChannel = new Channels;
735 NotificationChannels.insert( std::make_pair( this, OurChannel) );
[7188b1]736 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
[02ce36]737 OurChannel->addChannel(type);
[7dad10]738 molecules_deprecated->signOn(this);
739}
[5d1611]740
741World::~World()
[354859]742{
[028c2e]743 molecules_deprecated->signOff(this);
[4834f4]744 delete LCcontroller;
[84c494]745 delete cell_size;
[46d958]746 delete molecules_deprecated;
[cbc5fb]747 MoleculeSet::iterator molIter;
748 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
749 DeleteMolecule((*molIter).second);
750 }
751 molecules.clear();
752 AtomSet::iterator atIter;
753 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
754 DeleteAtom((*atIter).second);
[46d958]755 }
756 atoms.clear();
[7188b1]757
758 // empty notifications
[02ce36]759 std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
760 ASSERT(iter != NotificationChannels.end(),
761 "World::~World() - cannot find our Channels in NotificationChannels.");
762 delete iter->second;
763 NotificationChannels.erase(iter);
[7188b1]764
[f71baf]765 delete BG;
[6cb9c76]766 delete periode;
767 delete configuration;
768 delete Thermostats;
[354859]769}
[5d1611]770
[23b547]771// Explicit instantiation of the singleton mechanism at this point
[5d1611]772
[3e4fb6]773// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
[b97a60]774CONSTRUCT_IDPOOL(atomId_t, uniqueId)
775CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
[3e4fb6]776
[23b547]777CONSTRUCT_SINGLETON(World)
[5d1611]778
[5f1d5b8]779CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
780
781CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
782
[5d1611]783/******************************* deprecated Legacy Stuff ***********************/
784
[354859]785MoleculeListClass *&World::getMolecules() {
786 return molecules_deprecated;
[5d1611]787}
Note: See TracBrowser for help on using the repository browser.