source: src/World.cpp@ 0cd8cf

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 0cd8cf was 03abd0, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: World::getLinkedCell() does not allow distance less than 1.

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