Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/World.cpp

    r3839e5 rb9c847  
    99
    1010#include "World.hpp"
    11 
    12 #include <functional>
    1311
    1412#include "atom.hpp"
     
    2422#include "Actions/ManipulateAtomsProcess.hpp"
    2523#include "Helpers/Assert.hpp"
    26 #include "Box.hpp"
    27 #include "Matrix.hpp"
    28 #include "defs.hpp"
    2924
    3025#include "Patterns/Singleton_impl.hpp"
    31 #include "Patterns/ObservedContainer_impl.hpp"
    3226
    3327using namespace std;
     
    8074// system
    8175
    82 Box& World::getDomain() {
    83   return *cell_size;
    84 }
    85 
    86 void World::setDomain(const Matrix &mat){
    87   *cell_size = mat;
     76double * World::getDomain() {
     77  return cell_size;
    8878}
    8979
    9080void World::setDomain(double * matrix)
    9181{
    92   Matrix M = ReturnFullMatrixforSymmetric(matrix);
    93   cell_size->setM(M);
     82  OBSERVE;
     83  cell_size[0] = matrix[0];
     84  cell_size[1] = matrix[1];
     85  cell_size[2] = matrix[2];
     86  cell_size[3] = matrix[3];
     87  cell_size[4] = matrix[4];
     88  cell_size[5] = matrix[5];
    9489}
    9590
     
    124119  molecule *mol = NULL;
    125120  mol = NewMolecule();
    126   moleculeId_t id = getNextMoleculeId();
    127   ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
    128   mol->setId(id);
     121  ASSERT(!molecules.count(currMoleculeId),"currMoleculeId did not specify an unused ID");
     122  mol->setId(currMoleculeId++);
    129123  // store the molecule by ID
    130124  molecules[mol->getId()] = mol;
     
    144138  DeleteMolecule(mol);
    145139  molecules.erase(id);
    146   releaseMoleculeId(id);
    147 }
     140}
     141
     142double *World::cell_size = NULL;
    148143
    149144atom *World::createAtom(){
    150145  OBSERVE;
    151146  atomId_t id = getNextAtomId();
    152   ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
    153147  atom *res = NewAtom(id);
    154148  res->setWorld(this);
     
    227221
    228222atomId_t World::getNextAtomId(){
    229   // try to find an Id in the pool;
    230   if(!atomIdPool.empty()){
    231     atomIdPool_t::iterator iter=atomIdPool.begin();
    232     atomId_t id = iter->first;
    233     pair<atomId_t,atomId_t> newRange = make_pair(id+1,iter->second);
    234     // we wont use this iterator anymore, so we don't care about invalidating
    235     atomIdPool.erase(iter);
    236     if(newRange.first<newRange.second){
    237       atomIdPool.insert(newRange);
    238     }
     223  // see if we can reuse some Id
     224  if(atomIdPool.empty()){
     225    return currAtomId++;
     226  }
     227  else{
     228    // we give out the first ID from the pool
     229    atomId_t id = *(atomIdPool.begin());
     230    atomIdPool.erase(id);
    239231    return id;
    240232  }
    241   // Nothing in the pool... we are out of luck
    242   return currAtomId++;
    243233}
    244234
    245235void World::releaseAtomId(atomId_t id){
    246   atomIdPool.insert(make_pair(id,id+1));
    247   defragAtomIdPool();
     236  atomIdPool.insert(id);
     237  // defragmentation of the pool
     238  set<atomId_t>::reverse_iterator iter;
     239  // go through all Ids in the pool that lie immediately below the border
     240  while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){
     241    atomIdPool.erase(--currAtomId);
     242  }
    248243}
    249244
    250245bool World::reserveAtomId(atomId_t id){
    251246  if(id>=currAtomId ){
    252     pair<atomId_t,atomId_t> newRange = make_pair(currAtomId,id);
    253     if(newRange.first<newRange.second){
    254       atomIdPool.insert(newRange);
     247    // add all ids between the new one and current border as available
     248    for(atomId_t pos=currAtomId; pos<id; ++pos){
     249      atomIdPool.insert(pos);
    255250    }
    256251    currAtomId=id+1;
    257     defragAtomIdPool();
    258252    return true;
    259253  }
    260   // look for a range that matches the request
    261   for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
    262     if(iter->first>id){
    263       // we have coverd all available ranges... nothing to be found here
    264       break;
    265     }
    266     // no need to check first, since it has to be <=id, since otherwise we would have broken out
    267     if(iter->second > id){
    268       // we found a matching range... get the id from this range
    269 
    270       // split up this range at the point of id
    271       pair<atomId_t,atomId_t> bottomRange = make_pair(iter->first,id);
    272       pair<atomId_t,atomId_t> topRange = make_pair(id+1,iter->second);
    273       // remove this range
    274       atomIdPool.erase(iter);
    275       if(bottomRange.first<bottomRange.second){
    276         atomIdPool.insert(bottomRange);
    277       }
    278       if(topRange.first<topRange.second){
    279         atomIdPool.insert(topRange);
    280       }
    281       defragAtomIdPool();
    282       return true;
    283     }
    284   }
    285   // this ID could not be reserved
    286   return false;
    287 }
    288 
    289 void World::defragAtomIdPool(){
    290   // check if the situation is bad enough to make defragging neccessary
    291   if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
    292      (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
    293     ++numAtomDefragSkips;
    294     return;
    295   }
    296   for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
    297     // see if this range is adjacent to the next one
    298     atomIdPool_t::iterator next = iter;
    299     next++;
    300     if(next!=atomIdPool.end() && (next->first==iter->second)){
    301       // merge the two ranges
    302       pair<atomId_t,atomId_t> newRange = make_pair(iter->first,next->second);
    303       atomIdPool.erase(iter);
    304       atomIdPool.erase(next);
    305       pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
    306       ASSERT(res.second,"Id-Pool was confused");
    307       iter=res.first;
    308       continue;
    309     }
    310     ++iter;
    311   }
    312   if(!atomIdPool.empty()){
    313     // check if the last range is at the border
    314     atomIdPool_t::iterator iter = atomIdPool.end();
    315     iter--;
    316     if(iter->second==currAtomId){
    317       currAtomId=iter->first;
    318       atomIdPool.erase(iter);
    319     }
    320   }
    321   lastAtomPoolSize=atomIdPool.size();
    322   numAtomDefragSkips=0;
     254  else if(atomIdPool.count(id)){
     255    atomIdPool.erase(id);
     256    return true;
     257  }
     258  else{
     259    // this ID could not be reserved
     260    return false;
     261  }
    323262}
    324263
    325264// Molecules
    326265
    327 moleculeId_t World::getNextMoleculeId(){
    328   // try to find an Id in the pool;
    329   if(!moleculeIdPool.empty()){
    330     moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
    331     moleculeId_t id = iter->first;
    332     pair<moleculeId_t,moleculeId_t> newRange = make_pair(id+1,iter->second);
    333     // we wont use this iterator anymore, so we don't care about invalidating
    334     moleculeIdPool.erase(iter);
    335     if(newRange.first<newRange.second){
    336       moleculeIdPool.insert(newRange);
    337     }
    338     return id;
    339   }
    340   // Nothing in the pool... we are out of luck
    341   return currMoleculeId++;
    342 }
    343 
    344 void World::releaseMoleculeId(moleculeId_t id){
    345   moleculeIdPool.insert(make_pair(id,id+1));
    346   defragMoleculeIdPool();
    347 }
    348 
    349 bool World::reserveMoleculeId(moleculeId_t id){
    350   if(id>=currMoleculeId ){
    351     pair<moleculeId_t,moleculeId_t> newRange = make_pair(currMoleculeId,id);
    352     if(newRange.first<newRange.second){
    353       moleculeIdPool.insert(newRange);
    354     }
    355     currMoleculeId=id+1;
    356     defragMoleculeIdPool();
    357     return true;
    358   }
    359   // look for a range that matches the request
    360   for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
    361     if(iter->first>id){
    362       // we have coverd all available ranges... nothing to be found here
    363       break;
    364     }
    365     // no need to check first, since it has to be <=id, since otherwise we would have broken out
    366     if(iter->second > id){
    367       // we found a matching range... get the id from this range
    368 
    369       // split up this range at the point of id
    370       pair<moleculeId_t,moleculeId_t> bottomRange = make_pair(iter->first,id);
    371       pair<moleculeId_t,moleculeId_t> topRange = make_pair(id+1,iter->second);
    372       // remove this range
    373       moleculeIdPool.erase(iter);
    374       if(bottomRange.first<bottomRange.second){
    375         moleculeIdPool.insert(bottomRange);
    376       }
    377       if(topRange.first<topRange.second){
    378         moleculeIdPool.insert(topRange);
    379       }
    380       defragMoleculeIdPool();
    381       return true;
    382     }
    383   }
    384   // this ID could not be reserved
    385   return false;
    386 }
    387 
    388 void World::defragMoleculeIdPool(){
    389   // check if the situation is bad enough to make defragging neccessary
    390   if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
    391      (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
    392     ++numMoleculeDefragSkips;
    393     return;
    394   }
    395   for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
    396     // see if this range is adjacent to the next one
    397     moleculeIdPool_t::iterator next = iter;
    398     next++;
    399     if(next!=moleculeIdPool.end() && (next->first==iter->second)){
    400       // merge the two ranges
    401       pair<moleculeId_t,moleculeId_t> newRange = make_pair(iter->first,next->second);
    402       moleculeIdPool.erase(iter);
    403       moleculeIdPool.erase(next);
    404       pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
    405       ASSERT(res.second,"Id-Pool was confused");
    406       iter=res.first;
    407       continue;
    408     }
    409     ++iter;
    410   }
    411   if(!moleculeIdPool.empty()){
    412     // check if the last range is at the border
    413     moleculeIdPool_t::iterator iter = moleculeIdPool.end();
    414     iter--;
    415     if(iter->second==currMoleculeId){
    416       currMoleculeId=iter->first;
    417       moleculeIdPool.erase(iter);
    418     }
    419   }
    420   lastMoleculePoolSize=moleculeIdPool.size();
    421   numMoleculeDefragSkips=0;
    422 }
    423 
    424266/******************************* Iterators ********************************/
    425267
    426 // external parts with observers
    427 
     268// Build the AtomIterator from template
    428269CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
    429270
    430 World::AtomIterator
    431 World::getAtomIter(AtomDescriptor descr){
    432     return AtomIterator(descr,atoms);
    433 }
    434 
    435 World::AtomIterator
    436 World::getAtomIter(){
    437     return AtomIterator(AllAtoms(),atoms);
    438 }
    439 
    440 World::AtomIterator
    441 World::atomEnd(){
     271
     272World::AtomIterator World::getAtomIter(AtomDescriptor descr){
     273  return AtomIterator(descr,atoms);
     274}
     275
     276World::AtomIterator World::atomEnd(){
    442277  return AtomIterator(AllAtoms(),atoms,atoms.end());
    443278}
    444279
     280// build the MoleculeIterator from template
    445281CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
    446282
    447 World::MoleculeIterator
    448 World::getMoleculeIter(MoleculeDescriptor descr){
    449     return MoleculeIterator(descr,molecules);
    450 }
    451 
    452 World::MoleculeIterator
    453 World::getMoleculeIter(){
    454     return MoleculeIterator(AllMolecules(),molecules);
    455 }
    456 
    457 World::MoleculeIterator
    458 World::moleculeEnd(){
     283World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
     284  return MoleculeIterator(descr,molecules);
     285}
     286
     287World::MoleculeIterator World::moleculeEnd(){
    459288  return MoleculeIterator(AllMolecules(),molecules,molecules.end());
    460 }
    461 
    462 // Internal parts, without observers
    463 
    464 // Build the AtomIterator from template
    465 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
    466 
    467 
    468 World::internal_AtomIterator
    469 World::getAtomIter_internal(AtomDescriptor descr){
    470   return internal_AtomIterator(descr,atoms.getContent());
    471 }
    472 
    473 World::internal_AtomIterator
    474 World::atomEnd_internal(){
    475   return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
    476 }
    477 
    478 // build the MoleculeIterator from template
    479 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
    480 
    481 World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
    482   return internal_MoleculeIterator(descr,molecules.getContent());
    483 }
    484 
    485 World::internal_MoleculeIterator World::moleculeEnd_internal(){
    486   return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
    487 }
    488 
    489 /************************** Selection of Atoms and molecules ******************/
    490 
    491 // Atoms
    492 
    493 void World::clearAtomSelection(){
    494   selectedAtoms.clear();
    495 }
    496 
    497 void World::selectAtom(atom *atom){
    498   ASSERT(atom,"Invalid pointer in selection of atom");
    499   selectedAtoms[atom->getId()]=atom;
    500 }
    501 
    502 void World::selectAtom(atomId_t id){
    503   ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
    504   selectedAtoms[id]=atoms[id];
    505 }
    506 
    507 void World::selectAllAtoms(AtomDescriptor descr){
    508   internal_AtomIterator begin = getAtomIter_internal(descr);
    509   internal_AtomIterator end = atomEnd_internal();
    510   void (World::*func)(atom*) = &World::selectAtom; // needed for type resolution of overloaded function
    511   for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
    512 }
    513 
    514 void World::selectAtomsOfMolecule(molecule *_mol){
    515   ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
    516   // need to make it const to get the fast iterators
    517   const molecule *mol = _mol;
    518   void (World::*func)(atom*) = &World::selectAtom; // needed for type resolution of overloaded function
    519   for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
    520 }
    521 
    522 void World::selectAtomsOfMolecule(moleculeId_t id){
    523   ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
    524   selectAtomsOfMolecule(molecules[id]);
    525 }
    526 
    527 void World::unselectAtom(atom *atom){
    528   ASSERT(atom,"Invalid pointer in unselection of atom");
    529   unselectAtom(atom->getId());
    530 }
    531 
    532 void World::unselectAtom(atomId_t id){
    533   ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
    534   selectedAtoms.erase(id);
    535 }
    536 
    537 void World::unselectAllAtoms(AtomDescriptor descr){
    538   internal_AtomIterator begin = getAtomIter_internal(descr);
    539   internal_AtomIterator end = atomEnd_internal();
    540   void (World::*func)(atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
    541   for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
    542 }
    543 
    544 void World::unselectAtomsOfMolecule(molecule *_mol){
    545   ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
    546   // need to make it const to get the fast iterators
    547   const molecule *mol = _mol;
    548   void (World::*func)(atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
    549   for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above
    550 }
    551 
    552 void World::unselectAtomsOfMolecule(moleculeId_t id){
    553   ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
    554   unselectAtomsOfMolecule(molecules[id]);
    555 }
    556 
    557 // Molecules
    558 
    559 void World::clearMoleculeSelection(){
    560   selectedMolecules.clear();
    561 }
    562 
    563 void World::selectMolecule(molecule *mol){
    564   ASSERT(mol,"Invalid pointer to molecule in selection");
    565   selectedMolecules[mol->getId()]=mol;
    566 }
    567 
    568 void World::selectMolecule(moleculeId_t id){
    569   ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
    570   selectedMolecules[id]=molecules[id];
    571 }
    572 
    573 void World::selectAllMoleculess(MoleculeDescriptor descr){
    574   internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
    575   internal_MoleculeIterator end = moleculeEnd_internal();
    576   void (World::*func)(molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
    577   for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
    578 }
    579 
    580 void World::selectMoleculeOfAtom(atom *atom){
    581   ASSERT(atom,"Invalid atom pointer in selection of MoleculeOfAtom");
    582   molecule *mol=atom->getMolecule();
    583   // the atom might not be part of a molecule
    584   if(mol){
    585     selectMolecule(mol);
    586   }
    587 }
    588 
    589 void World::selectMoleculeOfAtom(atomId_t id){
    590   ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
    591   selectMoleculeOfAtom(atoms[id]);
    592 }
    593 
    594 void World::unselectMolecule(molecule *mol){
    595   ASSERT(mol,"invalid pointer in unselection of molecule");
    596   unselectMolecule(mol->getId());
    597 }
    598 
    599 void World::unselectMolecule(moleculeId_t id){
    600   ASSERT(molecules.count(id),"No such molecule with ID in unselection");
    601   selectedMolecules.erase(id);
    602 }
    603 
    604 void World::unselectAllMoleculess(MoleculeDescriptor descr){
    605   internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
    606   internal_MoleculeIterator end = moleculeEnd_internal();
    607   void (World::*func)(molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
    608   for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
    609 }
    610 
    611 void World::unselectMoleculeOfAtom(atom *atom){
    612   ASSERT(atom,"Invalid atom pointer in selection of MoleculeOfAtom");
    613   molecule *mol=atom->getMolecule();
    614   // the atom might not be part of a molecule
    615   if(mol){
    616     unselectMolecule(mol);
    617   }
    618 }
    619 
    620 void World::unselectMoleculeOfAtom(atomId_t id){
    621   ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
    622   unselectMoleculeOfAtom(atoms[id]);
    623 }
    624 
    625 /******************* Iterators over Selection *****************************/
    626 World::AtomSelectionIterator World::beginAtomSelection(){
    627   return selectedAtoms.begin();
    628 }
    629 
    630 World::AtomSelectionIterator World::endAtomSelection(){
    631   return selectedAtoms.end();
    632 }
    633 
    634 
    635 World::MoleculeSelectionIterator World::beginMoleculeSelection(){
    636   return selectedMolecules.begin();
    637 }
    638 
    639 World::MoleculeSelectionIterator World::endMoleculeSelection(){
    640   return selectedMolecules.end();
    641289}
    642290
     
    649297    Thermostats(new ThermoStatContainer),
    650298    ExitFlag(0),
    651     atoms(this),
    652     selectedAtoms(this),
     299    atoms(),
    653300    currAtomId(0),
    654     lastAtomPoolSize(0),
    655     numAtomDefragSkips(0),
    656     molecules(this),
    657     selectedMolecules(this),
     301    molecules(),
    658302    currMoleculeId(0),
    659303    molecules_deprecated(new MoleculeListClass(this))
    660304{
    661   cell_size = new Box;
    662   Matrix domain;
    663   domain.at(0,0) = 20;
    664   domain.at(1,1) = 20;
    665   domain.at(2,2) = 20;
    666   cell_size->setM(domain);
     305  cell_size = new double[6];
     306  cell_size[0] = 20.;
     307  cell_size[1] = 0.;
     308  cell_size[2] = 20.;
     309  cell_size[3] = 0.;
     310  cell_size[4] = 0.;
     311  cell_size[5] = 20.;
    667312  defaultName = "none";
    668313  molecules_deprecated->signOn(this);
     
    672317{
    673318  molecules_deprecated->signOff(this);
    674   delete cell_size;
     319  delete[] cell_size;
    675320  delete molecules_deprecated;
    676321  delete periode;
Note: See TracChangeset for help on using the changeset viewer.