source: src/World.cpp@ 5f8660a

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 5f8660a was bcf653, checked in by Frederik Heber <heber@…>, 14 years ago

Added copyright note to each .cpp file and an extensive one to builder.cpp.

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