source: src/World.cpp@ 796aa6

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 796aa6 was 11e206, checked in by Tillmann Crueger <crueger@…>, 14 years ago

Removed multiple definitions of some global constants from executeable

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