source: src/World.cpp@ 2bfc5b

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 Candidate_v1.7.0 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 2bfc5b was 7f1865d, checked in by Frederik Heber <heber@…>, 10 years ago

Added template functions to (un)set vector of instances in a row.

  • Property mode set to 100644
File size: 32.5 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[5aaa43]5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
[94d5ac6]6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]22 */
23
[5d1611]24/*
25 * World.cpp
26 *
27 * Created on: Feb 3, 2010
28 * Author: crueger
29 */
30
[bf3817]31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
[ad011c]36#include "CodePatterns/MemDebug.hpp"
[112b09]37
[5d1611]38#include "World.hpp"
39
[90c4280]40#include <functional>
[5d1611]41
[3139b2]42#include "Actions/ActionTrait.hpp"
[d297a3]43#include "Actions/ManipulateAtomsProcess.hpp"
[6f0841]44#include "Atom/atom.hpp"
[d297a3]45#include "Box.hpp"
46#include "CodePatterns/Assert.hpp"
[8e1f7af]47#include "config.hpp"
[fc1b24]48#include "Descriptors/AtomDescriptor.hpp"
[865a945]49#include "Descriptors/AtomDescriptor_impl.hpp"
[c1d837]50#include "Descriptors/AtomIdDescriptor.hpp"
[ebc499]51#include "Descriptors/AtomSelectionDescriptor.hpp"
[1c51c8]52#include "Descriptors/MoleculeDescriptor.hpp"
53#include "Descriptors/MoleculeDescriptor_impl.hpp"
[c1d837]54#include "Descriptors/MoleculeIdDescriptor.hpp"
[ebc499]55#include "Descriptors/MoleculeSelectionDescriptor.hpp"
[feb5d0]56#include "Descriptors/SelectiveConstIterator_impl.hpp"
[6e97e5]57#include "Descriptors/SelectiveIterator_impl.hpp"
[42127c]58#include "Element/periodentafel.hpp"
[98dbee]59#include "Fragmentation/Homology/HomologyContainer.hpp"
[3139b2]60#include "Graph/BondGraph.hpp"
[4b8630]61#include "Graph/DepthFirstSearchAnalysis.hpp"
[e4fe8d]62#include "Helpers/defs.hpp"
[d297a3]63#include "LinearAlgebra/RealSpaceMatrix.hpp"
[4834f4]64#include "LinkedCell/LinkedCell_Controller.hpp"
65#include "LinkedCell/PointCloudAdaptor.hpp"
[d297a3]66#include "molecule.hpp"
[42127c]67#include "MoleculeListClass.hpp"
[ab26c3]68#include "Thermostats/ThermoStatContainer.hpp"
[d297a3]69#include "WorldTime.hpp"
[d346b6]70
[3e4fb6]71#include "IdPool_impl.hpp"
72
[4834f4]73#include "CodePatterns/IteratorAdaptors.hpp"
[ad011c]74#include "CodePatterns/Singleton_impl.hpp"
[02ce36]75#include "CodePatterns/Observer/Channels.hpp"
76#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
[23b547]77
[ce7fdc]78using namespace MoleCuilder;
[4d9c01]79
[7188b1]80/******************************* Notifications ************************/
81
82
83atom* World::_lastchangedatom = NULL;
[fb95a5]84atomId_t World::_lastchangedatomid = -1;
[7188b1]85molecule* World::_lastchangedmol = NULL;
[fb95a5]86moleculeId_t World::_lastchangedmolid = -1;
[7188b1]87
[5d1611]88/******************************* getter and setter ************************/
[f71baf]89periodentafel *&World::getPeriode()
90{
[5d1611]91 return periode;
92}
93
[f71baf]94BondGraph *&World::getBondGraph()
95{
96 return BG;
97}
98
[98dbee]99HomologyContainer &World::getHomologies()
100{
101 return *homologies;
102}
103
104void World::resetHomologies(HomologyContainer *&_homologies)
105{
106 HomologyContainer *oldhomologies = homologies;
107
108 // install new instance, resetting given pointer
109 homologies = _homologies;
110 _homologies = NULL;
111
112 // delete old instance which also informs all observers
113 delete oldhomologies;
114}
115
[f71baf]116void World::setBondGraph(BondGraph *_BG){
117 delete (BG);
118 BG = _BG;
119}
120
[8e1f7af]121config *&World::getConfig(){
122 return configuration;
123}
124
[1c51c8]125// Atoms
126
[7a1ce5]127atom* World::getAtom(AtomDescriptor descriptor){
[fc1b24]128 return descriptor.find();
129}
130
[795c0f]131const atom* World::getAtom(AtomDescriptor descriptor) const{
132 return const_cast<const AtomDescriptor &>(descriptor).find();
133}
134
[4d72e4]135World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
[fc1b24]136 return descriptor.findAll();
137}
138
[795c0f]139World::ConstAtomComposite World::getAllAtoms(AtomDescriptor descriptor) const {
140 return const_cast<const AtomDescriptor &>(descriptor).findAll();
141}
142
[4d72e4]143World::AtomComposite World::getAllAtoms(){
[0e2a47]144 return getAllAtoms(AllAtoms());
145}
146
[795c0f]147World::ConstAtomComposite World::getAllAtoms() const {
148 return getAllAtoms(AllAtoms());
149}
150
151int World::numAtoms() const {
[354859]152 return atoms.size();
153}
154
[1c51c8]155// Molecules
156
157molecule *World::getMolecule(MoleculeDescriptor descriptor){
158 return descriptor.find();
159}
160
[97445f]161const molecule *World::getMolecule(MoleculeDescriptor descriptor) const {
162 return const_cast<const MoleculeDescriptor &>(descriptor).find();
163}
164
[1c51c8]165std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
166 return descriptor.findAll();
167}
168
[97445f]169std::vector<const molecule*> World::getAllMolecules(MoleculeDescriptor descriptor) const {
170 return const_cast<const MoleculeDescriptor &>(descriptor).findAll();
171}
172
[97ebf8]173std::vector<molecule*> World::getAllMolecules(){
174 return getAllMolecules(AllMolecules());
175}
176
[97445f]177std::vector<const molecule*> World::getAllMolecules() const {
178 return getAllMolecules(AllMolecules());
179}
180
181int World::numMolecules() const {
[354859]182 return molecules_deprecated->ListOfMolecules.size();
183}
184
[5f612ee]185// system
186
[84c494]187Box& World::getDomain() {
188 return *cell_size;
189}
190
[cca9ef]191void World::setDomain(const RealSpaceMatrix &mat){
[be97a8]192 OBSERVE;
[84c494]193 *cell_size = mat;
[5f612ee]194}
195
196void World::setDomain(double * matrix)
197{
[b9c847]198 OBSERVE;
[cca9ef]199 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
[84c494]200 cell_size->setM(M);
[5f612ee]201}
202
[03abd0]203LinkedCell::LinkedCell_View World::getLinkedCell(double distance)
[4834f4]204{
[d067e35]205 ASSERT( distance >= 0,
[03abd0]206 "World::getLinkedCell() - distance is not positive.");
207 if (distance < 1.) {
208 ELOG(2, "Linked cell grid with length less than 1. is very memory-intense!");
209 distance = 1.;
210 }
[4834f4]211 // we have to grope past the ObservedContainer mechanism and transmorph the map
212 // into a traversable list for the adaptor
213 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
214 &(atoms.getContent()),
215 std::string("WorldsAtoms"));
216 return LCcontroller->getView(distance, atomset);
217}
218
[2a8731]219const unsigned World::getTime() const
220{
221 return WorldTime::getTime();
222}
223
[388ddd]224bool areBondsPresent(const unsigned int _step)
225{
226 bool status = false;
227
228 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
229 (!status) && (iter != const_cast<const World &>(World::getInstance()).atomEnd()); ++iter) {
230 const atom * const Walker = *iter;
231 status |= !Walker->getListOfBondsAtStep(_step).empty();
232 }
233
234 return status;
235}
236
237void copyBondgraph(const unsigned int _srcstep, const unsigned int _deststep)
238{
239 // gather all bonds from _srcstep
240 std::set<bond *> SetOfBonds;
241 for (World::AtomConstIterator iter = const_cast<const World &>(World::getInstance()).getAtomIter();
242 iter != const_cast<const World &>(World::getInstance()).atomEnd(); ++iter) {
243 const atom * const Walker = *iter;
244 const BondList bonds = Walker->getListOfBondsAtStep(_srcstep);
245 BOOST_FOREACH( bond::ptr bondptr, bonds) {
246 SetOfBonds.insert(bondptr.get());
247 }
248 }
249 LOG(4, "DEBUG: We gathered " << SetOfBonds.size() << " bonds in total.");
250
251 // copy bond to new time step
252 for (std::set<bond *>::const_iterator bonditer = SetOfBonds.begin();
253 bonditer != SetOfBonds.end(); ++bonditer) {
254 const atom * const Walker = (*bonditer)->leftatom;
255 const atom * const OtherWalker = (*bonditer)->rightatom;
[0763ce]256 bond::ptr const _bond =
257 const_cast<atom *>(Walker)->addBond(_deststep, const_cast<atom *>(OtherWalker));
258 _bond->setDegree((*bonditer)->getDegree());
[388ddd]259 }
260}
261
[d297a3]262void World::setTime(const unsigned int _step)
263{
[76163d]264 if (_step != WorldTime::getTime()) {
[388ddd]265 const unsigned int oldstep = WorldTime::getTime();
[46ce1c]266
267 // 1. copy bond graph (such not each addBond causes GUI update)
268 if (!areBondsPresent(_step)) {
269// AtomComposite Set = getAllAtoms();
270// BG->cleanAdjacencyList(Set);
271 copyBondgraph(oldstep, _step);
272 }
273
274 // 2. set new time
[040a5c]275 WorldTime::getInstance().setTime(_step);
[46ce1c]276
277 // 4. scan for connected subgraphs => molecules
[4b8630]278 DepthFirstSearchAnalysis DFS;
279 DFS();
280 DFS.UpdateMoleculeStructure();
[76163d]281 }
[d297a3]282}
283
[387b36]284std::string World::getDefaultName() {
[5f612ee]285 return defaultName;
286}
287
[387b36]288void World::setDefaultName(std::string name)
[5f612ee]289{
[be97a8]290 OBSERVE;
[387b36]291 defaultName = name;
[5f612ee]292};
293
[43dad6]294class ThermoStatContainer * World::getThermostats()
295{
296 return Thermostats;
297}
298
299
[e4b5de]300int World::getExitFlag() {
301 return ExitFlag;
302}
303
304void World::setExitFlag(int flag) {
305 if (ExitFlag < flag)
306 ExitFlag = flag;
307}
[5f612ee]308
[afb47f]309/******************** Methods to change World state *********************/
310
[354859]311molecule* World::createMolecule(){
312 OBSERVE;
313 molecule *mol = NULL;
[cbc5fb]314 mol = NewMolecule();
[3e4fb6]315 moleculeId_t id = moleculeIdPool.getNextId();
[127a8e]316 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
317 mol->setId(id);
[244d26]318 // store the molecule by ID
[cbc5fb]319 molecules[mol->getId()] = mol;
[7188b1]320 _lastchangedmol = mol;
[fb95a5]321 _lastchangedmolid = mol->getId();
[7188b1]322 NOTIFY(MoleculeInserted);
[354859]323 return mol;
324}
325
[5cf341]326molecule* World::recreateMolecule(const moleculeId_t &_id)
327{
328 molecule *mol = NULL;
329 if (!molecules.count(_id)) {
330 OBSERVE;
331 mol = NewMolecule();
332 mol->setId(_id);
333 // store the molecule by ID
334 molecules[mol->getId()] = mol;
335 _lastchangedmol = mol;
336 _lastchangedmolid = mol->getId();
337 NOTIFY(MoleculeInserted);
338 }
339 return mol;
340}
341
[cbc5fb]342void World::destroyMolecule(molecule* mol){
[fa7989]343 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
[cbc5fb]344 destroyMolecule(mol->getId());
345}
346
347void World::destroyMolecule(moleculeId_t id){
348 molecule *mol = molecules[id];
[6d574a]349 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
[38f991]350 // give notice about immediate removal
351 {
352 OBSERVE;
353 _lastchangedmol = mol;
[fb95a5]354 _lastchangedmolid = mol->getId();
[38f991]355 NOTIFY(MoleculeRemoved);
356 }
[a7aebd]357 // TODO: removed when depcreated MoleculeListClass is gone
358 molecules_deprecated->erase(mol);
[4965d9f]359 if (isMoleculeSelected(id)) {
[38f991]360 selectedMolecules.erase(id);
[4965d9f]361 NOTIFY(SelectionChanged);
362 }
[f02b53]363 DeleteMolecule(mol);
[7eec64]364 molecules.erase(id);
[3e4fb6]365 moleculeIdPool.releaseId(id);
[cbc5fb]366}
367
[46d958]368atom *World::createAtom(){
369 OBSERVE;
[3e4fb6]370 atomId_t id = atomIdPool.getNextId();
[127a8e]371 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
[88d586]372 atom *res = NewAtom(id);
[46d958]373 res->setWorld(this);
[244d26]374 // store the atom by ID
[46d958]375 atoms[res->getId()] = res;
[7188b1]376 _lastchangedatom = res;
[fb95a5]377 _lastchangedatomid = res->getId();
[7188b1]378 NOTIFY(AtomInserted);
[46d958]379 return res;
380}
381
[5cf341]382atom *World::recreateAtom(const atomId_t _id){
383 if (!atoms.count(_id)) {
384 OBSERVE;
385 atom *res = NewAtom(_id);
386 res->setWorld(this);
387 // store the atom by ID
388 atoms[res->getId()] = res;
389 _lastchangedatom = res;
390 _lastchangedatomid = res->getId();
391 NOTIFY(AtomInserted);
392 return res;
393 } else
394 return NULL;
395}
396
[5f612ee]397
[46d958]398int World::registerAtom(atom *atom){
399 OBSERVE;
[3e4fb6]400 atomId_t id = atomIdPool.getNextId();
[88d586]401 atom->setId(id);
[46d958]402 atom->setWorld(this);
403 atoms[atom->getId()] = atom;
[65d7ca]404 _lastchangedatom = atom;
[fb95a5]405 _lastchangedatomid = atom->getId();
[65d7ca]406 NOTIFY(AtomInserted);
[46d958]407 return atom->getId();
408}
409
410void World::destroyAtom(atom* atom){
411 int id = atom->getId();
412 destroyAtom(id);
413}
414
[cbc5fb]415void World::destroyAtom(atomId_t id) {
[46d958]416 atom *atom = atoms[id];
[6d574a]417 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[ab4a33]418 // give notice about immediate removal
419 {
420 OBSERVE;
421 _lastchangedatom = atom;
[fb95a5]422 _lastchangedatomid = atom->getId();
[ab4a33]423 NOTIFY(AtomRemoved);
424 }
[a7aebd]425 // check if it's the last atom
[270bdf]426 molecule *_mol = const_cast<molecule *>(atom->getMolecule());
[cad383]427 if ((_mol == NULL) || (_mol->getAtomCount() > 1))
[a7aebd]428 _mol = NULL;
[4965d9f]429 if (isAtomSelected(id)) {
[38f991]430 selectedAtoms.erase(id);
[4965d9f]431 NOTIFY(SelectionChanged);
432 }
[f02b53]433 DeleteAtom(atom);
[59e7996]434 atoms.erase(id);
[3e4fb6]435 atomIdPool.releaseId(id);
[a7aebd]436 // remove molecule if empty
437 if (_mol != NULL)
438 destroyMolecule(_mol);
[88d586]439}
440
441bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
442 OBSERVE;
443 // in case this call did not originate from inside the atom, we redirect it,
444 // to also let it know that it has changed
445 if(!target){
446 target = atoms[oldId];
[6d574a]447 ASSERT(target,"Atom with that ID not found");
[88d586]448 return target->changeId(newId);
449 }
450 else{
[3e4fb6]451 if(atomIdPool.reserveId(newId)){
[88d586]452 atoms.erase(oldId);
453 atoms.insert(pair<atomId_t,atom*>(newId,target));
454 return true;
455 }
456 else{
457 return false;
458 }
459 }
[46d958]460}
461
[a7a087]462bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
463 OBSERVE;
464 // in case this call did not originate from inside the atom, we redirect it,
465 // to also let it know that it has changed
466 if(!target){
467 target = molecules[oldId];
468 ASSERT(target,"Molecule with that ID not found");
469 return target->changeId(newId);
470 }
471 else{
[3e4fb6]472 if(moleculeIdPool.reserveId(newId)){
[a7a087]473 molecules.erase(oldId);
474 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
475 return true;
476 }
477 else{
478 return false;
479 }
480 }
481}
482
[7c4e29]483ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[3139b2]484 ActionTrait manipulateTrait(name);
[126867]485 return new ManipulateAtomsProcess(op, descr,manipulateTrait);
[7c4e29]486}
487
[0e2a47]488ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
489 return manipulateAtoms(op,name,AllAtoms());
490}
491
[afb47f]492/********************* Internal Change methods for double Callback and Observer mechanism ********/
493
494void World::doManipulate(ManipulateAtomsProcess *proc){
495 proc->signOn(this);
496 {
497 OBSERVE;
498 proc->doManipulate(this);
499 }
500 proc->signOff(this);
501}
[865a945]502/******************************* Iterators ********************************/
503
[fa0b18]504// external parts with observers
505
[feb5d0]506CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
507
508CONSTRUCT_SELECTIVE_CONST_ITERATOR(atom*,World::AtomSet,AtomDescriptor)
[6e97e5]509
[fa0b18]510World::AtomIterator
511World::getAtomIter(AtomDescriptor descr){
512 return AtomIterator(descr,atoms);
513}
[865a945]514
[feb5d0]515World::AtomConstIterator
516World::getAtomIter(AtomDescriptor descr) const{
517 return AtomConstIterator(descr,atoms);
518}
519
[fa0b18]520World::AtomIterator
521World::getAtomIter(){
522 return AtomIterator(AllAtoms(),atoms);
[865a945]523}
[354859]524
[feb5d0]525World::AtomConstIterator
526World::getAtomIter() const{
527 return AtomConstIterator(AllAtoms(),atoms);
528}
529
[fa0b18]530World::AtomIterator
531World::atomEnd(){
[6e97e5]532 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]533}
534
[feb5d0]535World::AtomConstIterator
536World::atomEnd() const{
537 return AtomConstIterator(AllAtoms(),atoms,atoms.end());
538}
539
540CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
541
542CONSTRUCT_SELECTIVE_CONST_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor)
[6e97e5]543
[5d880e]544World::MoleculeIterator
545World::getMoleculeIter(MoleculeDescriptor descr){
546 return MoleculeIterator(descr,molecules);
547}
548
[feb5d0]549World::MoleculeConstIterator
550World::getMoleculeIter(MoleculeDescriptor descr) const{
551 return MoleculeConstIterator(descr,molecules);
552}
553
[5d880e]554World::MoleculeIterator
555World::getMoleculeIter(){
556 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]557}
558
[feb5d0]559World::MoleculeConstIterator
560World::getMoleculeIter() const{
561 return MoleculeConstIterator(AllMolecules(),molecules);
562}
563
[5d880e]564World::MoleculeIterator
565World::moleculeEnd(){
[6e97e5]566 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]567}
568
[feb5d0]569World::MoleculeConstIterator
570World::moleculeEnd() const{
571 return MoleculeConstIterator(AllMolecules(),molecules,molecules.end());
572}
573
[fa0b18]574// Internal parts, without observers
575
576// Build the AtomIterator from template
577CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
578
579
580World::internal_AtomIterator
581World::getAtomIter_internal(AtomDescriptor descr){
582 return internal_AtomIterator(descr,atoms.getContent());
583}
584
585World::internal_AtomIterator
586World::atomEnd_internal(){
587 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
588}
589
[6e97e5]590// build the MoleculeIterator from template
[e3d865]591CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]592
[e3d865]593World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
594 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]595}
596
[e3d865]597World::internal_MoleculeIterator World::moleculeEnd_internal(){
598 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]599}
600
[90c4280]601/************************** Selection of Atoms and molecules ******************/
602
[7f1865d]603// translate type's selection member functions to overloaded with specific type
604
605template <class T>
606void World::selectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
607{
608 std::for_each(_begin,_end,
609 boost::bind(&World::selectInstance<typename T::value_type::second_type>,
610 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
611}
612
613template <class T>
614void World::unselectVectorOfInstances(const typename T::iterator _begin, const typename T::iterator _end)
615{
616 std::for_each(_begin,_end,
617 boost::bind(&World::unselectInstance<typename T::value_type::second_type>,
618 boost::bind(_take<typename T::value_type::second_type,typename T::value_type>::get, _1)));
619}
620
[90c4280]621// Atoms
622
623void World::clearAtomSelection(){
[69643a]624 OBSERVE;
625 NOTIFY(SelectionChanged);
[7f1865d]626 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[90c4280]627 selectedAtoms.clear();
628}
629
[ebc499]630void World::invertAtomSelection(){
631 // get all atoms not selected
632 AtomComposite invertedSelection(getAllAtoms());
633 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
634 AtomComposite::iterator iter =
635 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
636 std::bind1st(std::mem_fun(predicate), this));
637 invertedSelection.erase(iter, invertedSelection.end());
638 // apply new selection
[7f1865d]639 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[ebc499]640 selectedAtoms.clear();
641 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
642 std::for_each(invertedSelection.begin(),invertedSelection.end(),
643 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
644}
645
[cad383]646void World::popAtomSelection(){
647 OBSERVE;
648 NOTIFY(SelectionChanged);
[c1d837]649 const atomIdsVector_t atomids = selectedAtoms_Stack.top();
650 boost::function<void (const atomId_t)> IdSelector =
651 boost::bind(static_cast<void (World::*)(const atomId_t)>(&World::selectAtom), this, _1);
[7f1865d]652 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[c1d837]653 selectedAtoms.clear();
654 std::for_each(atomids.begin(),atomids.end(), IdSelector);
[cad383]655 selectedAtoms_Stack.pop();
656}
657
658void World::pushAtomSelection(){
659 OBSERVE;
660 NOTIFY(SelectionChanged);
[c1d837]661 atomIdsVector_t atomids(countSelectedAtoms(), (atomId_t)-1);
662 std::copy(
663 MapKeyIterator<AtomSelectionConstIterator>(beginAtomSelection()),
664 MapKeyIterator<AtomSelectionConstIterator>(endAtomSelection()),
665 atomids.begin());
666 selectedAtoms_Stack.push( atomids );
[7f1865d]667 unselectVectorOfInstances<AtomSet>(selectedAtoms.begin(), selectedAtoms.end());
[cad383]668 selectedAtoms.clear();
669}
670
[e4afb4]671void World::selectAtom(const atom *_atom){
[69643a]672 OBSERVE;
673 NOTIFY(SelectionChanged);
[e4afb4]674 // atom * is unchanged in this function, but we do store entity as changeable
675 ASSERT(_atom,"Invalid pointer in selection of atom");
[7f1865d]676 selectAtom(_atom->getId());
[90c4280]677}
678
[e4afb4]679void World::selectAtom(const atomId_t id){
[69643a]680 OBSERVE;
681 NOTIFY(SelectionChanged);
[90c4280]682 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
683 selectedAtoms[id]=atoms[id];
[7f1865d]684 atoms[id]->select();
[90c4280]685}
686
687void World::selectAllAtoms(AtomDescriptor descr){
[69643a]688 OBSERVE;
689 NOTIFY(SelectionChanged);
[90c4280]690 internal_AtomIterator begin = getAtomIter_internal(descr);
691 internal_AtomIterator end = atomEnd_internal();
[e4afb4]692 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]693 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
694}
695
[e4afb4]696void World::selectAtomsOfMolecule(const molecule *_mol){
[69643a]697 OBSERVE;
698 NOTIFY(SelectionChanged);
[90c4280]699 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
700 // need to make it const to get the fast iterators
701 const molecule *mol = _mol;
[e4afb4]702 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]703 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
704}
705
[e4afb4]706void World::selectAtomsOfMolecule(const moleculeId_t id){
[69643a]707 OBSERVE;
708 NOTIFY(SelectionChanged);
[90c4280]709 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
710 selectAtomsOfMolecule(molecules[id]);
711}
712
[e4afb4]713void World::unselectAtom(const atom *_atom){
[69643a]714 OBSERVE;
715 NOTIFY(SelectionChanged);
[e4afb4]716 ASSERT(_atom,"Invalid pointer in unselection of atom");
717 unselectAtom(_atom->getId());
[61d655e]718}
719
[e4afb4]720void World::unselectAtom(const atomId_t id){
[69643a]721 OBSERVE;
722 NOTIFY(SelectionChanged);
[61d655e]723 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
[7f1865d]724 atoms[id]->unselect();
[61d655e]725 selectedAtoms.erase(id);
726}
727
728void World::unselectAllAtoms(AtomDescriptor descr){
[69643a]729 OBSERVE;
730 NOTIFY(SelectionChanged);
[61d655e]731 internal_AtomIterator begin = getAtomIter_internal(descr);
732 internal_AtomIterator end = atomEnd_internal();
[e4afb4]733 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]734 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
735}
736
[e4afb4]737void World::unselectAtomsOfMolecule(const molecule *_mol){
[69643a]738 OBSERVE;
739 NOTIFY(SelectionChanged);
[61d655e]740 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
741 // need to make it const to get the fast iterators
742 const molecule *mol = _mol;
[e4afb4]743 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[992bd5]744 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
[61d655e]745}
746
[e4afb4]747void World::unselectAtomsOfMolecule(const moleculeId_t id){
[69643a]748 OBSERVE;
749 NOTIFY(SelectionChanged);
[61d655e]750 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
751 unselectAtomsOfMolecule(molecules[id]);
752}
753
[e472eab]754size_t World::countSelectedAtoms() const {
[eacc3b]755 size_t count = 0;
[e472eab]756 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]757 count++;
758 return count;
759}
760
[e4afb4]761bool World::isSelected(const atom *_atom) const {
[7f1865d]762 const bool status = isAtomSelected(_atom->getId());
763 ASSERT( status == _atom->selected,
764 "World::isSelected() - mismatch between selection state in atom "+
765 toString(_atom->getId())+" and World.");
766 return status;
[89643d]767}
768
769bool World::isAtomSelected(const atomId_t no) const {
770 return selectedAtoms.find(no) != selectedAtoms.end();
[e0e156]771}
772
[99db9b]773std::vector<atom *> World::getSelectedAtoms() {
[e472eab]774 std::vector<atom *> returnAtoms;
[99db9b]775 std::transform(
776 selectedAtoms.begin(),
777 selectedAtoms.end(),
778 back_inserter(returnAtoms),
779 _take<atom*,World::AtomSet::value_type>::get);
780 return returnAtoms;
781}
782
783std::vector<const atom *> World::getSelectedAtoms() const {
784 std::vector<const atom *> returnAtoms;
785 std::transform(
786 selectedAtoms.begin(),
787 selectedAtoms.end(),
788 back_inserter(returnAtoms),
789 _take<atom*,World::AtomSet::value_type>::get);
[e472eab]790 return returnAtoms;
791}
792
[143263]793std::vector<atomId_t> World::getSelectedAtomIds() const {
794 std::vector<atomId_t> returnAtomIds;
795 std::transform(
796 selectedAtoms.begin(),
797 selectedAtoms.end(),
798 back_inserter(returnAtomIds),
799 _take<atom*,World::AtomSet::value_type>::getKey);
800 return returnAtomIds;
801}
[e472eab]802
[90c4280]803// Molecules
804
805void World::clearMoleculeSelection(){
[69643a]806 OBSERVE;
807 NOTIFY(SelectionChanged);
[7f1865d]808 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[90c4280]809 selectedMolecules.clear();
810}
811
[ebc499]812void World::invertMoleculeSelection(){
813 // get all molecules not selected
814 typedef std::vector<molecule *> MoleculeVector_t;
815 MoleculeVector_t invertedSelection(getAllMolecules());
816 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
817 MoleculeVector_t::iterator iter =
818 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
819 std::bind1st(std::mem_fun(predicate), this));
820 invertedSelection.erase(iter, invertedSelection.end());
821 // apply new selection
[7f1865d]822 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[ebc499]823 selectedMolecules.clear();
824 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
825 std::for_each(invertedSelection.begin(),invertedSelection.end(),
826 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
827}
828
[cad383]829void World::popMoleculeSelection(){
830 OBSERVE;
831 NOTIFY(SelectionChanged);
[c1d837]832 const moleculeIdsVector_t moleculeids = selectedMolecules_Stack.top();
833 boost::function<void (const moleculeId_t)> IdSelector =
834 boost::bind(static_cast<void (World::*)(const moleculeId_t)>(&World::selectMolecule), this, _1);
[7f1865d]835 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[c1d837]836 selectedMolecules.clear();
837 std::for_each(moleculeids.begin(),moleculeids.end(), IdSelector);
[cad383]838 selectedMolecules_Stack.pop();
839}
840
841void World::pushMoleculeSelection(){
842 OBSERVE;
843 NOTIFY(SelectionChanged);
[c1d837]844 moleculeIdsVector_t moleculeids(countSelectedMolecules(), (moleculeId_t)-1);
845 boost::function<moleculeId_t (const molecule*)> IdRetriever =
846 boost::bind(&molecule::getId, _1);
847 std::copy(
848 MapKeyIterator<MoleculeSelectionConstIterator>(beginMoleculeSelection()),
849 MapKeyIterator<MoleculeSelectionConstIterator>(endMoleculeSelection()),
850 moleculeids.begin());
851 selectedMolecules_Stack.push( moleculeids );
[7f1865d]852 unselectVectorOfInstances<MoleculeSet>(selectedMolecules.begin(), selectedMolecules.end());
[cad383]853 selectedMolecules.clear();
854}
855
[e4afb4]856void World::selectMolecule(const molecule *_mol){
[69643a]857 OBSERVE;
858 NOTIFY(SelectionChanged);
[e4afb4]859 // molecule * is unchanged in this function, but we do store entity as changeable
860 ASSERT(_mol,"Invalid pointer to molecule in selection");
[7f1865d]861 selectMolecule(_mol->getId());
[90c4280]862}
863
[e4afb4]864void World::selectMolecule(const moleculeId_t id){
[69643a]865 OBSERVE;
866 NOTIFY(SelectionChanged);
[90c4280]867 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
[7f1865d]868 molecules[id]->select();
[90c4280]869 selectedMolecules[id]=molecules[id];
870}
871
[e472eab]872void World::selectAllMolecules(MoleculeDescriptor descr){
[69643a]873 OBSERVE;
874 NOTIFY(SelectionChanged);
[90c4280]875 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
876 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]877 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]878 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
879}
880
[e4afb4]881void World::selectMoleculeOfAtom(const atom *_atom){
[69643a]882 OBSERVE;
883 NOTIFY(SelectionChanged);
[e4afb4]884 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
[270bdf]885 const molecule *mol=_atom->getMolecule();
[90c4280]886 // the atom might not be part of a molecule
887 if(mol){
888 selectMolecule(mol);
889 }
890}
891
[e4afb4]892void World::selectMoleculeOfAtom(const atomId_t id){
[69643a]893 OBSERVE;
894 NOTIFY(SelectionChanged);
[90c4280]895 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
896 selectMoleculeOfAtom(atoms[id]);
897}
898
[e4afb4]899void World::unselectMolecule(const molecule *_mol){
[69643a]900 OBSERVE;
901 NOTIFY(SelectionChanged);
[e4afb4]902 ASSERT(_mol,"invalid pointer in unselection of molecule");
903 unselectMolecule(_mol->getId());
[61d655e]904}
905
[e4afb4]906void World::unselectMolecule(const moleculeId_t id){
[69643a]907 OBSERVE;
908 NOTIFY(SelectionChanged);
[61d655e]909 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
[7f1865d]910 molecules[id]->unselect();
[61d655e]911 selectedMolecules.erase(id);
912}
913
[e472eab]914void World::unselectAllMolecules(MoleculeDescriptor descr){
[69643a]915 OBSERVE;
916 NOTIFY(SelectionChanged);
[61d655e]917 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
918 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]919 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]920 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
921}
922
[e4afb4]923void World::unselectMoleculeOfAtom(const atom *_atom){
[69643a]924 OBSERVE;
925 NOTIFY(SelectionChanged);
[e4afb4]926 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
[270bdf]927 const molecule *mol=_atom->getMolecule();
[61d655e]928 // the atom might not be part of a molecule
929 if(mol){
930 unselectMolecule(mol);
931 }
932}
933
[e4afb4]934void World::unselectMoleculeOfAtom(const atomId_t id){
[69643a]935 OBSERVE;
936 NOTIFY(SelectionChanged);
[61d655e]937 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
938 unselectMoleculeOfAtom(atoms[id]);
939}
940
[e472eab]941size_t World::countSelectedMolecules() const {
[eacc3b]942 size_t count = 0;
[e472eab]943 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]944 count++;
945 return count;
946}
947
[e4afb4]948bool World::isSelected(const molecule *_mol) const {
[7f1865d]949 const bool status = isMoleculeSelected(_mol->getId());
950 ASSERT( status == _mol->selected,
951 "World::isSelected() - mismatch in selection status between mol "+
952 toString(_mol->getId())+" and World.");
953 return status;
[89643d]954}
955
956bool World::isMoleculeSelected(const moleculeId_t no) const {
957 return selectedMolecules.find(no) != selectedMolecules.end();
[e0e156]958}
959
[97445f]960std::vector<molecule *> World::getSelectedMolecules() {
[e472eab]961 std::vector<molecule *> returnMolecules;
[97445f]962 std::transform(
963 selectedMolecules.begin(),
964 selectedMolecules.end(),
965 back_inserter(returnMolecules),
966 _take<molecule*,World::MoleculeSet::value_type>::get);
967 return returnMolecules;
968}
969
970std::vector<const molecule *> World::getSelectedMolecules() const {
971 std::vector<const molecule *> returnMolecules;
972 std::transform(
973 selectedMolecules.begin(),
974 selectedMolecules.end(),
975 back_inserter(returnMolecules),
976 _take<molecule*,World::MoleculeSet::value_type>::get);
[e472eab]977 return returnMolecules;
978}
979
[143263]980std::vector<moleculeId_t> World::getSelectedMoleculeIds() const {
981 std::vector<moleculeId_t> returnMoleculeIds;
982 std::transform(
983 selectedMolecules.begin(),
984 selectedMolecules.end(),
985 back_inserter(returnMoleculeIds),
986 _take<molecule*,World::MoleculeSet::value_type>::getKey);
987 return returnMoleculeIds;
988}
989
[3839e5]990/******************* Iterators over Selection *****************************/
991World::AtomSelectionIterator World::beginAtomSelection(){
992 return selectedAtoms.begin();
993}
994
995World::AtomSelectionIterator World::endAtomSelection(){
996 return selectedAtoms.end();
997}
998
[38f991]999World::AtomSelectionConstIterator World::beginAtomSelection() const{
1000 return selectedAtoms.begin();
1001}
1002
1003World::AtomSelectionConstIterator World::endAtomSelection() const{
1004 return selectedAtoms.end();
1005}
1006
[3839e5]1007
1008World::MoleculeSelectionIterator World::beginMoleculeSelection(){
1009 return selectedMolecules.begin();
1010}
1011
1012World::MoleculeSelectionIterator World::endMoleculeSelection(){
1013 return selectedMolecules.end();
1014}
1015
[38f991]1016World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
1017 return selectedMolecules.begin();
1018}
1019
1020World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
1021 return selectedMolecules.end();
1022}
1023
[5d1611]1024/******************************* Singleton Stuff **************************/
1025
[7a1ce5]1026World::World() :
[cd5047]1027 Observable("World"),
[f71baf]1028 BG(new BondGraph(true)), // assume Angstroem for the moment
[4ae823]1029 periode(new periodentafel(true)),
[8e1f7af]1030 configuration(new config),
[98dbee]1031 homologies(new HomologyContainer()),
[43dad6]1032 Thermostats(new ThermoStatContainer),
[e4b5de]1033 ExitFlag(0),
[fa0b18]1034 atoms(this),
[90c4280]1035 selectedAtoms(this),
[3e4fb6]1036 atomIdPool(0, 20, 100),
[51be2a]1037 molecules(this),
[90c4280]1038 selectedMolecules(this),
[3e4fb6]1039 moleculeIdPool(0, 20,100),
[24a5e0]1040 molecules_deprecated(new MoleculeListClass(this))
[7dad10]1041{
[84c494]1042 cell_size = new Box;
[cca9ef]1043 RealSpaceMatrix domain;
[84c494]1044 domain.at(0,0) = 20;
1045 domain.at(1,1) = 20;
1046 domain.at(2,2) = 20;
1047 cell_size->setM(domain);
[4834f4]1048 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
[387b36]1049 defaultName = "none";
[02ce36]1050 Channels *OurChannel = new Channels;
[574d377]1051 Observable::insertNotificationChannel( std::make_pair( static_cast<Observable *>(this), OurChannel) );
[7188b1]1052 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
[02ce36]1053 OurChannel->addChannel(type);
[7dad10]1054}
[5d1611]1055
1056World::~World()
[354859]1057{
[4834f4]1058 delete LCcontroller;
[84c494]1059 delete cell_size;
[46d958]1060 delete molecules_deprecated;
[cbc5fb]1061 MoleculeSet::iterator molIter;
1062 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
1063 DeleteMolecule((*molIter).second);
1064 }
1065 molecules.clear();
1066 AtomSet::iterator atIter;
1067 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
1068 DeleteAtom((*atIter).second);
[46d958]1069 }
1070 atoms.clear();
[7188b1]1071
[f71baf]1072 delete BG;
[6cb9c76]1073 delete periode;
1074 delete configuration;
1075 delete Thermostats;
[09f615]1076 delete homologies;
[354859]1077}
[5d1611]1078
[23b547]1079// Explicit instantiation of the singleton mechanism at this point
[5d1611]1080
[3e4fb6]1081// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
[b97a60]1082CONSTRUCT_IDPOOL(atomId_t, uniqueId)
1083CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
[3e4fb6]1084
[23b547]1085CONSTRUCT_SINGLETON(World)
[5d1611]1086
[e2c2b1]1087CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet, UnobservedIterator<World::AtomSTLSet> )
[5f1d5b8]1088
[e2c2b1]1089CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet, UnobservedIterator<World::MoleculeSTLSet> )
[5f1d5b8]1090
[5d1611]1091/******************************* deprecated Legacy Stuff ***********************/
1092
[354859]1093MoleculeListClass *&World::getMolecules() {
1094 return molecules_deprecated;
[5d1611]1095}
Note: See TracBrowser for help on using the repository browser.