source: src/World.cpp@ 1cc661

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 1cc661 was 4b8630, checked in by Frederik Heber <heber@…>, 14 years ago

World::setTime() now updates bond structure of system and related changes to DipoleAngularCorrelation.

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