source: src/World.cpp@ d297a3

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 Candidate_v1.7.0 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 d297a3 was d297a3, checked in by Frederik Heber <heber@…>, 15 years ago

World::setTime() is single access point to modifying WorldTime::CurrentTime.

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