source: src/World.cpp@ 75363b

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 75363b was 42127c, checked in by Frederik Heber <heber@…>, 14 years ago

Extracted definition of MoleculeListClass and put into own header module.

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