source: src/World.cpp@ 6550cf

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 6550cf was 98dbee, checked in by Frederik Heber <heber@…>, 11 years ago

World now maintains HomologyContainer instance.

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