source: src/World.cpp@ 9cd807

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

BUGFIX: fixed undefined ref to ObservedContainer<...>::begin()/end()/count()/... at -O1

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