source: src/World.cpp@ 60896f

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 60896f was fa7989, checked in by Frederik Heber <heber@…>, 15 years ago

FIX: World::destroyMolecule(mol *) - assert that pointer is not NULL.

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