source: src/World.cpp@ 47d041

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 47d041 was 7ba268, checked in by Frederik Heber <heber@…>, 13 years ago

Merge branch 'DipoleAngularCorrelation' into mergeMaster

Conflicts:

src/World.cpp

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