source: src/World.cpp@ ab4a33

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 Candidate_v1.7.0 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 ab4a33 was ab4a33, checked in by Frederik Heber <heber@…>, 14 years ago

FIX: World::destroyAtom() now informs before atom's destruction, not after.

  • Property mode set to 100644
File size: 23.7 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 int id = atom->getId();
228 destroyAtom(id);
229}
230
[cbc5fb]231void World::destroyAtom(atomId_t id) {
[46d958]232 atom *atom = atoms[id];
[6d574a]233 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[ab4a33]234 // give notice about immediate removal
235 {
236 OBSERVE;
237 _lastchangedatom = atom;
238 NOTIFY(AtomRemoved);
239 }
[46d958]240 DeleteAtom(atom);
241 atoms.erase(id);
[88d586]242 releaseAtomId(id);
243}
244
245bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
246 OBSERVE;
247 // in case this call did not originate from inside the atom, we redirect it,
248 // to also let it know that it has changed
249 if(!target){
250 target = atoms[oldId];
[6d574a]251 ASSERT(target,"Atom with that ID not found");
[88d586]252 return target->changeId(newId);
253 }
254 else{
255 if(reserveAtomId(newId)){
256 atoms.erase(oldId);
257 atoms.insert(pair<atomId_t,atom*>(newId,target));
258 return true;
259 }
260 else{
261 return false;
262 }
263 }
[46d958]264}
265
[a7a087]266bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
267 OBSERVE;
268 // in case this call did not originate from inside the atom, we redirect it,
269 // to also let it know that it has changed
270 if(!target){
271 target = molecules[oldId];
272 ASSERT(target,"Molecule with that ID not found");
273 return target->changeId(newId);
274 }
275 else{
276 if(reserveMoleculeId(newId)){
277 molecules.erase(oldId);
278 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
279 return true;
280 }
281 else{
282 return false;
283 }
284 }
285}
286
[7c4e29]287ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[e4afb4]288 ActionTraits manipulateTrait(name);
289 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
[7c4e29]290}
291
[0e2a47]292ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
293 return manipulateAtoms(op,name,AllAtoms());
294}
295
[afb47f]296/********************* Internal Change methods for double Callback and Observer mechanism ********/
297
298void World::doManipulate(ManipulateAtomsProcess *proc){
299 proc->signOn(this);
300 {
301 OBSERVE;
302 proc->doManipulate(this);
303 }
304 proc->signOff(this);
305}
[88d586]306/******************************* IDManagement *****************************/
307
[57adc7]308// Atoms
309
[88d586]310atomId_t World::getNextAtomId(){
[127a8e]311 // try to find an Id in the pool;
312 if(!atomIdPool.empty()){
313 atomIdPool_t::iterator iter=atomIdPool.begin();
314 atomId_t id = iter->first;
[dc11c9]315 range<atomId_t> newRange = makeRange(id+1,iter->last);
[127a8e]316 // we wont use this iterator anymore, so we don't care about invalidating
317 atomIdPool.erase(iter);
[dc11c9]318 if(newRange.first<newRange.last){
[127a8e]319 atomIdPool.insert(newRange);
320 }
[23b547]321 return id;
[88d586]322 }
[127a8e]323 // Nothing in the pool... we are out of luck
324 return currAtomId++;
[88d586]325}
326
327void World::releaseAtomId(atomId_t id){
[dc11c9]328 atomIdPool.insert(makeRange(id,id+1));
[127a8e]329 defragAtomIdPool();
[88d586]330}
[afb47f]331
[88d586]332bool World::reserveAtomId(atomId_t id){
333 if(id>=currAtomId ){
[dc11c9]334 range<atomId_t> newRange = makeRange(currAtomId,id);
335 if(newRange.first<newRange.last){
[127a8e]336 atomIdPool.insert(newRange);
[88d586]337 }
338 currAtomId=id+1;
[127a8e]339 defragAtomIdPool();
[88d586]340 return true;
341 }
[127a8e]342 // look for a range that matches the request
343 for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
[dc11c9]344 if(iter->isBefore(id)){
345 // we have covered all available ranges... nothing to be found here
[127a8e]346 break;
347 }
348 // no need to check first, since it has to be <=id, since otherwise we would have broken out
[dc11c9]349 if(!iter->isBeyond(id)){
[127a8e]350 // we found a matching range... get the id from this range
351
352 // split up this range at the point of id
[dc11c9]353 range<atomId_t> bottomRange = makeRange(iter->first,id);
354 range<atomId_t> topRange = makeRange(id+1,iter->last);
[127a8e]355 // remove this range
356 atomIdPool.erase(iter);
[dc11c9]357 if(bottomRange.first<bottomRange.last){
[127a8e]358 atomIdPool.insert(bottomRange);
359 }
[dc11c9]360 if(topRange.first<topRange.last){
[127a8e]361 atomIdPool.insert(topRange);
362 }
363 defragAtomIdPool();
364 return true;
365 }
[88d586]366 }
[127a8e]367 // this ID could not be reserved
368 return false;
369}
370
371void World::defragAtomIdPool(){
372 // check if the situation is bad enough to make defragging neccessary
373 if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
374 (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
375 ++numAtomDefragSkips;
376 return;
377 }
378 for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
379 // see if this range is adjacent to the next one
380 atomIdPool_t::iterator next = iter;
381 next++;
[dc11c9]382 if(next!=atomIdPool.end() && (next->first==iter->last)){
[127a8e]383 // merge the two ranges
[dc11c9]384 range<atomId_t> newRange = makeRange(iter->first,next->last);
[127a8e]385 atomIdPool.erase(iter);
386 atomIdPool.erase(next);
387 pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
388 ASSERT(res.second,"Id-Pool was confused");
389 iter=res.first;
390 continue;
391 }
392 ++iter;
393 }
394 if(!atomIdPool.empty()){
395 // check if the last range is at the border
396 atomIdPool_t::iterator iter = atomIdPool.end();
397 iter--;
[dc11c9]398 if(iter->last==currAtomId){
[127a8e]399 currAtomId=iter->first;
400 atomIdPool.erase(iter);
401 }
[88d586]402 }
[127a8e]403 lastAtomPoolSize=atomIdPool.size();
404 numAtomDefragSkips=0;
[88d586]405}
[57adc7]406
407// Molecules
408
[127a8e]409moleculeId_t World::getNextMoleculeId(){
410 // try to find an Id in the pool;
411 if(!moleculeIdPool.empty()){
412 moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
413 moleculeId_t id = iter->first;
[dc11c9]414 range<moleculeId_t> newRange = makeRange(id+1,iter->last);
[127a8e]415 // we wont use this iterator anymore, so we don't care about invalidating
416 moleculeIdPool.erase(iter);
[dc11c9]417 if(newRange.first<newRange.last){
[127a8e]418 moleculeIdPool.insert(newRange);
419 }
420 return id;
421 }
422 // Nothing in the pool... we are out of luck
423 return currMoleculeId++;
424}
425
426void World::releaseMoleculeId(moleculeId_t id){
[dc11c9]427 moleculeIdPool.insert(makeRange(id,id+1));
[127a8e]428 defragMoleculeIdPool();
429}
430
431bool World::reserveMoleculeId(moleculeId_t id){
432 if(id>=currMoleculeId ){
[dc11c9]433 range<moleculeId_t> newRange = makeRange(currMoleculeId,id);
434 if(newRange.first<newRange.last){
[127a8e]435 moleculeIdPool.insert(newRange);
436 }
437 currMoleculeId=id+1;
438 defragMoleculeIdPool();
439 return true;
440 }
441 // look for a range that matches the request
442 for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
[dc11c9]443 if(iter->isBefore(id)){
[127a8e]444 // we have coverd all available ranges... nothing to be found here
445 break;
446 }
447 // no need to check first, since it has to be <=id, since otherwise we would have broken out
[dc11c9]448 if(!iter->isBeyond(id)){
[127a8e]449 // we found a matching range... get the id from this range
450
451 // split up this range at the point of id
[dc11c9]452 range<moleculeId_t> bottomRange = makeRange(iter->first,id);
453 range<moleculeId_t> topRange = makeRange(id+1,iter->last);
[127a8e]454 // remove this range
455 moleculeIdPool.erase(iter);
[dc11c9]456 if(bottomRange.first<bottomRange.last){
[127a8e]457 moleculeIdPool.insert(bottomRange);
458 }
[dc11c9]459 if(topRange.first<topRange.last){
[127a8e]460 moleculeIdPool.insert(topRange);
461 }
462 defragMoleculeIdPool();
463 return true;
464 }
465 }
466 // this ID could not be reserved
467 return false;
468}
469
470void World::defragMoleculeIdPool(){
471 // check if the situation is bad enough to make defragging neccessary
472 if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
473 (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
474 ++numMoleculeDefragSkips;
475 return;
476 }
477 for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
478 // see if this range is adjacent to the next one
479 moleculeIdPool_t::iterator next = iter;
480 next++;
[dc11c9]481 if(next!=moleculeIdPool.end() && (next->first==iter->last)){
[127a8e]482 // merge the two ranges
[dc11c9]483 range<moleculeId_t> newRange = makeRange(iter->first,next->last);
[127a8e]484 moleculeIdPool.erase(iter);
485 moleculeIdPool.erase(next);
486 pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
487 ASSERT(res.second,"Id-Pool was confused");
488 iter=res.first;
489 continue;
490 }
491 ++iter;
492 }
493 if(!moleculeIdPool.empty()){
494 // check if the last range is at the border
495 moleculeIdPool_t::iterator iter = moleculeIdPool.end();
496 iter--;
[dc11c9]497 if(iter->last==currMoleculeId){
[127a8e]498 currMoleculeId=iter->first;
499 moleculeIdPool.erase(iter);
500 }
501 }
502 lastMoleculePoolSize=moleculeIdPool.size();
503 numMoleculeDefragSkips=0;
504}
505
[865a945]506/******************************* Iterators ********************************/
507
[fa0b18]508// external parts with observers
509
[6e97e5]510CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
511
[fa0b18]512World::AtomIterator
513World::getAtomIter(AtomDescriptor descr){
514 return AtomIterator(descr,atoms);
515}
[865a945]516
[fa0b18]517World::AtomIterator
518World::getAtomIter(){
519 return AtomIterator(AllAtoms(),atoms);
[865a945]520}
[354859]521
[fa0b18]522World::AtomIterator
523World::atomEnd(){
[6e97e5]524 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]525}
526
[6e97e5]527CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
528
[5d880e]529World::MoleculeIterator
530World::getMoleculeIter(MoleculeDescriptor descr){
531 return MoleculeIterator(descr,molecules);
532}
533
534World::MoleculeIterator
535World::getMoleculeIter(){
536 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]537}
538
[5d880e]539World::MoleculeIterator
540World::moleculeEnd(){
[6e97e5]541 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]542}
543
[fa0b18]544// Internal parts, without observers
545
546// Build the AtomIterator from template
547CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
548
549
550World::internal_AtomIterator
551World::getAtomIter_internal(AtomDescriptor descr){
552 return internal_AtomIterator(descr,atoms.getContent());
553}
554
555World::internal_AtomIterator
556World::atomEnd_internal(){
557 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
558}
559
[6e97e5]560// build the MoleculeIterator from template
[e3d865]561CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]562
[e3d865]563World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
564 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]565}
566
[e3d865]567World::internal_MoleculeIterator World::moleculeEnd_internal(){
568 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]569}
570
[90c4280]571/************************** Selection of Atoms and molecules ******************/
572
573// Atoms
574
575void World::clearAtomSelection(){
576 selectedAtoms.clear();
577}
578
[e4afb4]579void World::selectAtom(const atom *_atom){
580 // atom * is unchanged in this function, but we do store entity as changeable
581 ASSERT(_atom,"Invalid pointer in selection of atom");
582 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
[90c4280]583}
584
[e4afb4]585void World::selectAtom(const atomId_t id){
[90c4280]586 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
587 selectedAtoms[id]=atoms[id];
588}
589
590void World::selectAllAtoms(AtomDescriptor descr){
591 internal_AtomIterator begin = getAtomIter_internal(descr);
592 internal_AtomIterator end = atomEnd_internal();
[e4afb4]593 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]594 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
595}
596
[e4afb4]597void World::selectAtomsOfMolecule(const molecule *_mol){
[90c4280]598 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
599 // need to make it const to get the fast iterators
600 const molecule *mol = _mol;
[e4afb4]601 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]602 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
603}
604
[e4afb4]605void World::selectAtomsOfMolecule(const moleculeId_t id){
[90c4280]606 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
607 selectAtomsOfMolecule(molecules[id]);
608}
609
[e4afb4]610void World::unselectAtom(const atom *_atom){
611 ASSERT(_atom,"Invalid pointer in unselection of atom");
612 unselectAtom(_atom->getId());
[61d655e]613}
614
[e4afb4]615void World::unselectAtom(const atomId_t id){
[61d655e]616 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
617 selectedAtoms.erase(id);
618}
619
620void World::unselectAllAtoms(AtomDescriptor descr){
621 internal_AtomIterator begin = getAtomIter_internal(descr);
622 internal_AtomIterator end = atomEnd_internal();
[e4afb4]623 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]624 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
625}
626
[e4afb4]627void World::unselectAtomsOfMolecule(const molecule *_mol){
[61d655e]628 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
629 // need to make it const to get the fast iterators
630 const molecule *mol = _mol;
[e4afb4]631 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]632 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
633}
634
[e4afb4]635void World::unselectAtomsOfMolecule(const moleculeId_t id){
[61d655e]636 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
637 unselectAtomsOfMolecule(molecules[id]);
638}
639
[e472eab]640size_t World::countSelectedAtoms() const {
[eacc3b]641 size_t count = 0;
[e472eab]642 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]643 count++;
644 return count;
645}
646
[e4afb4]647bool World::isSelected(const atom *_atom) const {
[89643d]648 return isAtomSelected(_atom->getId());
649}
650
651bool World::isAtomSelected(const atomId_t no) const {
652 return selectedAtoms.find(no) != selectedAtoms.end();
[e0e156]653}
654
[e472eab]655const std::vector<atom *> World::getSelectedAtoms() const {
656 std::vector<atom *> returnAtoms;
657 returnAtoms.resize(countSelectedAtoms());
658 int count = 0;
659 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
660 returnAtoms[count++] = iter->second;
661 return returnAtoms;
662}
663
664
[90c4280]665// Molecules
666
667void World::clearMoleculeSelection(){
668 selectedMolecules.clear();
669}
670
[e4afb4]671void World::selectMolecule(const molecule *_mol){
672 // molecule * is unchanged in this function, but we do store entity as changeable
673 ASSERT(_mol,"Invalid pointer to molecule in selection");
674 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
[90c4280]675}
676
[e4afb4]677void World::selectMolecule(const moleculeId_t id){
[90c4280]678 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
679 selectedMolecules[id]=molecules[id];
680}
681
[e472eab]682void World::selectAllMolecules(MoleculeDescriptor descr){
[90c4280]683 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
684 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]685 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]686 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
687}
688
[e4afb4]689void World::selectMoleculeOfAtom(const atom *_atom){
690 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
691 molecule *mol=_atom->getMolecule();
[90c4280]692 // the atom might not be part of a molecule
693 if(mol){
694 selectMolecule(mol);
695 }
696}
697
[e4afb4]698void World::selectMoleculeOfAtom(const atomId_t id){
[90c4280]699 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
700 selectMoleculeOfAtom(atoms[id]);
701}
702
[e4afb4]703void World::unselectMolecule(const molecule *_mol){
704 ASSERT(_mol,"invalid pointer in unselection of molecule");
705 unselectMolecule(_mol->getId());
[61d655e]706}
707
[e4afb4]708void World::unselectMolecule(const moleculeId_t id){
[61d655e]709 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
710 selectedMolecules.erase(id);
711}
712
[e472eab]713void World::unselectAllMolecules(MoleculeDescriptor descr){
[61d655e]714 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
715 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]716 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]717 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
718}
719
[e4afb4]720void World::unselectMoleculeOfAtom(const atom *_atom){
721 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
722 molecule *mol=_atom->getMolecule();
[61d655e]723 // the atom might not be part of a molecule
724 if(mol){
725 unselectMolecule(mol);
726 }
727}
728
[e4afb4]729void World::unselectMoleculeOfAtom(const atomId_t id){
[61d655e]730 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
731 unselectMoleculeOfAtom(atoms[id]);
732}
733
[e472eab]734size_t World::countSelectedMolecules() const {
[eacc3b]735 size_t count = 0;
[e472eab]736 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]737 count++;
738 return count;
739}
740
[e4afb4]741bool World::isSelected(const molecule *_mol) const {
[89643d]742 return isMoleculeSelected(_mol->getId());
743}
744
745bool World::isMoleculeSelected(const moleculeId_t no) const {
746 return selectedMolecules.find(no) != selectedMolecules.end();
[e0e156]747}
748
[e472eab]749const std::vector<molecule *> World::getSelectedMolecules() const {
750 std::vector<molecule *> returnMolecules;
751 returnMolecules.resize(countSelectedMolecules());
752 int count = 0;
753 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
754 returnMolecules[count++] = iter->second;
755 return returnMolecules;
756}
757
[3839e5]758/******************* Iterators over Selection *****************************/
759World::AtomSelectionIterator World::beginAtomSelection(){
760 return selectedAtoms.begin();
761}
762
763World::AtomSelectionIterator World::endAtomSelection(){
764 return selectedAtoms.end();
765}
766
767
768World::MoleculeSelectionIterator World::beginMoleculeSelection(){
769 return selectedMolecules.begin();
770}
771
772World::MoleculeSelectionIterator World::endMoleculeSelection(){
773 return selectedMolecules.end();
774}
775
[5d1611]776/******************************* Singleton Stuff **************************/
777
[7a1ce5]778World::World() :
[cd5047]779 Observable("World"),
[f71baf]780 BG(new BondGraph(true)), // assume Angstroem for the moment
[354859]781 periode(new periodentafel),
[8e1f7af]782 configuration(new config),
[43dad6]783 Thermostats(new ThermoStatContainer),
[e4b5de]784 ExitFlag(0),
[fa0b18]785 atoms(this),
[90c4280]786 selectedAtoms(this),
[24a5e0]787 currAtomId(0),
[127a8e]788 lastAtomPoolSize(0),
789 numAtomDefragSkips(0),
[51be2a]790 molecules(this),
[90c4280]791 selectedMolecules(this),
[24a5e0]792 currMoleculeId(0),
[654394]793 lastMoleculePoolSize(0),
794 numMoleculeDefragSkips(0),
[24a5e0]795 molecules_deprecated(new MoleculeListClass(this))
[7dad10]796{
[84c494]797 cell_size = new Box;
[cca9ef]798 RealSpaceMatrix domain;
[84c494]799 domain.at(0,0) = 20;
800 domain.at(1,1) = 20;
801 domain.at(2,2) = 20;
802 cell_size->setM(domain);
[387b36]803 defaultName = "none";
[7188b1]804 NotificationChannels = new Channels(this);
805 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
806 NotificationChannels->addChannel(type);
[7dad10]807 molecules_deprecated->signOn(this);
808}
[5d1611]809
810World::~World()
[354859]811{
[028c2e]812 molecules_deprecated->signOff(this);
[84c494]813 delete cell_size;
[46d958]814 delete molecules_deprecated;
[cbc5fb]815 MoleculeSet::iterator molIter;
816 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
817 DeleteMolecule((*molIter).second);
818 }
819 molecules.clear();
820 AtomSet::iterator atIter;
821 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
822 DeleteAtom((*atIter).second);
[46d958]823 }
824 atoms.clear();
[7188b1]825
826 // empty notifications
827 delete NotificationChannels;
828
[f71baf]829 delete BG;
[6cb9c76]830 delete periode;
831 delete configuration;
832 delete Thermostats;
[354859]833}
[5d1611]834
[23b547]835// Explicit instantiation of the singleton mechanism at this point
[5d1611]836
[23b547]837CONSTRUCT_SINGLETON(World)
[5d1611]838
[5f1d5b8]839CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
840
841CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
842
[5d1611]843/******************************* deprecated Legacy Stuff ***********************/
844
[354859]845MoleculeListClass *&World::getMolecules() {
846 return molecules_deprecated;
[5d1611]847}
Note: See TracBrowser for help on using the repository browser.