source: src/World.cpp@ feb5d0

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

Added SelectiveConstIterator, allows for constant iteration over Descriptor-constraint ranges.

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