Changes in src/World.cpp [b9c847:3839e5]
- File:
-
- 1 edited
-
src/World.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/World.cpp
rb9c847 r3839e5 9 9 10 10 #include "World.hpp" 11 12 #include <functional> 11 13 12 14 #include "atom.hpp" … … 22 24 #include "Actions/ManipulateAtomsProcess.hpp" 23 25 #include "Helpers/Assert.hpp" 26 #include "Box.hpp" 27 #include "Matrix.hpp" 28 #include "defs.hpp" 24 29 25 30 #include "Patterns/Singleton_impl.hpp" 31 #include "Patterns/ObservedContainer_impl.hpp" 26 32 27 33 using namespace std; … … 74 80 // system 75 81 76 double * World::getDomain() { 77 return cell_size; 82 Box& World::getDomain() { 83 return *cell_size; 84 } 85 86 void World::setDomain(const Matrix &mat){ 87 *cell_size = mat; 78 88 } 79 89 80 90 void World::setDomain(double * matrix) 81 91 { 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]; 92 Matrix M = ReturnFullMatrixforSymmetric(matrix); 93 cell_size->setM(M); 89 94 } 90 95 … … 119 124 molecule *mol = NULL; 120 125 mol = NewMolecule(); 121 ASSERT(!molecules.count(currMoleculeId),"currMoleculeId did not specify an unused ID"); 122 mol->setId(currMoleculeId++); 126 moleculeId_t id = getNextMoleculeId(); 127 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID"); 128 mol->setId(id); 123 129 // store the molecule by ID 124 130 molecules[mol->getId()] = mol; … … 138 144 DeleteMolecule(mol); 139 145 molecules.erase(id); 140 } 141 142 double *World::cell_size = NULL; 146 releaseMoleculeId(id); 147 } 143 148 144 149 atom *World::createAtom(){ 145 150 OBSERVE; 146 151 atomId_t id = getNextAtomId(); 152 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID"); 147 153 atom *res = NewAtom(id); 148 154 res->setWorld(this); … … 221 227 222 228 atomId_t World::getNextAtomId(){ 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); 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 } 231 239 return id; 232 240 } 241 // Nothing in the pool... we are out of luck 242 return currAtomId++; 233 243 } 234 244 235 245 void World::releaseAtomId(atomId_t id){ 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 } 246 atomIdPool.insert(make_pair(id,id+1)); 247 defragAtomIdPool(); 243 248 } 244 249 245 250 bool World::reserveAtomId(atomId_t id){ 246 251 if(id>=currAtomId ){ 247 // add all ids between the new one and current border as available248 for(atomId_t pos=currAtomId; pos<id; ++pos){249 atomIdPool.insert( pos);252 pair<atomId_t,atomId_t> newRange = make_pair(currAtomId,id); 253 if(newRange.first<newRange.second){ 254 atomIdPool.insert(newRange); 250 255 } 251 256 currAtomId=id+1; 257 defragAtomIdPool(); 252 258 return true; 253 259 } 254 else if(atomIdPool.count(id)){ 255 atomIdPool.erase(id); 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; 323 } 324 325 // Molecules 326 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(); 256 357 return true; 257 358 } 258 else{ 259 // this ID could not be reserved 260 return false; 261 } 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 424 /******************************* Iterators ********************************/ 425 426 // external parts with observers 427 428 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor); 429 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(){ 442 return AtomIterator(AllAtoms(),atoms,atoms.end()); 443 } 444 445 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor); 446 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(){ 459 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]); 262 555 } 263 556 264 557 // Molecules 265 558 266 /******************************* Iterators ********************************/ 267 268 // Build the AtomIterator from template 269 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor); 270 271 272 World::AtomIterator World::getAtomIter(AtomDescriptor descr){ 273 return AtomIterator(descr,atoms); 274 } 275 276 World::AtomIterator World::atomEnd(){ 277 return AtomIterator(AllAtoms(),atoms,atoms.end()); 278 } 279 280 // build the MoleculeIterator from template 281 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor); 282 283 World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){ 284 return MoleculeIterator(descr,molecules); 285 } 286 287 World::MoleculeIterator World::moleculeEnd(){ 288 return MoleculeIterator(AllMolecules(),molecules,molecules.end()); 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(); 289 641 } 290 642 … … 297 649 Thermostats(new ThermoStatContainer), 298 650 ExitFlag(0), 299 atoms(), 651 atoms(this), 652 selectedAtoms(this), 300 653 currAtomId(0), 301 molecules(), 654 lastAtomPoolSize(0), 655 numAtomDefragSkips(0), 656 molecules(this), 657 selectedMolecules(this), 302 658 currMoleculeId(0), 303 659 molecules_deprecated(new MoleculeListClass(this)) 304 660 { 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.; 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); 312 667 defaultName = "none"; 313 668 molecules_deprecated->signOn(this); … … 317 672 { 318 673 molecules_deprecated->signOff(this); 319 delete []cell_size;674 delete cell_size; 320 675 delete molecules_deprecated; 321 676 delete periode;
Note:
See TracChangeset
for help on using the changeset viewer.
