source: src/World.cpp@ 5837dd

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 5837dd was 4b8630, checked in by Frederik Heber <heber@…>, 13 years ago

World::setTime() now updates bond structure of system and related changes to DipoleAngularCorrelation.

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