source: src/World.cpp@ 6ff62c

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

FIX: Using fixed Observer in CodePatterns 1.2.6.

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