Changes in src/World.cpp [3839e5:b9c847]
- File:
-
- 1 edited
-
src/World.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/World.cpp
r3839e5 rb9c847 9 9 10 10 #include "World.hpp" 11 12 #include <functional>13 11 14 12 #include "atom.hpp" … … 24 22 #include "Actions/ManipulateAtomsProcess.hpp" 25 23 #include "Helpers/Assert.hpp" 26 #include "Box.hpp"27 #include "Matrix.hpp"28 #include "defs.hpp"29 24 30 25 #include "Patterns/Singleton_impl.hpp" 31 #include "Patterns/ObservedContainer_impl.hpp"32 26 33 27 using namespace std; … … 80 74 // system 81 75 82 Box& World::getDomain() { 83 return *cell_size; 84 } 85 86 void World::setDomain(const Matrix &mat){ 87 *cell_size = mat; 76 double * World::getDomain() { 77 return cell_size; 88 78 } 89 79 90 80 void World::setDomain(double * matrix) 91 81 { 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]; 94 89 } 95 90 … … 124 119 molecule *mol = NULL; 125 120 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++); 129 123 // store the molecule by ID 130 124 molecules[mol->getId()] = mol; … … 144 138 DeleteMolecule(mol); 145 139 molecules.erase(id); 146 releaseMoleculeId(id); 147 } 140 } 141 142 double *World::cell_size = NULL; 148 143 149 144 atom *World::createAtom(){ 150 145 OBSERVE; 151 146 atomId_t id = getNextAtomId(); 152 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");153 147 atom *res = NewAtom(id); 154 148 res->setWorld(this); … … 227 221 228 222 atomId_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); 239 231 return id; 240 232 } 241 // Nothing in the pool... we are out of luck242 return currAtomId++;243 233 } 244 234 245 235 void 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 } 248 243 } 249 244 250 245 bool World::reserveAtomId(atomId_t id){ 251 246 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); 255 250 } 256 251 currAtomId=id+1; 257 defragAtomIdPool();258 252 return true; 259 253 } 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 } 323 262 } 324 263 325 264 // Molecules 326 265 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 invalidating334 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 luck341 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 request360 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 here363 break;364 }365 // no need to check first, since it has to be <=id, since otherwise we would have broken out366 if(iter->second > id){367 // we found a matching range... get the id from this range368 369 // split up this range at the point of id370 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 range373 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 reserved385 return false;386 }387 388 void World::defragMoleculeIdPool(){389 // check if the situation is bad enough to make defragging neccessary390 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 one397 moleculeIdPool_t::iterator next = iter;398 next++;399 if(next!=moleculeIdPool.end() && (next->first==iter->second)){400 // merge the two ranges401 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 border413 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 424 266 /******************************* Iterators ********************************/ 425 267 426 // external parts with observers 427 268 // Build the AtomIterator from template 428 269 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor); 429 270 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 272 World::AtomIterator World::getAtomIter(AtomDescriptor descr){ 273 return AtomIterator(descr,atoms); 274 } 275 276 World::AtomIterator World::atomEnd(){ 442 277 return AtomIterator(AllAtoms(),atoms,atoms.end()); 443 278 } 444 279 280 // build the MoleculeIterator from template 445 281 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor); 446 282 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(){ 283 World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){ 284 return MoleculeIterator(descr,molecules); 285 } 286 287 World::MoleculeIterator World::moleculeEnd(){ 459 288 return MoleculeIterator(AllMolecules(),molecules,molecules.end()); 460 }461 462 // Internal parts, without observers463 464 // Build the AtomIterator from template465 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);466 467 468 World::internal_AtomIterator469 World::getAtomIter_internal(AtomDescriptor descr){470 return internal_AtomIterator(descr,atoms.getContent());471 }472 473 World::internal_AtomIterator474 World::atomEnd_internal(){475 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());476 }477 478 // build the MoleculeIterator from template479 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 // Atoms492 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 function511 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above512 }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 iterators517 const molecule *mol = _mol;518 void (World::*func)(atom*) = &World::selectAtom; // needed for type resolution of overloaded function519 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above520 }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 function541 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above542 }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 iterators547 const molecule *mol = _mol;548 void (World::*func)(atom*) = &World::unselectAtom; // needed for type resolution of overloaded function549 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unsselect... see above550 }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 // Molecules558 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 function577 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above578 }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 molecule584 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 function608 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above609 }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 molecule615 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();641 289 } 642 290 … … 649 297 Thermostats(new ThermoStatContainer), 650 298 ExitFlag(0), 651 atoms(this), 652 selectedAtoms(this), 299 atoms(), 653 300 currAtomId(0), 654 lastAtomPoolSize(0), 655 numAtomDefragSkips(0), 656 molecules(this), 657 selectedMolecules(this), 301 molecules(), 658 302 currMoleculeId(0), 659 303 molecules_deprecated(new MoleculeListClass(this)) 660 304 { 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.; 667 312 defaultName = "none"; 668 313 molecules_deprecated->signOn(this); … … 672 317 { 673 318 molecules_deprecated->signOff(this); 674 delete cell_size;319 delete[] cell_size; 675 320 delete molecules_deprecated; 676 321 delete periode;
Note:
See TracChangeset
for help on using the changeset viewer.
