source: src/World.cpp@ 748fc7

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 748fc7 was 126867, checked in by Frederik Heber <heber@…>, 11 years ago

Actions no longer register themselves, ActionQueue::addAction() introduced.

  • eventually, Actions should be constrained to the ActionQueue alone. They may be created externally but their control has to be delivered to the ActionQueue.
  • Hence, we reversed the registering process: Actions do not register themselves with the ActionRegistry but as almost all are created in ActionRegistry::fillRegistry() they are registered there as well.
  • Actions cstor and dstor are now protected, ActionRegistry is friend.
  • Action needs to befriend Registry<T> and ActionSequenceTest to grant access to dstor.
  • Property mode set to 100644
File size: 24.3 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
196void World::setTime(const unsigned int _step)
197{
198 if (_step != WorldTime::getTime()) {
199 // set new time
200 WorldTime::getInstance().setTime(_step);
201 // TODO: removed when BondGraph creates the adjacency
202 // 1. remove all of World's molecules
203 for (MoleculeIterator iter = getMoleculeIter();
204 getMoleculeIter() != moleculeEnd();
205 iter = getMoleculeIter()) {
206 getMolecules()->erase(*iter);
207 destroyMolecule(*iter);
208 }
209 // 2. (re-)create bondgraph
210 AtomComposite Set = getAllAtoms();
211 BG->CreateAdjacency(Set);
212
213 // 3. scan for connected subgraphs => molecules
214 DepthFirstSearchAnalysis DFS;
215 DFS();
216 DFS.UpdateMoleculeStructure();
217 }
218}
219
220std::string World::getDefaultName() {
221 return defaultName;
222}
223
224void World::setDefaultName(std::string name)
225{
226 OBSERVE;
227 defaultName = name;
228};
229
230class ThermoStatContainer * World::getThermostats()
231{
232 return Thermostats;
233}
234
235
236int World::getExitFlag() {
237 return ExitFlag;
238}
239
240void World::setExitFlag(int flag) {
241 if (ExitFlag < flag)
242 ExitFlag = flag;
243}
244
245/******************** Methods to change World state *********************/
246
247molecule* World::createMolecule(){
248 OBSERVE;
249 molecule *mol = NULL;
250 mol = NewMolecule();
251 moleculeId_t id = moleculeIdPool.getNextId();
252 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
253 mol->setId(id);
254 // store the molecule by ID
255 molecules[mol->getId()] = mol;
256 mol->signOn(this);
257 _lastchangedmol = mol;
258 NOTIFY(MoleculeInserted);
259 return mol;
260}
261
262void World::destroyMolecule(molecule* mol){
263 OBSERVE;
264 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
265 destroyMolecule(mol->getId());
266}
267
268void World::destroyMolecule(moleculeId_t id){
269 molecule *mol = molecules[id];
270 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
271 // give notice about immediate removal
272 {
273 OBSERVE;
274 _lastchangedmol = mol;
275 NOTIFY(MoleculeRemoved);
276 }
277 mol->signOff(this);
278 DeleteMolecule(mol);
279 if (isMoleculeSelected(id))
280 selectedMolecules.erase(id);
281 molecules.erase(id);
282 moleculeIdPool.releaseId(id);
283}
284
285atom *World::createAtom(){
286 OBSERVE;
287 atomId_t id = atomIdPool.getNextId();
288 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
289 atom *res = NewAtom(id);
290 res->setWorld(this);
291 // store the atom by ID
292 atoms[res->getId()] = res;
293 _lastchangedatom = res;
294 NOTIFY(AtomInserted);
295 return res;
296}
297
298
299int World::registerAtom(atom *atom){
300 OBSERVE;
301 atomId_t id = atomIdPool.getNextId();
302 atom->setId(id);
303 atom->setWorld(this);
304 atoms[atom->getId()] = atom;
305 _lastchangedatom = atom;
306 NOTIFY(AtomInserted);
307 return atom->getId();
308}
309
310void World::destroyAtom(atom* atom){
311 int id = atom->getId();
312 destroyAtom(id);
313}
314
315void World::destroyAtom(atomId_t id) {
316 atom *atom = atoms[id];
317 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
318 // give notice about immediate removal
319 {
320 OBSERVE;
321 _lastchangedatom = atom;
322 NOTIFY(AtomRemoved);
323 }
324 DeleteAtom(atom);
325 if (isAtomSelected(id))
326 selectedAtoms.erase(id);
327 atoms.erase(id);
328 atomIdPool.releaseId(id);
329}
330
331bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* 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 = atoms[oldId];
337 ASSERT(target,"Atom with that ID not found");
338 return target->changeId(newId);
339 }
340 else{
341 if(atomIdPool.reserveId(newId)){
342 atoms.erase(oldId);
343 atoms.insert(pair<atomId_t,atom*>(newId,target));
344 return true;
345 }
346 else{
347 return false;
348 }
349 }
350}
351
352bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
353 OBSERVE;
354 // in case this call did not originate from inside the atom, we redirect it,
355 // to also let it know that it has changed
356 if(!target){
357 target = molecules[oldId];
358 ASSERT(target,"Molecule with that ID not found");
359 return target->changeId(newId);
360 }
361 else{
362 if(moleculeIdPool.reserveId(newId)){
363 molecules.erase(oldId);
364 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
365 return true;
366 }
367 else{
368 return false;
369 }
370 }
371}
372
373ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
374 ActionTrait manipulateTrait(name);
375 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
376}
377
378ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
379 return manipulateAtoms(op,name,AllAtoms());
380}
381
382/********************* Internal Change methods for double Callback and Observer mechanism ********/
383
384void World::doManipulate(ManipulateAtomsProcess *proc){
385 proc->signOn(this);
386 {
387 OBSERVE;
388 proc->doManipulate(this);
389 }
390 proc->signOff(this);
391}
392/******************************* Iterators ********************************/
393
394// external parts with observers
395
396CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
397
398CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
399
400World::AtomIterator
401World::getAtomIter(AtomDescriptor descr){
402 return AtomIterator(descr,atoms);
403}
404
405World::AtomConstIterator
406World::getAtomIter(AtomDescriptor descr) const{
407 return AtomConstIterator(descr,atoms);
408}
409
410World::AtomIterator
411World::getAtomIter(){
412 return AtomIterator(AllAtoms(),atoms);
413}
414
415World::AtomConstIterator
416World::getAtomIter() const{
417 return AtomConstIterator(AllAtoms(),atoms);
418}
419
420World::AtomIterator
421World::atomEnd(){
422 return AtomIterator(AllAtoms(),atoms,atoms.end());
423}
424
425World::AtomConstIterator
426World::atomEnd() const{
427 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
428}
429
430CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
431
432CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
433
434World::MoleculeIterator
435World::getMoleculeIter(MoleculeDescriptor descr){
436 return MoleculeIterator(descr,molecules);
437}
438
439World::MoleculeConstIterator
440World::getMoleculeIter(MoleculeDescriptor descr) const{
441 return MoleculeConstIterator(descr,molecules);
442}
443
444World::MoleculeIterator
445World::getMoleculeIter(){
446 return MoleculeIterator(AllMolecules(),molecules);
447}
448
449World::MoleculeConstIterator
450World::getMoleculeIter() const{
451 return MoleculeConstIterator(AllMolecules(),molecules);
452}
453
454World::MoleculeIterator
455World::moleculeEnd(){
456 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
457}
458
459World::MoleculeConstIterator
460World::moleculeEnd() const{
461 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
462}
463
464// Internal parts, without observers
465
466// Build the AtomIterator from template
467CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
468
469
470World::internal_AtomIterator
471World::getAtomIter_internal(AtomDescriptor descr){
472 return internal_AtomIterator(descr,atoms.getContent());
473}
474
475World::internal_AtomIterator
476World::atomEnd_internal(){
477 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
478}
479
480// build the MoleculeIterator from template
481CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
482
483World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
484 return internal_MoleculeIterator(descr,molecules.getContent());
485}
486
487World::internal_MoleculeIterator World::moleculeEnd_internal(){
488 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
489}
490
491/************************** Selection of Atoms and molecules ******************/
492
493// Atoms
494
495void World::clearAtomSelection(){
496 OBSERVE;
497 NOTIFY(SelectionChanged);
498 selectedAtoms.clear();
499}
500
501void World::invertAtomSelection(){
502 // get all atoms not selected
503 AtomComposite invertedSelection(getAllAtoms());
504 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
505 AtomComposite::iterator iter =
506 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
507 std::bind1st(std::mem_fun(predicate), this));
508 invertedSelection.erase(iter, invertedSelection.end());
509 // apply new selection
510 selectedAtoms.clear();
511 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
512 std::for_each(invertedSelection.begin(),invertedSelection.end(),
513 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
514}
515
516void World::selectAtom(const atom *_atom){
517 OBSERVE;
518 NOTIFY(SelectionChanged);
519 // atom * is unchanged in this function, but we do store entity as changeable
520 ASSERT(_atom,"Invalid pointer in selection of atom");
521 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
522}
523
524void World::selectAtom(const atomId_t id){
525 OBSERVE;
526 NOTIFY(SelectionChanged);
527 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
528 selectedAtoms[id]=atoms[id];
529}
530
531void World::selectAllAtoms(AtomDescriptor descr){
532 OBSERVE;
533 NOTIFY(SelectionChanged);
534 internal_AtomIterator begin = getAtomIter_internal(descr);
535 internal_AtomIterator end = atomEnd_internal();
536 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
537 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
538}
539
540void World::selectAtomsOfMolecule(const molecule *_mol){
541 OBSERVE;
542 NOTIFY(SelectionChanged);
543 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
544 // need to make it const to get the fast iterators
545 const molecule *mol = _mol;
546 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
547 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
548}
549
550void World::selectAtomsOfMolecule(const moleculeId_t id){
551 OBSERVE;
552 NOTIFY(SelectionChanged);
553 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
554 selectAtomsOfMolecule(molecules[id]);
555}
556
557void World::unselectAtom(const atom *_atom){
558 OBSERVE;
559 NOTIFY(SelectionChanged);
560 ASSERT(_atom,"Invalid pointer in unselection of atom");
561 unselectAtom(_atom->getId());
562}
563
564void World::unselectAtom(const atomId_t id){
565 OBSERVE;
566 NOTIFY(SelectionChanged);
567 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
568 selectedAtoms.erase(id);
569}
570
571void World::unselectAllAtoms(AtomDescriptor descr){
572 OBSERVE;
573 NOTIFY(SelectionChanged);
574 internal_AtomIterator begin = getAtomIter_internal(descr);
575 internal_AtomIterator end = atomEnd_internal();
576 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
577 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
578}
579
580void World::unselectAtomsOfMolecule(const molecule *_mol){
581 OBSERVE;
582 NOTIFY(SelectionChanged);
583 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
584 // need to make it const to get the fast iterators
585 const molecule *mol = _mol;
586 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
587 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
588}
589
590void World::unselectAtomsOfMolecule(const moleculeId_t id){
591 OBSERVE;
592 NOTIFY(SelectionChanged);
593 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
594 unselectAtomsOfMolecule(molecules[id]);
595}
596
597size_t World::countSelectedAtoms() const {
598 size_t count = 0;
599 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
600 count++;
601 return count;
602}
603
604bool World::isSelected(const atom *_atom) const {
605 return isAtomSelected(_atom->getId());
606}
607
608bool World::isAtomSelected(const atomId_t no) const {
609 return selectedAtoms.find(no) != selectedAtoms.end();
610}
611
612const std::vector<atom *> World::getSelectedAtoms() const {
613 std::vector<atom *> returnAtoms;
614 returnAtoms.resize(countSelectedAtoms());
615 int count = 0;
616 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
617 returnAtoms[count++] = iter->second;
618 return returnAtoms;
619}
620
621
622// Molecules
623
624void World::clearMoleculeSelection(){
625 OBSERVE;
626 NOTIFY(SelectionChanged);
627 selectedMolecules.clear();
628}
629
630void World::invertMoleculeSelection(){
631 // get all molecules not selected
632 typedef std::vector<molecule *> MoleculeVector_t;
633 MoleculeVector_t invertedSelection(getAllMolecules());
634 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
635 MoleculeVector_t::iterator iter =
636 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
637 std::bind1st(std::mem_fun(predicate), this));
638 invertedSelection.erase(iter, invertedSelection.end());
639 // apply new selection
640 selectedMolecules.clear();
641 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
642 std::for_each(invertedSelection.begin(),invertedSelection.end(),
643 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
644}
645
646void World::selectMolecule(const molecule *_mol){
647 OBSERVE;
648 NOTIFY(SelectionChanged);
649 // molecule * is unchanged in this function, but we do store entity as changeable
650 ASSERT(_mol,"Invalid pointer to molecule in selection");
651 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
652}
653
654void World::selectMolecule(const moleculeId_t id){
655 OBSERVE;
656 NOTIFY(SelectionChanged);
657 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
658 selectedMolecules[id]=molecules[id];
659}
660
661void World::selectAllMolecules(MoleculeDescriptor descr){
662 OBSERVE;
663 NOTIFY(SelectionChanged);
664 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
665 internal_MoleculeIterator end = moleculeEnd_internal();
666 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
667 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
668}
669
670void World::selectMoleculeOfAtom(const atom *_atom){
671 OBSERVE;
672 NOTIFY(SelectionChanged);
673 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
674 molecule *mol=_atom->getMolecule();
675 // the atom might not be part of a molecule
676 if(mol){
677 selectMolecule(mol);
678 }
679}
680
681void World::selectMoleculeOfAtom(const atomId_t id){
682 OBSERVE;
683 NOTIFY(SelectionChanged);
684 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
685 selectMoleculeOfAtom(atoms[id]);
686}
687
688void World::unselectMolecule(const molecule *_mol){
689 OBSERVE;
690 NOTIFY(SelectionChanged);
691 ASSERT(_mol,"invalid pointer in unselection of molecule");
692 unselectMolecule(_mol->getId());
693}
694
695void World::unselectMolecule(const moleculeId_t id){
696 OBSERVE;
697 NOTIFY(SelectionChanged);
698 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
699 selectedMolecules.erase(id);
700}
701
702void World::unselectAllMolecules(MoleculeDescriptor descr){
703 OBSERVE;
704 NOTIFY(SelectionChanged);
705 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
706 internal_MoleculeIterator end = moleculeEnd_internal();
707 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
708 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
709}
710
711void World::unselectMoleculeOfAtom(const atom *_atom){
712 OBSERVE;
713 NOTIFY(SelectionChanged);
714 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
715 molecule *mol=_atom->getMolecule();
716 // the atom might not be part of a molecule
717 if(mol){
718 unselectMolecule(mol);
719 }
720}
721
722void World::unselectMoleculeOfAtom(const atomId_t id){
723 OBSERVE;
724 NOTIFY(SelectionChanged);
725 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
726 unselectMoleculeOfAtom(atoms[id]);
727}
728
729size_t World::countSelectedMolecules() const {
730 size_t count = 0;
731 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
732 count++;
733 return count;
734}
735
736bool World::isSelected(const molecule *_mol) const {
737 return isMoleculeSelected(_mol->getId());
738}
739
740bool World::isMoleculeSelected(const moleculeId_t no) const {
741 return selectedMolecules.find(no) != selectedMolecules.end();
742}
743
744const std::vector<molecule *> World::getSelectedMolecules() const {
745 std::vector<molecule *> returnMolecules;
746 returnMolecules.resize(countSelectedMolecules());
747 int count = 0;
748 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
749 returnMolecules[count++] = iter->second;
750 return returnMolecules;
751}
752
753/******************* Iterators over Selection *****************************/
754World::AtomSelectionIterator World::beginAtomSelection(){
755 return selectedAtoms.begin();
756}
757
758World::AtomSelectionIterator World::endAtomSelection(){
759 return selectedAtoms.end();
760}
761
762World::AtomSelectionConstIterator World::beginAtomSelection() const{
763 return selectedAtoms.begin();
764}
765
766World::AtomSelectionConstIterator World::endAtomSelection() const{
767 return selectedAtoms.end();
768}
769
770
771World::MoleculeSelectionIterator World::beginMoleculeSelection(){
772 return selectedMolecules.begin();
773}
774
775World::MoleculeSelectionIterator World::endMoleculeSelection(){
776 return selectedMolecules.end();
777}
778
779World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
780 return selectedMolecules.begin();
781}
782
783World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
784 return selectedMolecules.end();
785}
786
787/******************************* Singleton Stuff **************************/
788
789World::World() :
790 Observable("World"),
791 BG(new BondGraph(true)), // assume Angstroem for the moment
792 periode(new periodentafel(true)),
793 configuration(new config),
794 homologies(new HomologyContainer()),
795 Thermostats(new ThermoStatContainer),
796 ExitFlag(0),
797 atoms(this),
798 selectedAtoms(this),
799 atomIdPool(0, 20, 100),
800 molecules(this),
801 selectedMolecules(this),
802 moleculeIdPool(0, 20,100),
803 molecules_deprecated(new MoleculeListClass(this))
804{
805 cell_size = new Box;
806 RealSpaceMatrix domain;
807 domain.at(0,0) = 20;
808 domain.at(1,1) = 20;
809 domain.at(2,2) = 20;
810 cell_size->setM(domain);
811 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
812 defaultName = "none";
813 Channels *OurChannel = new Channels;
814 NotificationChannels.insert( std::make_pair( static_cast<Observable *>(this), OurChannel) );
815 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
816 OurChannel->addChannel(type);
817 molecules_deprecated->signOn(this);
818}
819
820World::~World()
821{
822 molecules_deprecated->signOff(this);
823 delete LCcontroller;
824 delete cell_size;
825 delete molecules_deprecated;
826 MoleculeSet::iterator molIter;
827 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
828 DeleteMolecule((*molIter).second);
829 }
830 molecules.clear();
831 AtomSet::iterator atIter;
832 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
833 DeleteAtom((*atIter).second);
834 }
835 atoms.clear();
836
837 delete BG;
838 delete periode;
839 delete configuration;
840 delete Thermostats;
841}
842
843// Explicit instantiation of the singleton mechanism at this point
844
845// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
846CONSTRUCT_IDPOOL(atomId_t, uniqueId)
847CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
848
849CONSTRUCT_SINGLETON(World)
850
851CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
852
853CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
854
855/******************************* deprecated Legacy Stuff ***********************/
856
857MoleculeListClass *&World::getMolecules() {
858 return molecules_deprecated;
859}
Note: See TracBrowser for help on using the repository browser.