source: src/World.cpp@ 936a02

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 936a02 was 3139b2, checked in by Frederik Heber <heber@…>, 13 years ago

Renamed ActionTrait and ActionTraits.

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