source: src/World.cpp@ 5c8807

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 5c8807 was 46ce1c, checked in by Frederik Heber <heber@…>, 10 years ago

FIX: World::setTime() now first copies Bondgraph and then sets the time.

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