source: src/World.cpp@ 435065

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

Moved files bondgraph.?pp -> Graph/BondGraph.?pp.

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