source: src/World.cpp@ c8302f3

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 c8302f3 was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

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