source: src/World.cpp@ 9d4ff35

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 9d4ff35 was 3bdb6d, checked in by Frederik Heber <heber@…>, 13 years ago

Moved all stuff related to elements into own subfolder and has its own convenience library.

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