source: src/World.cpp@ 4f2895

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 4f2895 was 4f2895, checked in by Frederik Heber <heber@…>, 10 years ago

FIX: World::SetTime() erased molecules twice.

  • once in SetTime() and then again in DFS.Update...().
  • Property mode set to 100644
File size: 26.5 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * World.cpp
26 *
27 * Created on: Feb 3, 2010
28 * Author: crueger
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "CodePatterns/MemDebug.hpp"
37
38#include "World.hpp"
39
40#include <functional>
41
42#include "Actions/ActionTrait.hpp"
43#include "Actions/ManipulateAtomsProcess.hpp"
44#include "Atom/atom.hpp"
45#include "Box.hpp"
46#include "CodePatterns/Assert.hpp"
47#include "config.hpp"
48#include "Descriptors/AtomDescriptor.hpp"
49#include "Descriptors/AtomDescriptor_impl.hpp"
50#include "Descriptors/AtomSelectionDescriptor.hpp"
51#include "Descriptors/MoleculeDescriptor.hpp"
52#include "Descriptors/MoleculeDescriptor_impl.hpp"
53#include "Descriptors/MoleculeSelectionDescriptor.hpp"
54#include "Descriptors/SelectiveConstIterator_impl.hpp"
55#include "Descriptors/SelectiveIterator_impl.hpp"
56#include "Element/periodentafel.hpp"
57#include "Fragmentation/Homology/HomologyContainer.hpp"
58#include "Graph/BondGraph.hpp"
59#include "Graph/DepthFirstSearchAnalysis.hpp"
60#include "Helpers/defs.hpp"
61#include "LinearAlgebra/RealSpaceMatrix.hpp"
62#include "LinkedCell/LinkedCell_Controller.hpp"
63#include "LinkedCell/PointCloudAdaptor.hpp"
64#include "molecule.hpp"
65#include "MoleculeListClass.hpp"
66#include "Thermostats/ThermoStatContainer.hpp"
67#include "WorldTime.hpp"
68
69#include "IdPool_impl.hpp"
70
71#include "CodePatterns/IteratorAdaptors.hpp"
72#include "CodePatterns/Singleton_impl.hpp"
73#include "CodePatterns/Observer/Channels.hpp"
74#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
75
76using namespace MoleCuilder;
77
78/******************************* Notifications ************************/
79
80
81atom* World::_lastchangedatom = NULL;
82molecule* World::_lastchangedmol = NULL;
83
84/******************************* getter and setter ************************/
85periodentafel *&World::getPeriode()
86{
87 return periode;
88}
89
90BondGraph *&World::getBondGraph()
91{
92 return BG;
93}
94
95HomologyContainer &World::getHomologies()
96{
97 return *homologies;
98}
99
100void World::resetHomologies(HomologyContainer *&_homologies)
101{
102 HomologyContainer *oldhomologies = homologies;
103
104 // install new instance, resetting given pointer
105 homologies = _homologies;
106 _homologies = NULL;
107
108 // delete old instance which also informs all observers
109 delete oldhomologies;
110}
111
112void World::setBondGraph(BondGraph *_BG){
113 delete (BG);
114 BG = _BG;
115}
116
117config *&World::getConfig(){
118 return configuration;
119}
120
121// Atoms
122
123atom* World::getAtom(AtomDescriptor descriptor){
124 return descriptor.find();
125}
126
127World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
128 return descriptor.findAll();
129}
130
131World::AtomComposite World::getAllAtoms(){
132 return getAllAtoms(AllAtoms());
133}
134
135int World::numAtoms(){
136 return atoms.size();
137}
138
139// Molecules
140
141molecule *World::getMolecule(MoleculeDescriptor descriptor){
142 return descriptor.find();
143}
144
145std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
146 return descriptor.findAll();
147}
148
149std::vector<molecule*> World::getAllMolecules(){
150 return getAllMolecules(AllMolecules());
151}
152
153int World::numMolecules(){
154 return molecules_deprecated->ListOfMolecules.size();
155}
156
157// system
158
159Box& World::getDomain() {
160 return *cell_size;
161}
162
163void World::setDomain(const RealSpaceMatrix &mat){
164 OBSERVE;
165 *cell_size = mat;
166}
167
168void World::setDomain(double * matrix)
169{
170 OBSERVE;
171 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
172 cell_size->setM(M);
173}
174
175LinkedCell::LinkedCell_View World::getLinkedCell(double distance)
176{
177 ASSERT( distance >= 0,
178 "World::getLinkedCell() - distance is not positive.");
179 if (distance < 1.) {
180 ELOG(2, "Linked cell grid with length less than 1. is very memory-intense!");
181 distance = 1.;
182 }
183 // we have to grope past the ObservedContainer mechanism and transmorph the map
184 // into a traversable list for the adaptor
185 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
186 &(atoms.getContent()),
187 std::string("WorldsAtoms"));
188 return LCcontroller->getView(distance, atomset);
189}
190
191const unsigned World::getTime() const
192{
193 return WorldTime::getTime();
194}
195
196bool areBondsPresent(const unsigned int _step)
197{
198 bool status = false;
199
200 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
201 (!status) && (iter != const_cast<const World &>(World::getInstance()).atomEnd()); ++iter) {
202 const atom * const Walker = *iter;
203 status |= !Walker->getListOfBondsAtStep(_step).empty();
204 }
205
206 return status;
207}
208
209void copyBondgraph(const unsigned int _srcstep, const unsigned int _deststep)
210{
211 // gather all bonds from _srcstep
212 std::set<bond *> SetOfBonds;
213 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
214 iter != const_cast<const World &>(World::getInstance()).atomEnd(); ++iter) {
215 const atom * const Walker = *iter;
216 const BondList bonds = Walker->getListOfBondsAtStep(_srcstep);
217 BOOST_FOREACH( bond::ptr bondptr, bonds) {
218 SetOfBonds.insert(bondptr.get());
219 }
220 }
221 LOG(4, "DEBUG: We gathered " << SetOfBonds.size() << " bonds in total.");
222
223 // copy bond to new time step
224 for (std::set<bond *>::const_iterator bonditer = SetOfBonds.begin();
225 bonditer != SetOfBonds.end(); ++bonditer) {
226 const atom * const Walker = (*bonditer)->leftatom;
227 const atom * const OtherWalker = (*bonditer)->rightatom;
228 const_cast<atom *>(Walker)->addBond(_deststep, const_cast<atom *>(OtherWalker));
229 }
230}
231
232void World::setTime(const unsigned int _step)
233{
234 if (_step != WorldTime::getTime()) {
235 const unsigned int oldstep = WorldTime::getTime();
236
237 // 1. copy bond graph (such not each addBond causes GUI update)
238 if (!areBondsPresent(_step)) {
239// AtomComposite Set = getAllAtoms();
240// BG->cleanAdjacencyList(Set);
241 copyBondgraph(oldstep, _step);
242 }
243
244 // 2. set new time
245 WorldTime::getInstance().setTime(_step);
246
247 // 4. scan for connected subgraphs => molecules
248 DepthFirstSearchAnalysis DFS;
249 DFS();
250 DFS.UpdateMoleculeStructure();
251 }
252}
253
254std::string World::getDefaultName() {
255 return defaultName;
256}
257
258void World::setDefaultName(std::string name)
259{
260 OBSERVE;
261 defaultName = name;
262};
263
264class ThermoStatContainer * World::getThermostats()
265{
266 return Thermostats;
267}
268
269
270int World::getExitFlag() {
271 return ExitFlag;
272}
273
274void World::setExitFlag(int flag) {
275 if (ExitFlag < flag)
276 ExitFlag = flag;
277}
278
279/******************** Methods to change World state *********************/
280
281molecule* World::createMolecule(){
282 OBSERVE;
283 molecule *mol = NULL;
284 mol = NewMolecule();
285 moleculeId_t id = moleculeIdPool.getNextId();
286 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
287 mol->setId(id);
288 // store the molecule by ID
289 molecules[mol->getId()] = mol;
290 mol->signOn(this);
291 _lastchangedmol = mol;
292 NOTIFY(MoleculeInserted);
293 return mol;
294}
295
296void World::destroyMolecule(molecule* mol){
297 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
298 destroyMolecule(mol->getId());
299}
300
301void World::destroyMolecule(moleculeId_t id){
302 molecule *mol = molecules[id];
303 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
304 // give notice about immediate removal
305 {
306 OBSERVE;
307 _lastchangedmol = mol;
308 NOTIFY(MoleculeRemoved);
309 }
310 mol->signOff(this);
311 // TODO: removed when depcreated MoleculeListClass is gone
312 molecules_deprecated->erase(mol);
313 DeleteMolecule(mol);
314 if (isMoleculeSelected(id))
315 selectedMolecules.erase(id);
316 molecules.erase(id);
317 moleculeIdPool.releaseId(id);
318}
319
320atom *World::createAtom(){
321 OBSERVE;
322 atomId_t id = atomIdPool.getNextId();
323 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
324 atom *res = NewAtom(id);
325 res->setWorld(this);
326 // store the atom by ID
327 atoms[res->getId()] = res;
328 _lastchangedatom = res;
329 NOTIFY(AtomInserted);
330 return res;
331}
332
333
334int World::registerAtom(atom *atom){
335 OBSERVE;
336 atomId_t id = atomIdPool.getNextId();
337 atom->setId(id);
338 atom->setWorld(this);
339 atoms[atom->getId()] = atom;
340 _lastchangedatom = atom;
341 NOTIFY(AtomInserted);
342 return atom->getId();
343}
344
345void World::destroyAtom(atom* atom){
346 int id = atom->getId();
347 destroyAtom(id);
348}
349
350void World::destroyAtom(atomId_t id) {
351 atom *atom = atoms[id];
352 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
353 // give notice about immediate removal
354 {
355 OBSERVE;
356 _lastchangedatom = atom;
357 NOTIFY(AtomRemoved);
358 }
359 // check if it's the last atom
360 molecule *_mol = atom->getMolecule();
361 if ((_mol == NULL) || (_mol->getAtomCount() > 1))
362 _mol = NULL;
363 DeleteAtom(atom);
364 if (isAtomSelected(id))
365 selectedAtoms.erase(id);
366 atoms.erase(id);
367 atomIdPool.releaseId(id);
368 // remove molecule if empty
369 if (_mol != NULL)
370 destroyMolecule(_mol);
371}
372
373bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
374 OBSERVE;
375 // in case this call did not originate from inside the atom, we redirect it,
376 // to also let it know that it has changed
377 if(!target){
378 target = atoms[oldId];
379 ASSERT(target,"Atom with that ID not found");
380 return target->changeId(newId);
381 }
382 else{
383 if(atomIdPool.reserveId(newId)){
384 atoms.erase(oldId);
385 atoms.insert(pair<atomId_t,atom*>(newId,target));
386 return true;
387 }
388 else{
389 return false;
390 }
391 }
392}
393
394bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
395 OBSERVE;
396 // in case this call did not originate from inside the atom, we redirect it,
397 // to also let it know that it has changed
398 if(!target){
399 target = molecules[oldId];
400 ASSERT(target,"Molecule with that ID not found");
401 return target->changeId(newId);
402 }
403 else{
404 if(moleculeIdPool.reserveId(newId)){
405 molecules.erase(oldId);
406 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
407 return true;
408 }
409 else{
410 return false;
411 }
412 }
413}
414
415ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
416 ActionTrait manipulateTrait(name);
417 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
418}
419
420ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
421 return manipulateAtoms(op,name,AllAtoms());
422}
423
424/********************* Internal Change methods for double Callback and Observer mechanism ********/
425
426void World::doManipulate(ManipulateAtomsProcess *proc){
427 proc->signOn(this);
428 {
429 OBSERVE;
430 proc->doManipulate(this);
431 }
432 proc->signOff(this);
433}
434/******************************* Iterators ********************************/
435
436// external parts with observers
437
438CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
439
440CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
441
442World::AtomIterator
443World::getAtomIter(AtomDescriptor descr){
444 return AtomIterator(descr,atoms);
445}
446
447World::AtomConstIterator
448World::getAtomIter(AtomDescriptor descr) const{
449 return AtomConstIterator(descr,atoms);
450}
451
452World::AtomIterator
453World::getAtomIter(){
454 return AtomIterator(AllAtoms(),atoms);
455}
456
457World::AtomConstIterator
458World::getAtomIter() const{
459 return AtomConstIterator(AllAtoms(),atoms);
460}
461
462World::AtomIterator
463World::atomEnd(){
464 return AtomIterator(AllAtoms(),atoms,atoms.end());
465}
466
467World::AtomConstIterator
468World::atomEnd() const{
469 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
470}
471
472CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
473
474CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
475
476World::MoleculeIterator
477World::getMoleculeIter(MoleculeDescriptor descr){
478 return MoleculeIterator(descr,molecules);
479}
480
481World::MoleculeConstIterator
482World::getMoleculeIter(MoleculeDescriptor descr) const{
483 return MoleculeConstIterator(descr,molecules);
484}
485
486World::MoleculeIterator
487World::getMoleculeIter(){
488 return MoleculeIterator(AllMolecules(),molecules);
489}
490
491World::MoleculeConstIterator
492World::getMoleculeIter() const{
493 return MoleculeConstIterator(AllMolecules(),molecules);
494}
495
496World::MoleculeIterator
497World::moleculeEnd(){
498 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
499}
500
501World::MoleculeConstIterator
502World::moleculeEnd() const{
503 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
504}
505
506// Internal parts, without observers
507
508// Build the AtomIterator from template
509CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
510
511
512World::internal_AtomIterator
513World::getAtomIter_internal(AtomDescriptor descr){
514 return internal_AtomIterator(descr,atoms.getContent());
515}
516
517World::internal_AtomIterator
518World::atomEnd_internal(){
519 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
520}
521
522// build the MoleculeIterator from template
523CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
524
525World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
526 return internal_MoleculeIterator(descr,molecules.getContent());
527}
528
529World::internal_MoleculeIterator World::moleculeEnd_internal(){
530 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
531}
532
533/************************** Selection of Atoms and molecules ******************/
534
535// Atoms
536
537void World::clearAtomSelection(){
538 OBSERVE;
539 NOTIFY(SelectionChanged);
540 selectedAtoms.clear();
541}
542
543void World::invertAtomSelection(){
544 // get all atoms not selected
545 AtomComposite invertedSelection(getAllAtoms());
546 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
547 AtomComposite::iterator iter =
548 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
549 std::bind1st(std::mem_fun(predicate), this));
550 invertedSelection.erase(iter, invertedSelection.end());
551 // apply new selection
552 selectedAtoms.clear();
553 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
554 std::for_each(invertedSelection.begin(),invertedSelection.end(),
555 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
556}
557
558void World::popAtomSelection(){
559 OBSERVE;
560 NOTIFY(SelectionChanged);
561 selectedAtoms = selectedAtoms_Stack.top();
562 selectedAtoms_Stack.pop();
563}
564
565void World::pushAtomSelection(){
566 OBSERVE;
567 NOTIFY(SelectionChanged);
568 selectedAtoms_Stack.push( selectedAtoms );
569 selectedAtoms.clear();
570}
571
572void World::selectAtom(const atom *_atom){
573 OBSERVE;
574 NOTIFY(SelectionChanged);
575 // atom * is unchanged in this function, but we do store entity as changeable
576 ASSERT(_atom,"Invalid pointer in selection of atom");
577 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
578}
579
580void World::selectAtom(const atomId_t id){
581 OBSERVE;
582 NOTIFY(SelectionChanged);
583 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
584 selectedAtoms[id]=atoms[id];
585}
586
587void World::selectAllAtoms(AtomDescriptor descr){
588 OBSERVE;
589 NOTIFY(SelectionChanged);
590 internal_AtomIterator begin = getAtomIter_internal(descr);
591 internal_AtomIterator end = atomEnd_internal();
592 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
593 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
594}
595
596void World::selectAtomsOfMolecule(const molecule *_mol){
597 OBSERVE;
598 NOTIFY(SelectionChanged);
599 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
600 // need to make it const to get the fast iterators
601 const molecule *mol = _mol;
602 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
603 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
604}
605
606void World::selectAtomsOfMolecule(const moleculeId_t id){
607 OBSERVE;
608 NOTIFY(SelectionChanged);
609 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
610 selectAtomsOfMolecule(molecules[id]);
611}
612
613void World::unselectAtom(const atom *_atom){
614 OBSERVE;
615 NOTIFY(SelectionChanged);
616 ASSERT(_atom,"Invalid pointer in unselection of atom");
617 unselectAtom(_atom->getId());
618}
619
620void World::unselectAtom(const atomId_t id){
621 OBSERVE;
622 NOTIFY(SelectionChanged);
623 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
624 selectedAtoms.erase(id);
625}
626
627void World::unselectAllAtoms(AtomDescriptor descr){
628 OBSERVE;
629 NOTIFY(SelectionChanged);
630 internal_AtomIterator begin = getAtomIter_internal(descr);
631 internal_AtomIterator end = atomEnd_internal();
632 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
633 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
634}
635
636void World::unselectAtomsOfMolecule(const molecule *_mol){
637 OBSERVE;
638 NOTIFY(SelectionChanged);
639 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
640 // need to make it const to get the fast iterators
641 const molecule *mol = _mol;
642 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
643 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
644}
645
646void World::unselectAtomsOfMolecule(const moleculeId_t id){
647 OBSERVE;
648 NOTIFY(SelectionChanged);
649 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
650 unselectAtomsOfMolecule(molecules[id]);
651}
652
653size_t World::countSelectedAtoms() const {
654 size_t count = 0;
655 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
656 count++;
657 return count;
658}
659
660bool World::isSelected(const atom *_atom) const {
661 return isAtomSelected(_atom->getId());
662}
663
664bool World::isAtomSelected(const atomId_t no) const {
665 return selectedAtoms.find(no) != selectedAtoms.end();
666}
667
668const std::vector<atom *> World::getSelectedAtoms() const {
669 std::vector<atom *> returnAtoms;
670 returnAtoms.resize(countSelectedAtoms());
671 int count = 0;
672 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
673 returnAtoms[count++] = iter->second;
674 return returnAtoms;
675}
676
677
678// Molecules
679
680void World::clearMoleculeSelection(){
681 OBSERVE;
682 NOTIFY(SelectionChanged);
683 selectedMolecules.clear();
684}
685
686void World::invertMoleculeSelection(){
687 // get all molecules not selected
688 typedef std::vector<molecule *> MoleculeVector_t;
689 MoleculeVector_t invertedSelection(getAllMolecules());
690 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
691 MoleculeVector_t::iterator iter =
692 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
693 std::bind1st(std::mem_fun(predicate), this));
694 invertedSelection.erase(iter, invertedSelection.end());
695 // apply new selection
696 selectedMolecules.clear();
697 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
698 std::for_each(invertedSelection.begin(),invertedSelection.end(),
699 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
700}
701
702void World::popMoleculeSelection(){
703 OBSERVE;
704 NOTIFY(SelectionChanged);
705 selectedMolecules = selectedMolecules_Stack.top();
706 selectedMolecules_Stack.pop();
707}
708
709void World::pushMoleculeSelection(){
710 OBSERVE;
711 NOTIFY(SelectionChanged);
712 selectedMolecules_Stack.push( selectedMolecules );
713 selectedMolecules.clear();
714}
715
716void World::selectMolecule(const molecule *_mol){
717 OBSERVE;
718 NOTIFY(SelectionChanged);
719 // molecule * is unchanged in this function, but we do store entity as changeable
720 ASSERT(_mol,"Invalid pointer to molecule in selection");
721 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
722}
723
724void World::selectMolecule(const moleculeId_t id){
725 OBSERVE;
726 NOTIFY(SelectionChanged);
727 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
728 selectedMolecules[id]=molecules[id];
729}
730
731void World::selectAllMolecules(MoleculeDescriptor descr){
732 OBSERVE;
733 NOTIFY(SelectionChanged);
734 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
735 internal_MoleculeIterator end = moleculeEnd_internal();
736 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
737 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
738}
739
740void World::selectMoleculeOfAtom(const atom *_atom){
741 OBSERVE;
742 NOTIFY(SelectionChanged);
743 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
744 molecule *mol=_atom->getMolecule();
745 // the atom might not be part of a molecule
746 if(mol){
747 selectMolecule(mol);
748 }
749}
750
751void World::selectMoleculeOfAtom(const atomId_t id){
752 OBSERVE;
753 NOTIFY(SelectionChanged);
754 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
755 selectMoleculeOfAtom(atoms[id]);
756}
757
758void World::unselectMolecule(const molecule *_mol){
759 OBSERVE;
760 NOTIFY(SelectionChanged);
761 ASSERT(_mol,"invalid pointer in unselection of molecule");
762 unselectMolecule(_mol->getId());
763}
764
765void World::unselectMolecule(const moleculeId_t id){
766 OBSERVE;
767 NOTIFY(SelectionChanged);
768 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
769 selectedMolecules.erase(id);
770}
771
772void World::unselectAllMolecules(MoleculeDescriptor descr){
773 OBSERVE;
774 NOTIFY(SelectionChanged);
775 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
776 internal_MoleculeIterator end = moleculeEnd_internal();
777 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
778 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
779}
780
781void World::unselectMoleculeOfAtom(const atom *_atom){
782 OBSERVE;
783 NOTIFY(SelectionChanged);
784 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
785 molecule *mol=_atom->getMolecule();
786 // the atom might not be part of a molecule
787 if(mol){
788 unselectMolecule(mol);
789 }
790}
791
792void World::unselectMoleculeOfAtom(const atomId_t id){
793 OBSERVE;
794 NOTIFY(SelectionChanged);
795 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
796 unselectMoleculeOfAtom(atoms[id]);
797}
798
799size_t World::countSelectedMolecules() const {
800 size_t count = 0;
801 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
802 count++;
803 return count;
804}
805
806bool World::isSelected(const molecule *_mol) const {
807 return isMoleculeSelected(_mol->getId());
808}
809
810bool World::isMoleculeSelected(const moleculeId_t no) const {
811 return selectedMolecules.find(no) != selectedMolecules.end();
812}
813
814const std::vector<molecule *> World::getSelectedMolecules() const {
815 std::vector<molecule *> returnMolecules;
816 returnMolecules.resize(countSelectedMolecules());
817 int count = 0;
818 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
819 returnMolecules[count++] = iter->second;
820 return returnMolecules;
821}
822
823/******************* Iterators over Selection *****************************/
824World::AtomSelectionIterator World::beginAtomSelection(){
825 return selectedAtoms.begin();
826}
827
828World::AtomSelectionIterator World::endAtomSelection(){
829 return selectedAtoms.end();
830}
831
832World::AtomSelectionConstIterator World::beginAtomSelection() const{
833 return selectedAtoms.begin();
834}
835
836World::AtomSelectionConstIterator World::endAtomSelection() const{
837 return selectedAtoms.end();
838}
839
840
841World::MoleculeSelectionIterator World::beginMoleculeSelection(){
842 return selectedMolecules.begin();
843}
844
845World::MoleculeSelectionIterator World::endMoleculeSelection(){
846 return selectedMolecules.end();
847}
848
849World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
850 return selectedMolecules.begin();
851}
852
853World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
854 return selectedMolecules.end();
855}
856
857/******************************* Singleton Stuff **************************/
858
859World::World() :
860 Observable("World"),
861 BG(new BondGraph(true)), // assume Angstroem for the moment
862 periode(new periodentafel(true)),
863 configuration(new config),
864 homologies(new HomologyContainer()),
865 Thermostats(new ThermoStatContainer),
866 ExitFlag(0),
867 atoms(this),
868 selectedAtoms(this),
869 atomIdPool(0, 20, 100),
870 molecules(this),
871 selectedMolecules(this),
872 moleculeIdPool(0, 20,100),
873 molecules_deprecated(new MoleculeListClass(this))
874{
875 cell_size = new Box;
876 RealSpaceMatrix domain;
877 domain.at(0,0) = 20;
878 domain.at(1,1) = 20;
879 domain.at(2,2) = 20;
880 cell_size->setM(domain);
881 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
882 defaultName = "none";
883 Channels *OurChannel = new Channels;
884 NotificationChannels.insert( std::make_pair( static_cast<Observable *>(this), OurChannel) );
885 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
886 OurChannel->addChannel(type);
887 molecules_deprecated->signOn(this);
888}
889
890World::~World()
891{
892 molecules_deprecated->signOff(this);
893 delete LCcontroller;
894 delete cell_size;
895 delete molecules_deprecated;
896 MoleculeSet::iterator molIter;
897 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
898 DeleteMolecule((*molIter).second);
899 }
900 molecules.clear();
901 AtomSet::iterator atIter;
902 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
903 DeleteAtom((*atIter).second);
904 }
905 atoms.clear();
906
907 delete BG;
908 delete periode;
909 delete configuration;
910 delete Thermostats;
911 delete homologies;
912}
913
914// Explicit instantiation of the singleton mechanism at this point
915
916// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
917CONSTRUCT_IDPOOL(atomId_t, uniqueId)
918CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
919
920CONSTRUCT_SINGLETON(World)
921
922CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
923
924CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
925
926/******************************* deprecated Legacy Stuff ***********************/
927
928MoleculeListClass *&World::getMolecules() {
929 return molecules_deprecated;
930}
Note: See TracBrowser for help on using the repository browser.