source: src/World.cpp@ df765f

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 df765f was 7188b1, checked in by Frederik Heber <heber@…>, 14 years ago

Introduced atom_observables and GLWorldView observes World, GLMoleculeObject_atom observes its atom.

Observer changes:

  • new Channels pattern required from CodePatterns 1.1.5 and that Observable signing on and off is now with const instance possible.
  • class atom is now observable, encapsulated in class AtomObservable:
    • enums have notification types
    • we use NotificationChannels of Observable to emit these distinct types.
  • atominfo, particleinfo, bondedparticleinfo all have OBSERVE and NOTIFY(..) in their setter functions (thx encapsulation).
  • class GLMoleculeObject_atom signs on to atom to changes to position, element, and index.
  • World equally has notifications for atom (new,remove) and molecules (new, remove).
  • GLWorldView now observes World for these changes.

Other changes:

  • removed additional hierarchy level for GLWidget of molecules (i.e. GLMoleculeScene removed and incorporated into GLWorldScene).
  • Property mode set to 100644
File size: 23.5 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
[5d1611]8/*
9 * World.cpp
10 *
11 * Created on: Feb 3, 2010
12 * Author: crueger
13 */
14
[bf3817]15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[ad011c]20#include "CodePatterns/MemDebug.hpp"
[112b09]21
[5d1611]22#include "World.hpp"
23
[90c4280]24#include <functional>
[5d1611]25
[d297a3]26#include "Actions/ActionTraits.hpp"
[76163d]27//#include "Actions/FragmentationAction/SubgraphDissectionAction.hpp"
[d297a3]28#include "Actions/ManipulateAtomsProcess.hpp"
[d346b6]29#include "atom.hpp"
[632508]30#include "Graph/BondGraph.hpp"
[d297a3]31#include "Box.hpp"
32#include "CodePatterns/Assert.hpp"
[8e1f7af]33#include "config.hpp"
[fc1b24]34#include "Descriptors/AtomDescriptor.hpp"
[865a945]35#include "Descriptors/AtomDescriptor_impl.hpp"
[1c51c8]36#include "Descriptors/MoleculeDescriptor.hpp"
37#include "Descriptors/MoleculeDescriptor_impl.hpp"
[6e97e5]38#include "Descriptors/SelectiveIterator_impl.hpp"
[e4fe8d]39#include "Helpers/defs.hpp"
[d297a3]40#include "LinearAlgebra/RealSpaceMatrix.hpp"
41#include "molecule.hpp"
42#include "periodentafel.hpp"
43#include "ThermoStatContainer.hpp"
44#include "WorldTime.hpp"
[d346b6]45
[ad011c]46#include "CodePatterns/Singleton_impl.hpp"
47#include "CodePatterns/ObservedContainer_impl.hpp"
[23b547]48
[d346b6]49using namespace std;
[4d9c01]50
[11e206]51const unsigned int MAX_POOL_FRAGMENTATION=20;
52const unsigned int MAX_FRAGMENTATION_SKIPS=100;
53
[7188b1]54/******************************* Notifications ************************/
55
56
57atom* World::_lastchangedatom = NULL;
58molecule* World::_lastchangedmol = NULL;
59
[5d1611]60/******************************* getter and setter ************************/
[f71baf]61periodentafel *&World::getPeriode()
62{
[5d1611]63 return periode;
64}
65
[f71baf]66BondGraph *&World::getBondGraph()
67{
68 return BG;
69}
70
71void World::setBondGraph(BondGraph *_BG){
72 delete (BG);
73 BG = _BG;
74}
75
[8e1f7af]76config *&World::getConfig(){
77 return configuration;
78}
79
[1c51c8]80// Atoms
81
[7a1ce5]82atom* World::getAtom(AtomDescriptor descriptor){
[fc1b24]83 return descriptor.find();
84}
85
[4d72e4]86World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
[fc1b24]87 return descriptor.findAll();
88}
89
[4d72e4]90World::AtomComposite World::getAllAtoms(){
[0e2a47]91 return getAllAtoms(AllAtoms());
92}
93
[354859]94int World::numAtoms(){
95 return atoms.size();
96}
97
[1c51c8]98// Molecules
99
100molecule *World::getMolecule(MoleculeDescriptor descriptor){
101 return descriptor.find();
102}
103
104std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
105 return descriptor.findAll();
106}
107
[97ebf8]108std::vector<molecule*> World::getAllMolecules(){
109 return getAllMolecules(AllMolecules());
110}
111
[354859]112int World::numMolecules(){
113 return molecules_deprecated->ListOfMolecules.size();
114}
115
[5f612ee]116// system
117
[84c494]118Box& World::getDomain() {
119 return *cell_size;
120}
121
[cca9ef]122void World::setDomain(const RealSpaceMatrix &mat){
[be97a8]123 OBSERVE;
[84c494]124 *cell_size = mat;
[5f612ee]125}
126
127void World::setDomain(double * matrix)
128{
[b9c847]129 OBSERVE;
[cca9ef]130 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
[84c494]131 cell_size->setM(M);
[5f612ee]132}
133
[d297a3]134void World::setTime(const unsigned int _step)
135{
[76163d]136 if (_step != WorldTime::getTime()) {
137 // set new time
138 WorldTime::setTime(_step);
139 // re-instantiate bond structure
140 //FragmentationSubgraphDissection();
141 }
[d297a3]142}
143
[387b36]144std::string World::getDefaultName() {
[5f612ee]145 return defaultName;
146}
147
[387b36]148void World::setDefaultName(std::string name)
[5f612ee]149{
[be97a8]150 OBSERVE;
[387b36]151 defaultName = name;
[5f612ee]152};
153
[43dad6]154class ThermoStatContainer * World::getThermostats()
155{
156 return Thermostats;
157}
158
159
[e4b5de]160int World::getExitFlag() {
161 return ExitFlag;
162}
163
164void World::setExitFlag(int flag) {
165 if (ExitFlag < flag)
166 ExitFlag = flag;
167}
[5f612ee]168
[afb47f]169/******************** Methods to change World state *********************/
170
[354859]171molecule* World::createMolecule(){
172 OBSERVE;
173 molecule *mol = NULL;
[cbc5fb]174 mol = NewMolecule();
[127a8e]175 moleculeId_t id = getNextMoleculeId();
176 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
177 mol->setId(id);
[244d26]178 // store the molecule by ID
[cbc5fb]179 molecules[mol->getId()] = mol;
[354859]180 mol->signOn(this);
[7188b1]181 _lastchangedmol = mol;
182 NOTIFY(MoleculeInserted);
[354859]183 return mol;
184}
185
[cbc5fb]186void World::destroyMolecule(molecule* mol){
187 OBSERVE;
[fa7989]188 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
[cbc5fb]189 destroyMolecule(mol->getId());
190}
191
192void World::destroyMolecule(moleculeId_t id){
193 OBSERVE;
194 molecule *mol = molecules[id];
[6d574a]195 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
[7188b1]196 _lastchangedmol = mol;
197 NOTIFY(MoleculeRemoved);
[cbc5fb]198 DeleteMolecule(mol);
199 molecules.erase(id);
[127a8e]200 releaseMoleculeId(id);
[cbc5fb]201}
202
[46d958]203atom *World::createAtom(){
204 OBSERVE;
[88d586]205 atomId_t id = getNextAtomId();
[127a8e]206 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
[88d586]207 atom *res = NewAtom(id);
[46d958]208 res->setWorld(this);
[244d26]209 // store the atom by ID
[46d958]210 atoms[res->getId()] = res;
[7188b1]211 _lastchangedatom = res;
212 NOTIFY(AtomInserted);
[46d958]213 return res;
214}
215
[5f612ee]216
[46d958]217int World::registerAtom(atom *atom){
218 OBSERVE;
[88d586]219 atomId_t id = getNextAtomId();
220 atom->setId(id);
[46d958]221 atom->setWorld(this);
222 atoms[atom->getId()] = atom;
223 return atom->getId();
224}
225
226void World::destroyAtom(atom* atom){
227 OBSERVE;
228 int id = atom->getId();
229 destroyAtom(id);
230}
231
[cbc5fb]232void World::destroyAtom(atomId_t id) {
[46d958]233 OBSERVE;
234 atom *atom = atoms[id];
[6d574a]235 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[7188b1]236 _lastchangedatom = atom;
237 NOTIFY(AtomRemoved);
[46d958]238 DeleteAtom(atom);
239 atoms.erase(id);
[88d586]240 releaseAtomId(id);
241}
242
243bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
244 OBSERVE;
245 // in case this call did not originate from inside the atom, we redirect it,
246 // to also let it know that it has changed
247 if(!target){
248 target = atoms[oldId];
[6d574a]249 ASSERT(target,"Atom with that ID not found");
[88d586]250 return target->changeId(newId);
251 }
252 else{
253 if(reserveAtomId(newId)){
254 atoms.erase(oldId);
255 atoms.insert(pair<atomId_t,atom*>(newId,target));
256 return true;
257 }
258 else{
259 return false;
260 }
261 }
[46d958]262}
263
[a7a087]264bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
265 OBSERVE;
266 // in case this call did not originate from inside the atom, we redirect it,
267 // to also let it know that it has changed
268 if(!target){
269 target = molecules[oldId];
270 ASSERT(target,"Molecule with that ID not found");
271 return target->changeId(newId);
272 }
273 else{
274 if(reserveMoleculeId(newId)){
275 molecules.erase(oldId);
276 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
277 return true;
278 }
279 else{
280 return false;
281 }
282 }
283}
284
[7c4e29]285ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[e4afb4]286 ActionTraits manipulateTrait(name);
287 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
[7c4e29]288}
289
[0e2a47]290ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
291 return manipulateAtoms(op,name,AllAtoms());
292}
293
[afb47f]294/********************* Internal Change methods for double Callback and Observer mechanism ********/
295
296void World::doManipulate(ManipulateAtomsProcess *proc){
297 proc->signOn(this);
298 {
299 OBSERVE;
300 proc->doManipulate(this);
301 }
302 proc->signOff(this);
303}
[88d586]304/******************************* IDManagement *****************************/
305
[57adc7]306// Atoms
307
[88d586]308atomId_t World::getNextAtomId(){
[127a8e]309 // try to find an Id in the pool;
310 if(!atomIdPool.empty()){
311 atomIdPool_t::iterator iter=atomIdPool.begin();
312 atomId_t id = iter->first;
[dc11c9]313 range<atomId_t> newRange = makeRange(id+1,iter->last);
[127a8e]314 // we wont use this iterator anymore, so we don't care about invalidating
315 atomIdPool.erase(iter);
[dc11c9]316 if(newRange.first<newRange.last){
[127a8e]317 atomIdPool.insert(newRange);
318 }
[23b547]319 return id;
[88d586]320 }
[127a8e]321 // Nothing in the pool... we are out of luck
322 return currAtomId++;
[88d586]323}
324
325void World::releaseAtomId(atomId_t id){
[dc11c9]326 atomIdPool.insert(makeRange(id,id+1));
[127a8e]327 defragAtomIdPool();
[88d586]328}
[afb47f]329
[88d586]330bool World::reserveAtomId(atomId_t id){
331 if(id>=currAtomId ){
[dc11c9]332 range<atomId_t> newRange = makeRange(currAtomId,id);
333 if(newRange.first<newRange.last){
[127a8e]334 atomIdPool.insert(newRange);
[88d586]335 }
336 currAtomId=id+1;
[127a8e]337 defragAtomIdPool();
[88d586]338 return true;
339 }
[127a8e]340 // look for a range that matches the request
341 for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
[dc11c9]342 if(iter->isBefore(id)){
343 // we have covered all available ranges... nothing to be found here
[127a8e]344 break;
345 }
346 // no need to check first, since it has to be <=id, since otherwise we would have broken out
[dc11c9]347 if(!iter->isBeyond(id)){
[127a8e]348 // we found a matching range... get the id from this range
349
350 // split up this range at the point of id
[dc11c9]351 range<atomId_t> bottomRange = makeRange(iter->first,id);
352 range<atomId_t> topRange = makeRange(id+1,iter->last);
[127a8e]353 // remove this range
354 atomIdPool.erase(iter);
[dc11c9]355 if(bottomRange.first<bottomRange.last){
[127a8e]356 atomIdPool.insert(bottomRange);
357 }
[dc11c9]358 if(topRange.first<topRange.last){
[127a8e]359 atomIdPool.insert(topRange);
360 }
361 defragAtomIdPool();
362 return true;
363 }
[88d586]364 }
[127a8e]365 // this ID could not be reserved
366 return false;
367}
368
369void World::defragAtomIdPool(){
370 // check if the situation is bad enough to make defragging neccessary
371 if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
372 (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
373 ++numAtomDefragSkips;
374 return;
375 }
376 for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
377 // see if this range is adjacent to the next one
378 atomIdPool_t::iterator next = iter;
379 next++;
[dc11c9]380 if(next!=atomIdPool.end() && (next->first==iter->last)){
[127a8e]381 // merge the two ranges
[dc11c9]382 range<atomId_t> newRange = makeRange(iter->first,next->last);
[127a8e]383 atomIdPool.erase(iter);
384 atomIdPool.erase(next);
385 pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
386 ASSERT(res.second,"Id-Pool was confused");
387 iter=res.first;
388 continue;
389 }
390 ++iter;
391 }
392 if(!atomIdPool.empty()){
393 // check if the last range is at the border
394 atomIdPool_t::iterator iter = atomIdPool.end();
395 iter--;
[dc11c9]396 if(iter->last==currAtomId){
[127a8e]397 currAtomId=iter->first;
398 atomIdPool.erase(iter);
399 }
[88d586]400 }
[127a8e]401 lastAtomPoolSize=atomIdPool.size();
402 numAtomDefragSkips=0;
[88d586]403}
[57adc7]404
405// Molecules
406
[127a8e]407moleculeId_t World::getNextMoleculeId(){
408 // try to find an Id in the pool;
409 if(!moleculeIdPool.empty()){
410 moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
411 moleculeId_t id = iter->first;
[dc11c9]412 range<moleculeId_t> newRange = makeRange(id+1,iter->last);
[127a8e]413 // we wont use this iterator anymore, so we don't care about invalidating
414 moleculeIdPool.erase(iter);
[dc11c9]415 if(newRange.first<newRange.last){
[127a8e]416 moleculeIdPool.insert(newRange);
417 }
418 return id;
419 }
420 // Nothing in the pool... we are out of luck
421 return currMoleculeId++;
422}
423
424void World::releaseMoleculeId(moleculeId_t id){
[dc11c9]425 moleculeIdPool.insert(makeRange(id,id+1));
[127a8e]426 defragMoleculeIdPool();
427}
428
429bool World::reserveMoleculeId(moleculeId_t id){
430 if(id>=currMoleculeId ){
[dc11c9]431 range<moleculeId_t> newRange = makeRange(currMoleculeId,id);
432 if(newRange.first<newRange.last){
[127a8e]433 moleculeIdPool.insert(newRange);
434 }
435 currMoleculeId=id+1;
436 defragMoleculeIdPool();
437 return true;
438 }
439 // look for a range that matches the request
440 for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
[dc11c9]441 if(iter->isBefore(id)){
[127a8e]442 // we have coverd all available ranges... nothing to be found here
443 break;
444 }
445 // no need to check first, since it has to be <=id, since otherwise we would have broken out
[dc11c9]446 if(!iter->isBeyond(id)){
[127a8e]447 // we found a matching range... get the id from this range
448
449 // split up this range at the point of id
[dc11c9]450 range<moleculeId_t> bottomRange = makeRange(iter->first,id);
451 range<moleculeId_t> topRange = makeRange(id+1,iter->last);
[127a8e]452 // remove this range
453 moleculeIdPool.erase(iter);
[dc11c9]454 if(bottomRange.first<bottomRange.last){
[127a8e]455 moleculeIdPool.insert(bottomRange);
456 }
[dc11c9]457 if(topRange.first<topRange.last){
[127a8e]458 moleculeIdPool.insert(topRange);
459 }
460 defragMoleculeIdPool();
461 return true;
462 }
463 }
464 // this ID could not be reserved
465 return false;
466}
467
468void World::defragMoleculeIdPool(){
469 // check if the situation is bad enough to make defragging neccessary
470 if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
471 (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
472 ++numMoleculeDefragSkips;
473 return;
474 }
475 for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
476 // see if this range is adjacent to the next one
477 moleculeIdPool_t::iterator next = iter;
478 next++;
[dc11c9]479 if(next!=moleculeIdPool.end() && (next->first==iter->last)){
[127a8e]480 // merge the two ranges
[dc11c9]481 range<moleculeId_t> newRange = makeRange(iter->first,next->last);
[127a8e]482 moleculeIdPool.erase(iter);
483 moleculeIdPool.erase(next);
484 pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
485 ASSERT(res.second,"Id-Pool was confused");
486 iter=res.first;
487 continue;
488 }
489 ++iter;
490 }
491 if(!moleculeIdPool.empty()){
492 // check if the last range is at the border
493 moleculeIdPool_t::iterator iter = moleculeIdPool.end();
494 iter--;
[dc11c9]495 if(iter->last==currMoleculeId){
[127a8e]496 currMoleculeId=iter->first;
497 moleculeIdPool.erase(iter);
498 }
499 }
500 lastMoleculePoolSize=moleculeIdPool.size();
501 numMoleculeDefragSkips=0;
502}
503
[865a945]504/******************************* Iterators ********************************/
505
[fa0b18]506// external parts with observers
507
[6e97e5]508CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
509
[fa0b18]510World::AtomIterator
511World::getAtomIter(AtomDescriptor descr){
512 return AtomIterator(descr,atoms);
513}
[865a945]514
[fa0b18]515World::AtomIterator
516World::getAtomIter(){
517 return AtomIterator(AllAtoms(),atoms);
[865a945]518}
[354859]519
[fa0b18]520World::AtomIterator
521World::atomEnd(){
[6e97e5]522 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]523}
524
[6e97e5]525CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
526
[5d880e]527World::MoleculeIterator
528World::getMoleculeIter(MoleculeDescriptor descr){
529 return MoleculeIterator(descr,molecules);
530}
531
532World::MoleculeIterator
533World::getMoleculeIter(){
534 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]535}
536
[5d880e]537World::MoleculeIterator
538World::moleculeEnd(){
[6e97e5]539 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]540}
541
[fa0b18]542// Internal parts, without observers
543
544// Build the AtomIterator from template
545CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
546
547
548World::internal_AtomIterator
549World::getAtomIter_internal(AtomDescriptor descr){
550 return internal_AtomIterator(descr,atoms.getContent());
551}
552
553World::internal_AtomIterator
554World::atomEnd_internal(){
555 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
556}
557
[6e97e5]558// build the MoleculeIterator from template
[e3d865]559CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]560
[e3d865]561World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
562 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]563}
564
[e3d865]565World::internal_MoleculeIterator World::moleculeEnd_internal(){
566 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]567}
568
[90c4280]569/************************** Selection of Atoms and molecules ******************/
570
571// Atoms
572
573void World::clearAtomSelection(){
574 selectedAtoms.clear();
575}
576
[e4afb4]577void World::selectAtom(const atom *_atom){
578 // atom * is unchanged in this function, but we do store entity as changeable
579 ASSERT(_atom,"Invalid pointer in selection of atom");
580 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
[90c4280]581}
582
[e4afb4]583void World::selectAtom(const atomId_t id){
[90c4280]584 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
585 selectedAtoms[id]=atoms[id];
586}
587
588void World::selectAllAtoms(AtomDescriptor descr){
589 internal_AtomIterator begin = getAtomIter_internal(descr);
590 internal_AtomIterator end = atomEnd_internal();
[e4afb4]591 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]592 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
593}
594
[e4afb4]595void World::selectAtomsOfMolecule(const molecule *_mol){
[90c4280]596 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
597 // need to make it const to get the fast iterators
598 const molecule *mol = _mol;
[e4afb4]599 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]600 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
601}
602
[e4afb4]603void World::selectAtomsOfMolecule(const moleculeId_t id){
[90c4280]604 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
605 selectAtomsOfMolecule(molecules[id]);
606}
607
[e4afb4]608void World::unselectAtom(const atom *_atom){
609 ASSERT(_atom,"Invalid pointer in unselection of atom");
610 unselectAtom(_atom->getId());
[61d655e]611}
612
[e4afb4]613void World::unselectAtom(const atomId_t id){
[61d655e]614 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
615 selectedAtoms.erase(id);
616}
617
618void World::unselectAllAtoms(AtomDescriptor descr){
619 internal_AtomIterator begin = getAtomIter_internal(descr);
620 internal_AtomIterator end = atomEnd_internal();
[e4afb4]621 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]622 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
623}
624
[e4afb4]625void World::unselectAtomsOfMolecule(const molecule *_mol){
[61d655e]626 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
627 // need to make it const to get the fast iterators
628 const molecule *mol = _mol;
[e4afb4]629 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]630 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
631}
632
[e4afb4]633void World::unselectAtomsOfMolecule(const moleculeId_t id){
[61d655e]634 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
635 unselectAtomsOfMolecule(molecules[id]);
636}
637
[e472eab]638size_t World::countSelectedAtoms() const {
[eacc3b]639 size_t count = 0;
[e472eab]640 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]641 count++;
642 return count;
643}
644
[e4afb4]645bool World::isSelected(const atom *_atom) const {
646 return selectedAtoms.find(_atom->getId()) != selectedAtoms.end();
[e0e156]647}
648
[e472eab]649const std::vector<atom *> World::getSelectedAtoms() const {
650 std::vector<atom *> returnAtoms;
651 returnAtoms.resize(countSelectedAtoms());
652 int count = 0;
653 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
654 returnAtoms[count++] = iter->second;
655 return returnAtoms;
656}
657
658
[90c4280]659// Molecules
660
661void World::clearMoleculeSelection(){
662 selectedMolecules.clear();
663}
664
[e4afb4]665void World::selectMolecule(const molecule *_mol){
666 // molecule * is unchanged in this function, but we do store entity as changeable
667 ASSERT(_mol,"Invalid pointer to molecule in selection");
668 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
[90c4280]669}
670
[e4afb4]671void World::selectMolecule(const moleculeId_t id){
[90c4280]672 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
673 selectedMolecules[id]=molecules[id];
674}
675
[e472eab]676void World::selectAllMolecules(MoleculeDescriptor descr){
[90c4280]677 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
678 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]679 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]680 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
681}
682
[e4afb4]683void World::selectMoleculeOfAtom(const atom *_atom){
684 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
685 molecule *mol=_atom->getMolecule();
[90c4280]686 // the atom might not be part of a molecule
687 if(mol){
688 selectMolecule(mol);
689 }
690}
691
[e4afb4]692void World::selectMoleculeOfAtom(const atomId_t id){
[90c4280]693 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
694 selectMoleculeOfAtom(atoms[id]);
695}
696
[e4afb4]697void World::unselectMolecule(const molecule *_mol){
698 ASSERT(_mol,"invalid pointer in unselection of molecule");
699 unselectMolecule(_mol->getId());
[61d655e]700}
701
[e4afb4]702void World::unselectMolecule(const moleculeId_t id){
[61d655e]703 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
704 selectedMolecules.erase(id);
705}
706
[e472eab]707void World::unselectAllMolecules(MoleculeDescriptor descr){
[61d655e]708 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
709 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]710 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]711 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
712}
713
[e4afb4]714void World::unselectMoleculeOfAtom(const atom *_atom){
715 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
716 molecule *mol=_atom->getMolecule();
[61d655e]717 // the atom might not be part of a molecule
718 if(mol){
719 unselectMolecule(mol);
720 }
721}
722
[e4afb4]723void World::unselectMoleculeOfAtom(const atomId_t id){
[61d655e]724 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
725 unselectMoleculeOfAtom(atoms[id]);
726}
727
[e472eab]728size_t World::countSelectedMolecules() const {
[eacc3b]729 size_t count = 0;
[e472eab]730 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]731 count++;
732 return count;
733}
734
[e4afb4]735bool World::isSelected(const molecule *_mol) const {
736 return selectedMolecules.find(_mol->getId()) != selectedMolecules.end();
[e0e156]737}
738
[e472eab]739const std::vector<molecule *> World::getSelectedMolecules() const {
740 std::vector<molecule *> returnMolecules;
741 returnMolecules.resize(countSelectedMolecules());
742 int count = 0;
743 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
744 returnMolecules[count++] = iter->second;
745 return returnMolecules;
746}
747
[3839e5]748/******************* Iterators over Selection *****************************/
749World::AtomSelectionIterator World::beginAtomSelection(){
750 return selectedAtoms.begin();
751}
752
753World::AtomSelectionIterator World::endAtomSelection(){
754 return selectedAtoms.end();
755}
756
757
758World::MoleculeSelectionIterator World::beginMoleculeSelection(){
759 return selectedMolecules.begin();
760}
761
762World::MoleculeSelectionIterator World::endMoleculeSelection(){
763 return selectedMolecules.end();
764}
765
[5d1611]766/******************************* Singleton Stuff **************************/
767
[7a1ce5]768World::World() :
[cd5047]769 Observable("World"),
[f71baf]770 BG(new BondGraph(true)), // assume Angstroem for the moment
[354859]771 periode(new periodentafel),
[8e1f7af]772 configuration(new config),
[43dad6]773 Thermostats(new ThermoStatContainer),
[e4b5de]774 ExitFlag(0),
[fa0b18]775 atoms(this),
[90c4280]776 selectedAtoms(this),
[24a5e0]777 currAtomId(0),
[127a8e]778 lastAtomPoolSize(0),
779 numAtomDefragSkips(0),
[51be2a]780 molecules(this),
[90c4280]781 selectedMolecules(this),
[24a5e0]782 currMoleculeId(0),
[654394]783 lastMoleculePoolSize(0),
784 numMoleculeDefragSkips(0),
[24a5e0]785 molecules_deprecated(new MoleculeListClass(this))
[7dad10]786{
[84c494]787 cell_size = new Box;
[cca9ef]788 RealSpaceMatrix domain;
[84c494]789 domain.at(0,0) = 20;
790 domain.at(1,1) = 20;
791 domain.at(2,2) = 20;
792 cell_size->setM(domain);
[387b36]793 defaultName = "none";
[7188b1]794 NotificationChannels = new Channels(this);
795 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
796 NotificationChannels->addChannel(type);
[7dad10]797 molecules_deprecated->signOn(this);
798}
[5d1611]799
800World::~World()
[354859]801{
[028c2e]802 molecules_deprecated->signOff(this);
[84c494]803 delete cell_size;
[46d958]804 delete molecules_deprecated;
[cbc5fb]805 MoleculeSet::iterator molIter;
806 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
807 DeleteMolecule((*molIter).second);
808 }
809 molecules.clear();
810 AtomSet::iterator atIter;
811 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
812 DeleteAtom((*atIter).second);
[46d958]813 }
814 atoms.clear();
[7188b1]815
816 // empty notifications
817 delete NotificationChannels;
818
[f71baf]819 delete BG;
[6cb9c76]820 delete periode;
821 delete configuration;
822 delete Thermostats;
[354859]823}
[5d1611]824
[23b547]825// Explicit instantiation of the singleton mechanism at this point
[5d1611]826
[23b547]827CONSTRUCT_SINGLETON(World)
[5d1611]828
[5f1d5b8]829CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
830
831CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
832
[5d1611]833/******************************* deprecated Legacy Stuff ***********************/
834
[354859]835MoleculeListClass *&World::getMolecules() {
836 return molecules_deprecated;
[5d1611]837}
Note: See TracBrowser for help on using the repository browser.