source: src/World.cpp@ e2373df

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 e2373df was 76163d, checked in by Frederik Heber <heber@…>, 14 years ago

World::setTime() now checks whether CurrentTime changes at all.

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