source: src/World.cpp@ b3b31e

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 b3b31e was 5aaa43, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: Fixed new copyright line since start of 2013 in CodeChecks test.

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