source: src/World.cpp@ fae462

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

Added BondGraph::checkBondDegree, FragmentationAction only resets degrees when incorrect.

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