source: src/World.cpp@ 1a6bda

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

CodePatterns places all includes now in subfolder CodePatterns/.

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