source: src/World.cpp@ 89643d

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 89643d was 89643d, checked in by Frederik Heber <heber@…>, 14 years ago

Enabled also un selection when clicking already selected atoms.

  • introduced ... which allow for just knowing the id (which is all needed):
    • World::isAtomSelected(),
    • World::isMoleculeSelected().
  • Property mode set to 100644
File size: 23.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * World.cpp
10 *
11 * Created on: Feb 3, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include "World.hpp"
23
24#include <functional>
25
26#include "Actions/ActionTraits.hpp"
27//#include "Actions/FragmentationAction/SubgraphDissectionAction.hpp"
28#include "Actions/ManipulateAtomsProcess.hpp"
29#include "atom.hpp"
30#include "Graph/BondGraph.hpp"
31#include "Box.hpp"
32#include "CodePatterns/Assert.hpp"
33#include "config.hpp"
34#include "Descriptors/AtomDescriptor.hpp"
35#include "Descriptors/AtomDescriptor_impl.hpp"
36#include "Descriptors/MoleculeDescriptor.hpp"
37#include "Descriptors/MoleculeDescriptor_impl.hpp"
38#include "Descriptors/SelectiveIterator_impl.hpp"
39#include "Helpers/defs.hpp"
40#include "LinearAlgebra/RealSpaceMatrix.hpp"
41#include "molecule.hpp"
42#include "periodentafel.hpp"
43#include "ThermoStatContainer.hpp"
44#include "WorldTime.hpp"
45
46#include "CodePatterns/Singleton_impl.hpp"
47#include "CodePatterns/ObservedContainer_impl.hpp"
48
49using namespace std;
50
51const unsigned int MAX_POOL_FRAGMENTATION=20;
52const unsigned int MAX_FRAGMENTATION_SKIPS=100;
53
54/******************************* Notifications ************************/
55
56
57atom* World::_lastchangedatom = NULL;
58molecule* World::_lastchangedmol = NULL;
59
60/******************************* getter and setter ************************/
61periodentafel *&World::getPeriode()
62{
63 return periode;
64}
65
66BondGraph *&World::getBondGraph()
67{
68 return BG;
69}
70
71void World::setBondGraph(BondGraph *_BG){
72 delete (BG);
73 BG = _BG;
74}
75
76config *&World::getConfig(){
77 return configuration;
78}
79
80// Atoms
81
82atom* World::getAtom(AtomDescriptor descriptor){
83 return descriptor.find();
84}
85
86World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
87 return descriptor.findAll();
88}
89
90World::AtomComposite World::getAllAtoms(){
91 return getAllAtoms(AllAtoms());
92}
93
94int World::numAtoms(){
95 return atoms.size();
96}
97
98// Molecules
99
100molecule *World::getMolecule(MoleculeDescriptor descriptor){
101 return descriptor.find();
102}
103
104std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
105 return descriptor.findAll();
106}
107
108std::vector<molecule*> World::getAllMolecules(){
109 return getAllMolecules(AllMolecules());
110}
111
112int World::numMolecules(){
113 return molecules_deprecated->ListOfMolecules.size();
114}
115
116// system
117
118Box& World::getDomain() {
119 return *cell_size;
120}
121
122void World::setDomain(const RealSpaceMatrix &mat){
123 OBSERVE;
124 *cell_size = mat;
125}
126
127void World::setDomain(double * matrix)
128{
129 OBSERVE;
130 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
131 cell_size->setM(M);
132}
133
134void World::setTime(const unsigned int _step)
135{
136 if (_step != WorldTime::getTime()) {
137 // set new time
138 WorldTime::setTime(_step);
139 // re-instantiate bond structure
140 //FragmentationSubgraphDissection();
141 }
142}
143
144std::string World::getDefaultName() {
145 return defaultName;
146}
147
148void World::setDefaultName(std::string name)
149{
150 OBSERVE;
151 defaultName = name;
152};
153
154class ThermoStatContainer * World::getThermostats()
155{
156 return Thermostats;
157}
158
159
160int World::getExitFlag() {
161 return ExitFlag;
162}
163
164void World::setExitFlag(int flag) {
165 if (ExitFlag < flag)
166 ExitFlag = flag;
167}
168
169/******************** Methods to change World state *********************/
170
171molecule* World::createMolecule(){
172 OBSERVE;
173 molecule *mol = NULL;
174 mol = NewMolecule();
175 moleculeId_t id = getNextMoleculeId();
176 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
177 mol->setId(id);
178 // store the molecule by ID
179 molecules[mol->getId()] = mol;
180 mol->signOn(this);
181 _lastchangedmol = mol;
182 NOTIFY(MoleculeInserted);
183 return mol;
184}
185
186void World::destroyMolecule(molecule* mol){
187 OBSERVE;
188 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
189 destroyMolecule(mol->getId());
190}
191
192void World::destroyMolecule(moleculeId_t id){
193 OBSERVE;
194 molecule *mol = molecules[id];
195 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
196 _lastchangedmol = mol;
197 NOTIFY(MoleculeRemoved);
198 DeleteMolecule(mol);
199 molecules.erase(id);
200 releaseMoleculeId(id);
201}
202
203atom *World::createAtom(){
204 OBSERVE;
205 atomId_t id = getNextAtomId();
206 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
207 atom *res = NewAtom(id);
208 res->setWorld(this);
209 // store the atom by ID
210 atoms[res->getId()] = res;
211 _lastchangedatom = res;
212 NOTIFY(AtomInserted);
213 return res;
214}
215
216
217int World::registerAtom(atom *atom){
218 OBSERVE;
219 atomId_t id = getNextAtomId();
220 atom->setId(id);
221 atom->setWorld(this);
222 atoms[atom->getId()] = atom;
223 return atom->getId();
224}
225
226void World::destroyAtom(atom* atom){
227 OBSERVE;
228 int id = atom->getId();
229 destroyAtom(id);
230}
231
232void World::destroyAtom(atomId_t id) {
233 OBSERVE;
234 atom *atom = atoms[id];
235 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
236 _lastchangedatom = atom;
237 NOTIFY(AtomRemoved);
238 DeleteAtom(atom);
239 atoms.erase(id);
240 releaseAtomId(id);
241}
242
243bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
244 OBSERVE;
245 // in case this call did not originate from inside the atom, we redirect it,
246 // to also let it know that it has changed
247 if(!target){
248 target = atoms[oldId];
249 ASSERT(target,"Atom with that ID not found");
250 return target->changeId(newId);
251 }
252 else{
253 if(reserveAtomId(newId)){
254 atoms.erase(oldId);
255 atoms.insert(pair<atomId_t,atom*>(newId,target));
256 return true;
257 }
258 else{
259 return false;
260 }
261 }
262}
263
264bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
265 OBSERVE;
266 // in case this call did not originate from inside the atom, we redirect it,
267 // to also let it know that it has changed
268 if(!target){
269 target = molecules[oldId];
270 ASSERT(target,"Molecule with that ID not found");
271 return target->changeId(newId);
272 }
273 else{
274 if(reserveMoleculeId(newId)){
275 molecules.erase(oldId);
276 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
277 return true;
278 }
279 else{
280 return false;
281 }
282 }
283}
284
285ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
286 ActionTraits manipulateTrait(name);
287 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
288}
289
290ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
291 return manipulateAtoms(op,name,AllAtoms());
292}
293
294/********************* Internal Change methods for double Callback and Observer mechanism ********/
295
296void World::doManipulate(ManipulateAtomsProcess *proc){
297 proc->signOn(this);
298 {
299 OBSERVE;
300 proc->doManipulate(this);
301 }
302 proc->signOff(this);
303}
304/******************************* IDManagement *****************************/
305
306// Atoms
307
308atomId_t World::getNextAtomId(){
309 // try to find an Id in the pool;
310 if(!atomIdPool.empty()){
311 atomIdPool_t::iterator iter=atomIdPool.begin();
312 atomId_t id = iter->first;
313 range<atomId_t> newRange = makeRange(id+1,iter->last);
314 // we wont use this iterator anymore, so we don't care about invalidating
315 atomIdPool.erase(iter);
316 if(newRange.first<newRange.last){
317 atomIdPool.insert(newRange);
318 }
319 return id;
320 }
321 // Nothing in the pool... we are out of luck
322 return currAtomId++;
323}
324
325void World::releaseAtomId(atomId_t id){
326 atomIdPool.insert(makeRange(id,id+1));
327 defragAtomIdPool();
328}
329
330bool World::reserveAtomId(atomId_t id){
331 if(id>=currAtomId ){
332 range<atomId_t> newRange = makeRange(currAtomId,id);
333 if(newRange.first<newRange.last){
334 atomIdPool.insert(newRange);
335 }
336 currAtomId=id+1;
337 defragAtomIdPool();
338 return true;
339 }
340 // look for a range that matches the request
341 for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
342 if(iter->isBefore(id)){
343 // we have covered all available ranges... nothing to be found here
344 break;
345 }
346 // no need to check first, since it has to be <=id, since otherwise we would have broken out
347 if(!iter->isBeyond(id)){
348 // we found a matching range... get the id from this range
349
350 // split up this range at the point of id
351 range<atomId_t> bottomRange = makeRange(iter->first,id);
352 range<atomId_t> topRange = makeRange(id+1,iter->last);
353 // remove this range
354 atomIdPool.erase(iter);
355 if(bottomRange.first<bottomRange.last){
356 atomIdPool.insert(bottomRange);
357 }
358 if(topRange.first<topRange.last){
359 atomIdPool.insert(topRange);
360 }
361 defragAtomIdPool();
362 return true;
363 }
364 }
365 // this ID could not be reserved
366 return false;
367}
368
369void World::defragAtomIdPool(){
370 // check if the situation is bad enough to make defragging neccessary
371 if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
372 (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
373 ++numAtomDefragSkips;
374 return;
375 }
376 for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
377 // see if this range is adjacent to the next one
378 atomIdPool_t::iterator next = iter;
379 next++;
380 if(next!=atomIdPool.end() && (next->first==iter->last)){
381 // merge the two ranges
382 range<atomId_t> newRange = makeRange(iter->first,next->last);
383 atomIdPool.erase(iter);
384 atomIdPool.erase(next);
385 pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
386 ASSERT(res.second,"Id-Pool was confused");
387 iter=res.first;
388 continue;
389 }
390 ++iter;
391 }
392 if(!atomIdPool.empty()){
393 // check if the last range is at the border
394 atomIdPool_t::iterator iter = atomIdPool.end();
395 iter--;
396 if(iter->last==currAtomId){
397 currAtomId=iter->first;
398 atomIdPool.erase(iter);
399 }
400 }
401 lastAtomPoolSize=atomIdPool.size();
402 numAtomDefragSkips=0;
403}
404
405// Molecules
406
407moleculeId_t World::getNextMoleculeId(){
408 // try to find an Id in the pool;
409 if(!moleculeIdPool.empty()){
410 moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
411 moleculeId_t id = iter->first;
412 range<moleculeId_t> newRange = makeRange(id+1,iter->last);
413 // we wont use this iterator anymore, so we don't care about invalidating
414 moleculeIdPool.erase(iter);
415 if(newRange.first<newRange.last){
416 moleculeIdPool.insert(newRange);
417 }
418 return id;
419 }
420 // Nothing in the pool... we are out of luck
421 return currMoleculeId++;
422}
423
424void World::releaseMoleculeId(moleculeId_t id){
425 moleculeIdPool.insert(makeRange(id,id+1));
426 defragMoleculeIdPool();
427}
428
429bool World::reserveMoleculeId(moleculeId_t id){
430 if(id>=currMoleculeId ){
431 range<moleculeId_t> newRange = makeRange(currMoleculeId,id);
432 if(newRange.first<newRange.last){
433 moleculeIdPool.insert(newRange);
434 }
435 currMoleculeId=id+1;
436 defragMoleculeIdPool();
437 return true;
438 }
439 // look for a range that matches the request
440 for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
441 if(iter->isBefore(id)){
442 // we have coverd all available ranges... nothing to be found here
443 break;
444 }
445 // no need to check first, since it has to be <=id, since otherwise we would have broken out
446 if(!iter->isBeyond(id)){
447 // we found a matching range... get the id from this range
448
449 // split up this range at the point of id
450 range<moleculeId_t> bottomRange = makeRange(iter->first,id);
451 range<moleculeId_t> topRange = makeRange(id+1,iter->last);
452 // remove this range
453 moleculeIdPool.erase(iter);
454 if(bottomRange.first<bottomRange.last){
455 moleculeIdPool.insert(bottomRange);
456 }
457 if(topRange.first<topRange.last){
458 moleculeIdPool.insert(topRange);
459 }
460 defragMoleculeIdPool();
461 return true;
462 }
463 }
464 // this ID could not be reserved
465 return false;
466}
467
468void World::defragMoleculeIdPool(){
469 // check if the situation is bad enough to make defragging neccessary
470 if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
471 (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
472 ++numMoleculeDefragSkips;
473 return;
474 }
475 for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
476 // see if this range is adjacent to the next one
477 moleculeIdPool_t::iterator next = iter;
478 next++;
479 if(next!=moleculeIdPool.end() && (next->first==iter->last)){
480 // merge the two ranges
481 range<moleculeId_t> newRange = makeRange(iter->first,next->last);
482 moleculeIdPool.erase(iter);
483 moleculeIdPool.erase(next);
484 pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
485 ASSERT(res.second,"Id-Pool was confused");
486 iter=res.first;
487 continue;
488 }
489 ++iter;
490 }
491 if(!moleculeIdPool.empty()){
492 // check if the last range is at the border
493 moleculeIdPool_t::iterator iter = moleculeIdPool.end();
494 iter--;
495 if(iter->last==currMoleculeId){
496 currMoleculeId=iter->first;
497 moleculeIdPool.erase(iter);
498 }
499 }
500 lastMoleculePoolSize=moleculeIdPool.size();
501 numMoleculeDefragSkips=0;
502}
503
504/******************************* Iterators ********************************/
505
506// external parts with observers
507
508CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
509
510World::AtomIterator
511World::getAtomIter(AtomDescriptor descr){
512 return AtomIterator(descr,atoms);
513}
514
515World::AtomIterator
516World::getAtomIter(){
517 return AtomIterator(AllAtoms(),atoms);
518}
519
520World::AtomIterator
521World::atomEnd(){
522 return AtomIterator(AllAtoms(),atoms,atoms.end());
523}
524
525CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
526
527World::MoleculeIterator
528World::getMoleculeIter(MoleculeDescriptor descr){
529 return MoleculeIterator(descr,molecules);
530}
531
532World::MoleculeIterator
533World::getMoleculeIter(){
534 return MoleculeIterator(AllMolecules(),molecules);
535}
536
537World::MoleculeIterator
538World::moleculeEnd(){
539 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
540}
541
542// Internal parts, without observers
543
544// Build the AtomIterator from template
545CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
546
547
548World::internal_AtomIterator
549World::getAtomIter_internal(AtomDescriptor descr){
550 return internal_AtomIterator(descr,atoms.getContent());
551}
552
553World::internal_AtomIterator
554World::atomEnd_internal(){
555 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
556}
557
558// build the MoleculeIterator from template
559CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
560
561World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
562 return internal_MoleculeIterator(descr,molecules.getContent());
563}
564
565World::internal_MoleculeIterator World::moleculeEnd_internal(){
566 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
567}
568
569/************************** Selection of Atoms and molecules ******************/
570
571// Atoms
572
573void World::clearAtomSelection(){
574 selectedAtoms.clear();
575}
576
577void World::selectAtom(const atom *_atom){
578 // atom * is unchanged in this function, but we do store entity as changeable
579 ASSERT(_atom,"Invalid pointer in selection of atom");
580 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
581}
582
583void World::selectAtom(const atomId_t id){
584 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
585 selectedAtoms[id]=atoms[id];
586}
587
588void World::selectAllAtoms(AtomDescriptor descr){
589 internal_AtomIterator begin = getAtomIter_internal(descr);
590 internal_AtomIterator end = atomEnd_internal();
591 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
592 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
593}
594
595void World::selectAtomsOfMolecule(const molecule *_mol){
596 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
597 // need to make it const to get the fast iterators
598 const molecule *mol = _mol;
599 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
600 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
601}
602
603void World::selectAtomsOfMolecule(const moleculeId_t id){
604 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
605 selectAtomsOfMolecule(molecules[id]);
606}
607
608void World::unselectAtom(const atom *_atom){
609 ASSERT(_atom,"Invalid pointer in unselection of atom");
610 unselectAtom(_atom->getId());
611}
612
613void World::unselectAtom(const atomId_t id){
614 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
615 selectedAtoms.erase(id);
616}
617
618void World::unselectAllAtoms(AtomDescriptor descr){
619 internal_AtomIterator begin = getAtomIter_internal(descr);
620 internal_AtomIterator end = atomEnd_internal();
621 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
622 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
623}
624
625void World::unselectAtomsOfMolecule(const molecule *_mol){
626 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
627 // need to make it const to get the fast iterators
628 const molecule *mol = _mol;
629 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
630 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
631}
632
633void World::unselectAtomsOfMolecule(const moleculeId_t id){
634 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
635 unselectAtomsOfMolecule(molecules[id]);
636}
637
638size_t World::countSelectedAtoms() const {
639 size_t count = 0;
640 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
641 count++;
642 return count;
643}
644
645bool World::isSelected(const atom *_atom) const {
646 return isAtomSelected(_atom->getId());
647}
648
649bool World::isAtomSelected(const atomId_t no) const {
650 return selectedAtoms.find(no) != selectedAtoms.end();
651}
652
653const std::vector<atom *> World::getSelectedAtoms() const {
654 std::vector<atom *> returnAtoms;
655 returnAtoms.resize(countSelectedAtoms());
656 int count = 0;
657 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
658 returnAtoms[count++] = iter->second;
659 return returnAtoms;
660}
661
662
663// Molecules
664
665void World::clearMoleculeSelection(){
666 selectedMolecules.clear();
667}
668
669void World::selectMolecule(const molecule *_mol){
670 // molecule * is unchanged in this function, but we do store entity as changeable
671 ASSERT(_mol,"Invalid pointer to molecule in selection");
672 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
673}
674
675void World::selectMolecule(const moleculeId_t id){
676 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
677 selectedMolecules[id]=molecules[id];
678}
679
680void World::selectAllMolecules(MoleculeDescriptor descr){
681 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
682 internal_MoleculeIterator end = moleculeEnd_internal();
683 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
684 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
685}
686
687void World::selectMoleculeOfAtom(const atom *_atom){
688 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
689 molecule *mol=_atom->getMolecule();
690 // the atom might not be part of a molecule
691 if(mol){
692 selectMolecule(mol);
693 }
694}
695
696void World::selectMoleculeOfAtom(const atomId_t id){
697 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
698 selectMoleculeOfAtom(atoms[id]);
699}
700
701void World::unselectMolecule(const molecule *_mol){
702 ASSERT(_mol,"invalid pointer in unselection of molecule");
703 unselectMolecule(_mol->getId());
704}
705
706void World::unselectMolecule(const moleculeId_t id){
707 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
708 selectedMolecules.erase(id);
709}
710
711void World::unselectAllMolecules(MoleculeDescriptor descr){
712 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
713 internal_MoleculeIterator end = moleculeEnd_internal();
714 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
715 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
716}
717
718void World::unselectMoleculeOfAtom(const atom *_atom){
719 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
720 molecule *mol=_atom->getMolecule();
721 // the atom might not be part of a molecule
722 if(mol){
723 unselectMolecule(mol);
724 }
725}
726
727void World::unselectMoleculeOfAtom(const atomId_t id){
728 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
729 unselectMoleculeOfAtom(atoms[id]);
730}
731
732size_t World::countSelectedMolecules() const {
733 size_t count = 0;
734 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
735 count++;
736 return count;
737}
738
739bool World::isSelected(const molecule *_mol) const {
740 return isMoleculeSelected(_mol->getId());
741}
742
743bool World::isMoleculeSelected(const moleculeId_t no) const {
744 return selectedMolecules.find(no) != selectedMolecules.end();
745}
746
747const std::vector<molecule *> World::getSelectedMolecules() const {
748 std::vector<molecule *> returnMolecules;
749 returnMolecules.resize(countSelectedMolecules());
750 int count = 0;
751 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
752 returnMolecules[count++] = iter->second;
753 return returnMolecules;
754}
755
756/******************* Iterators over Selection *****************************/
757World::AtomSelectionIterator World::beginAtomSelection(){
758 return selectedAtoms.begin();
759}
760
761World::AtomSelectionIterator World::endAtomSelection(){
762 return selectedAtoms.end();
763}
764
765
766World::MoleculeSelectionIterator World::beginMoleculeSelection(){
767 return selectedMolecules.begin();
768}
769
770World::MoleculeSelectionIterator World::endMoleculeSelection(){
771 return selectedMolecules.end();
772}
773
774/******************************* Singleton Stuff **************************/
775
776World::World() :
777 Observable("World"),
778 BG(new BondGraph(true)), // assume Angstroem for the moment
779 periode(new periodentafel),
780 configuration(new config),
781 Thermostats(new ThermoStatContainer),
782 ExitFlag(0),
783 atoms(this),
784 selectedAtoms(this),
785 currAtomId(0),
786 lastAtomPoolSize(0),
787 numAtomDefragSkips(0),
788 molecules(this),
789 selectedMolecules(this),
790 currMoleculeId(0),
791 lastMoleculePoolSize(0),
792 numMoleculeDefragSkips(0),
793 molecules_deprecated(new MoleculeListClass(this))
794{
795 cell_size = new Box;
796 RealSpaceMatrix domain;
797 domain.at(0,0) = 20;
798 domain.at(1,1) = 20;
799 domain.at(2,2) = 20;
800 cell_size->setM(domain);
801 defaultName = "none";
802 NotificationChannels = new Channels(this);
803 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
804 NotificationChannels->addChannel(type);
805 molecules_deprecated->signOn(this);
806}
807
808World::~World()
809{
810 molecules_deprecated->signOff(this);
811 delete cell_size;
812 delete molecules_deprecated;
813 MoleculeSet::iterator molIter;
814 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
815 DeleteMolecule((*molIter).second);
816 }
817 molecules.clear();
818 AtomSet::iterator atIter;
819 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
820 DeleteAtom((*atIter).second);
821 }
822 atoms.clear();
823
824 // empty notifications
825 delete NotificationChannels;
826
827 delete BG;
828 delete periode;
829 delete configuration;
830 delete Thermostats;
831}
832
833// Explicit instantiation of the singleton mechanism at this point
834
835CONSTRUCT_SINGLETON(World)
836
837CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
838
839CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
840
841/******************************* deprecated Legacy Stuff ***********************/
842
843MoleculeListClass *&World::getMolecules() {
844 return molecules_deprecated;
845}
Note: See TracBrowser for help on using the repository browser.