source: src/World.cpp@ ff58f1

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

Added ifdef HAVE_CONFIG and config.h include to each and every cpp file.

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