source: src/World.cpp@ 851be8

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 851be8 was 42127c, checked in by Frederik Heber <heber@…>, 14 years ago

Extracted definition of MoleculeListClass and put into own header module.

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