source: src/World.cpp@ fa7989

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

FIX: World::destroyMolecule(mol *) - assert that pointer is not NULL.

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