source: src/World.cpp@ 15463a

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 15463a was 03abd0, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: World::getLinkedCell() does not allow distance less than 1.

  • small distances make the linked cell approach very memory-intense, we now give a warning and set it to at least 1. Also asserting that it is positive.
  • Property mode set to 100644
File size: 23.2 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.
[94d5ac6]5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]21 */
22
[5d1611]23/*
24 * World.cpp
25 *
26 * Created on: Feb 3, 2010
27 * Author: crueger
28 */
29
[bf3817]30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
[ad011c]35#include "CodePatterns/MemDebug.hpp"
[112b09]36
[5d1611]37#include "World.hpp"
38
[90c4280]39#include <functional>
[5d1611]40
[3139b2]41#include "Actions/ActionTrait.hpp"
[d297a3]42#include "Actions/ManipulateAtomsProcess.hpp"
[6f0841]43#include "Atom/atom.hpp"
[5dfabd]44#include "Atom/AtomObserver.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"
[ebc499]50#include "Descriptors/AtomSelectionDescriptor.hpp"
[1c51c8]51#include "Descriptors/MoleculeDescriptor.hpp"
52#include "Descriptors/MoleculeDescriptor_impl.hpp"
[ebc499]53#include "Descriptors/MoleculeSelectionDescriptor.hpp"
[6e97e5]54#include "Descriptors/SelectiveIterator_impl.hpp"
[42127c]55#include "Element/periodentafel.hpp"
[3139b2]56#include "Graph/BondGraph.hpp"
[4b8630]57#include "Graph/DepthFirstSearchAnalysis.hpp"
[e4fe8d]58#include "Helpers/defs.hpp"
[d297a3]59#include "LinearAlgebra/RealSpaceMatrix.hpp"
[4834f4]60#include "LinkedCell/LinkedCell_Controller.hpp"
61#include "LinkedCell/PointCloudAdaptor.hpp"
[d297a3]62#include "molecule.hpp"
[42127c]63#include "MoleculeListClass.hpp"
[ab26c3]64#include "Thermostats/ThermoStatContainer.hpp"
[d297a3]65#include "WorldTime.hpp"
[d346b6]66
[3e4fb6]67#include "IdPool_impl.hpp"
68
[4834f4]69#include "CodePatterns/IteratorAdaptors.hpp"
[ad011c]70#include "CodePatterns/Singleton_impl.hpp"
[02ce36]71#include "CodePatterns/Observer/Channels.hpp"
72#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
[23b547]73
[ce7fdc]74using namespace MoleCuilder;
[4d9c01]75
[7188b1]76/******************************* Notifications ************************/
77
78
79atom* World::_lastchangedatom = NULL;
80molecule* World::_lastchangedmol = NULL;
81
[5d1611]82/******************************* getter and setter ************************/
[f71baf]83periodentafel *&World::getPeriode()
84{
[5d1611]85 return periode;
86}
87
[f71baf]88BondGraph *&World::getBondGraph()
89{
90 return BG;
91}
92
93void World::setBondGraph(BondGraph *_BG){
94 delete (BG);
95 BG = _BG;
96}
97
[8e1f7af]98config *&World::getConfig(){
99 return configuration;
100}
101
[1c51c8]102// Atoms
103
[7a1ce5]104atom* World::getAtom(AtomDescriptor descriptor){
[fc1b24]105 return descriptor.find();
106}
107
[4d72e4]108World::AtomComposite World::getAllAtoms(AtomDescriptor descriptor){
[fc1b24]109 return descriptor.findAll();
110}
111
[4d72e4]112World::AtomComposite World::getAllAtoms(){
[0e2a47]113 return getAllAtoms(AllAtoms());
114}
115
[354859]116int World::numAtoms(){
117 return atoms.size();
118}
119
[1c51c8]120// Molecules
121
122molecule *World::getMolecule(MoleculeDescriptor descriptor){
123 return descriptor.find();
124}
125
126std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
127 return descriptor.findAll();
128}
129
[97ebf8]130std::vector<molecule*> World::getAllMolecules(){
131 return getAllMolecules(AllMolecules());
132}
133
[354859]134int World::numMolecules(){
135 return molecules_deprecated->ListOfMolecules.size();
136}
137
[5f612ee]138// system
139
[84c494]140Box& World::getDomain() {
141 return *cell_size;
142}
143
[cca9ef]144void World::setDomain(const RealSpaceMatrix &mat){
[be97a8]145 OBSERVE;
[84c494]146 *cell_size = mat;
[5f612ee]147}
148
149void World::setDomain(double * matrix)
150{
[b9c847]151 OBSERVE;
[cca9ef]152 RealSpaceMatrix M = ReturnFullMatrixforSymmetric(matrix);
[84c494]153 cell_size->setM(M);
[5f612ee]154}
155
[03abd0]156LinkedCell::LinkedCell_View World::getLinkedCell(double distance)
[4834f4]157{
[03abd0]158 ASSERT( distance > 0,
159 "World::getLinkedCell() - distance is not positive.");
160 if (distance < 1.) {
161 ELOG(2, "Linked cell grid with length less than 1. is very memory-intense!");
162 distance = 1.;
163 }
[4834f4]164 // we have to grope past the ObservedContainer mechanism and transmorph the map
165 // into a traversable list for the adaptor
166 PointCloudAdaptor< AtomSet::set_t, MapValueIterator<AtomSet::set_t::iterator> > atomset(
167 &(atoms.getContent()),
168 std::string("WorldsAtoms"));
169 return LCcontroller->getView(distance, atomset);
170}
171
[d297a3]172void World::setTime(const unsigned int _step)
173{
[76163d]174 if (_step != WorldTime::getTime()) {
175 // set new time
[040a5c]176 WorldTime::getInstance().setTime(_step);
[4b8630]177 // TODO: removed when BondGraph creates the adjacency
178 // 1. remove all of World's molecules
179 for (MoleculeIterator iter = getMoleculeIter();
180 getMoleculeIter() != moleculeEnd();
181 iter = getMoleculeIter()) {
182 getMolecules()->erase(*iter);
183 destroyMolecule(*iter);
184 }
185 // 2. (re-)create bondgraph
186 AtomComposite Set = getAllAtoms();
187 BG->CreateAdjacency(Set);
188
189 // 3. scan for connected subgraphs => molecules
190 DepthFirstSearchAnalysis DFS;
191 DFS();
192 DFS.UpdateMoleculeStructure();
[76163d]193 }
[d297a3]194}
195
[387b36]196std::string World::getDefaultName() {
[5f612ee]197 return defaultName;
198}
199
[387b36]200void World::setDefaultName(std::string name)
[5f612ee]201{
[be97a8]202 OBSERVE;
[387b36]203 defaultName = name;
[5f612ee]204};
205
[43dad6]206class ThermoStatContainer * World::getThermostats()
207{
208 return Thermostats;
209}
210
211
[e4b5de]212int World::getExitFlag() {
213 return ExitFlag;
214}
215
216void World::setExitFlag(int flag) {
217 if (ExitFlag < flag)
218 ExitFlag = flag;
219}
[5f612ee]220
[afb47f]221/******************** Methods to change World state *********************/
222
[354859]223molecule* World::createMolecule(){
224 OBSERVE;
225 molecule *mol = NULL;
[cbc5fb]226 mol = NewMolecule();
[3e4fb6]227 moleculeId_t id = moleculeIdPool.getNextId();
[127a8e]228 ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
229 mol->setId(id);
[244d26]230 // store the molecule by ID
[cbc5fb]231 molecules[mol->getId()] = mol;
[354859]232 mol->signOn(this);
[7188b1]233 _lastchangedmol = mol;
234 NOTIFY(MoleculeInserted);
[354859]235 return mol;
236}
237
[cbc5fb]238void World::destroyMolecule(molecule* mol){
239 OBSERVE;
[fa7989]240 ASSERT(mol,"Molecule that was meant to be destroyed did not exist");
[cbc5fb]241 destroyMolecule(mol->getId());
242}
243
244void World::destroyMolecule(moleculeId_t id){
245 molecule *mol = molecules[id];
[6d574a]246 ASSERT(mol,"Molecule id that was meant to be destroyed did not exist");
[38f991]247 // give notice about immediate removal
248 {
249 OBSERVE;
250 _lastchangedmol = mol;
251 NOTIFY(MoleculeRemoved);
252 }
[7d82a5]253 mol->signOff(this);
[cbc5fb]254 DeleteMolecule(mol);
[38f991]255 if (isMoleculeSelected(id))
256 selectedMolecules.erase(id);
[cbc5fb]257 molecules.erase(id);
[3e4fb6]258 moleculeIdPool.releaseId(id);
[cbc5fb]259}
260
[46d958]261atom *World::createAtom(){
262 OBSERVE;
[3e4fb6]263 atomId_t id = atomIdPool.getNextId();
[127a8e]264 ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
[88d586]265 atom *res = NewAtom(id);
[46d958]266 res->setWorld(this);
[5dfabd]267 // sign on to global atom change tracker
268 AtomObserver::getInstance().AtomInserted(res);
[244d26]269 // store the atom by ID
[46d958]270 atoms[res->getId()] = res;
[7188b1]271 _lastchangedatom = res;
272 NOTIFY(AtomInserted);
[46d958]273 return res;
274}
275
[5f612ee]276
[46d958]277int World::registerAtom(atom *atom){
278 OBSERVE;
[3e4fb6]279 atomId_t id = atomIdPool.getNextId();
[88d586]280 atom->setId(id);
[46d958]281 atom->setWorld(this);
282 atoms[atom->getId()] = atom;
[65d7ca]283 _lastchangedatom = atom;
284 NOTIFY(AtomInserted);
[46d958]285 return atom->getId();
286}
287
288void World::destroyAtom(atom* atom){
289 int id = atom->getId();
290 destroyAtom(id);
291}
292
[cbc5fb]293void World::destroyAtom(atomId_t id) {
[46d958]294 atom *atom = atoms[id];
[6d574a]295 ASSERT(atom,"Atom ID that was meant to be destroyed did not exist");
[ab4a33]296 // give notice about immediate removal
297 {
298 OBSERVE;
299 _lastchangedatom = atom;
300 NOTIFY(AtomRemoved);
301 }
[46d958]302 DeleteAtom(atom);
[38f991]303 if (isAtomSelected(id))
304 selectedAtoms.erase(id);
[46d958]305 atoms.erase(id);
[3e4fb6]306 atomIdPool.releaseId(id);
[88d586]307}
308
309bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
310 OBSERVE;
311 // in case this call did not originate from inside the atom, we redirect it,
312 // to also let it know that it has changed
313 if(!target){
314 target = atoms[oldId];
[6d574a]315 ASSERT(target,"Atom with that ID not found");
[88d586]316 return target->changeId(newId);
317 }
318 else{
[3e4fb6]319 if(atomIdPool.reserveId(newId)){
[88d586]320 atoms.erase(oldId);
321 atoms.insert(pair<atomId_t,atom*>(newId,target));
322 return true;
323 }
324 else{
325 return false;
326 }
327 }
[46d958]328}
329
[a7a087]330bool World::changeMoleculeId(moleculeId_t oldId, moleculeId_t newId, molecule* target){
331 OBSERVE;
332 // in case this call did not originate from inside the atom, we redirect it,
333 // to also let it know that it has changed
334 if(!target){
335 target = molecules[oldId];
336 ASSERT(target,"Molecule with that ID not found");
337 return target->changeId(newId);
338 }
339 else{
[3e4fb6]340 if(moleculeIdPool.reserveId(newId)){
[a7a087]341 molecules.erase(oldId);
342 molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
343 return true;
344 }
345 else{
346 return false;
347 }
348 }
349}
350
[7c4e29]351ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
[3139b2]352 ActionTrait manipulateTrait(name);
[e4afb4]353 return new ManipulateAtomsProcess(op, descr,manipulateTrait,false);
[7c4e29]354}
355
[0e2a47]356ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
357 return manipulateAtoms(op,name,AllAtoms());
358}
359
[afb47f]360/********************* Internal Change methods for double Callback and Observer mechanism ********/
361
362void World::doManipulate(ManipulateAtomsProcess *proc){
363 proc->signOn(this);
364 {
365 OBSERVE;
366 proc->doManipulate(this);
367 }
368 proc->signOff(this);
369}
[865a945]370/******************************* Iterators ********************************/
371
[fa0b18]372// external parts with observers
373
[6e97e5]374CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
375
[fa0b18]376World::AtomIterator
377World::getAtomIter(AtomDescriptor descr){
378 return AtomIterator(descr,atoms);
379}
[865a945]380
[fa0b18]381World::AtomIterator
382World::getAtomIter(){
383 return AtomIterator(AllAtoms(),atoms);
[865a945]384}
[354859]385
[fa0b18]386World::AtomIterator
387World::atomEnd(){
[6e97e5]388 return AtomIterator(AllAtoms(),atoms,atoms.end());
[7c4e29]389}
390
[6e97e5]391CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
392
[5d880e]393World::MoleculeIterator
394World::getMoleculeIter(MoleculeDescriptor descr){
395 return MoleculeIterator(descr,molecules);
396}
397
398World::MoleculeIterator
399World::getMoleculeIter(){
400 return MoleculeIterator(AllMolecules(),molecules);
[1c51c8]401}
402
[5d880e]403World::MoleculeIterator
404World::moleculeEnd(){
[6e97e5]405 return MoleculeIterator(AllMolecules(),molecules,molecules.end());
[1c51c8]406}
407
[fa0b18]408// Internal parts, without observers
409
410// Build the AtomIterator from template
411CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet::set_t,AtomDescriptor);
412
413
414World::internal_AtomIterator
415World::getAtomIter_internal(AtomDescriptor descr){
416 return internal_AtomIterator(descr,atoms.getContent());
417}
418
419World::internal_AtomIterator
420World::atomEnd_internal(){
421 return internal_AtomIterator(AllAtoms(),atoms.getContent(),atoms.end_internal());
422}
423
[6e97e5]424// build the MoleculeIterator from template
[e3d865]425CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet::set_t,MoleculeDescriptor);
[6e97e5]426
[e3d865]427World::internal_MoleculeIterator World::getMoleculeIter_internal(MoleculeDescriptor descr){
428 return internal_MoleculeIterator(descr,molecules.getContent());
[1c51c8]429}
430
[e3d865]431World::internal_MoleculeIterator World::moleculeEnd_internal(){
432 return internal_MoleculeIterator(AllMolecules(),molecules.getContent(),molecules.end_internal());
[1c51c8]433}
434
[90c4280]435/************************** Selection of Atoms and molecules ******************/
436
437// Atoms
438
439void World::clearAtomSelection(){
[69643a]440 OBSERVE;
441 NOTIFY(SelectionChanged);
[90c4280]442 selectedAtoms.clear();
443}
444
[ebc499]445void World::invertAtomSelection(){
446 // get all atoms not selected
447 AtomComposite invertedSelection(getAllAtoms());
448 bool (World::*predicate)(const atom*) const = &World::isSelected; // needed for type resolution of overloaded function
449 AtomComposite::iterator iter =
450 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
451 std::bind1st(std::mem_fun(predicate), this));
452 invertedSelection.erase(iter, invertedSelection.end());
453 // apply new selection
454 selectedAtoms.clear();
455 void (World::*selector)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
456 std::for_each(invertedSelection.begin(),invertedSelection.end(),
457 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
458}
459
[e4afb4]460void World::selectAtom(const atom *_atom){
[69643a]461 OBSERVE;
462 NOTIFY(SelectionChanged);
[e4afb4]463 // atom * is unchanged in this function, but we do store entity as changeable
464 ASSERT(_atom,"Invalid pointer in selection of atom");
465 selectedAtoms[_atom->getId()]=const_cast<atom *>(_atom);
[90c4280]466}
467
[e4afb4]468void World::selectAtom(const atomId_t id){
[69643a]469 OBSERVE;
470 NOTIFY(SelectionChanged);
[90c4280]471 ASSERT(atoms.count(id),"Atom Id selected that was not in the world");
472 selectedAtoms[id]=atoms[id];
473}
474
475void World::selectAllAtoms(AtomDescriptor descr){
[69643a]476 OBSERVE;
477 NOTIFY(SelectionChanged);
[90c4280]478 internal_AtomIterator begin = getAtomIter_internal(descr);
479 internal_AtomIterator end = atomEnd_internal();
[e4afb4]480 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]481 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
482}
483
[e4afb4]484void World::selectAtomsOfMolecule(const molecule *_mol){
[69643a]485 OBSERVE;
486 NOTIFY(SelectionChanged);
[90c4280]487 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
488 // need to make it const to get the fast iterators
489 const molecule *mol = _mol;
[e4afb4]490 void (World::*func)(const atom*) = &World::selectAtom; // needed for type resolution of overloaded function
[90c4280]491 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is select... see above
492}
493
[e4afb4]494void World::selectAtomsOfMolecule(const moleculeId_t id){
[69643a]495 OBSERVE;
496 NOTIFY(SelectionChanged);
[90c4280]497 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
498 selectAtomsOfMolecule(molecules[id]);
499}
500
[e4afb4]501void World::unselectAtom(const atom *_atom){
[69643a]502 OBSERVE;
503 NOTIFY(SelectionChanged);
[e4afb4]504 ASSERT(_atom,"Invalid pointer in unselection of atom");
505 unselectAtom(_atom->getId());
[61d655e]506}
507
[e4afb4]508void World::unselectAtom(const atomId_t id){
[69643a]509 OBSERVE;
510 NOTIFY(SelectionChanged);
[61d655e]511 ASSERT(atoms.count(id),"Atom Id unselected that was not in the world");
512 selectedAtoms.erase(id);
513}
514
515void World::unselectAllAtoms(AtomDescriptor descr){
[69643a]516 OBSERVE;
517 NOTIFY(SelectionChanged);
[61d655e]518 internal_AtomIterator begin = getAtomIter_internal(descr);
519 internal_AtomIterator end = atomEnd_internal();
[e4afb4]520 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[61d655e]521 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
522}
523
[e4afb4]524void World::unselectAtomsOfMolecule(const molecule *_mol){
[69643a]525 OBSERVE;
526 NOTIFY(SelectionChanged);
[61d655e]527 ASSERT(_mol,"Invalid pointer to molecule in selection of Atoms of Molecule");
528 // need to make it const to get the fast iterators
529 const molecule *mol = _mol;
[e4afb4]530 void (World::*func)(const atom*) = &World::unselectAtom; // needed for type resolution of overloaded function
[992bd5]531 for_each(mol->begin(),mol->end(),bind1st(mem_fun(func),this)); // func is unselect... see above
[61d655e]532}
533
[e4afb4]534void World::unselectAtomsOfMolecule(const moleculeId_t id){
[69643a]535 OBSERVE;
536 NOTIFY(SelectionChanged);
[61d655e]537 ASSERT(molecules.count(id),"No molecule with the given id upon Selection of atoms from molecule");
538 unselectAtomsOfMolecule(molecules[id]);
539}
540
[e472eab]541size_t World::countSelectedAtoms() const {
[eacc3b]542 size_t count = 0;
[e472eab]543 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
[eacc3b]544 count++;
545 return count;
546}
547
[e4afb4]548bool World::isSelected(const atom *_atom) const {
[89643d]549 return isAtomSelected(_atom->getId());
550}
551
552bool World::isAtomSelected(const atomId_t no) const {
553 return selectedAtoms.find(no) != selectedAtoms.end();
[e0e156]554}
555
[e472eab]556const std::vector<atom *> World::getSelectedAtoms() const {
557 std::vector<atom *> returnAtoms;
558 returnAtoms.resize(countSelectedAtoms());
559 int count = 0;
560 for (AtomSet::const_iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter)
561 returnAtoms[count++] = iter->second;
562 return returnAtoms;
563}
564
565
[90c4280]566// Molecules
567
568void World::clearMoleculeSelection(){
[69643a]569 OBSERVE;
570 NOTIFY(SelectionChanged);
[90c4280]571 selectedMolecules.clear();
572}
573
[ebc499]574void World::invertMoleculeSelection(){
575 // get all molecules not selected
576 typedef std::vector<molecule *> MoleculeVector_t;
577 MoleculeVector_t invertedSelection(getAllMolecules());
578 bool (World::*predicate)(const molecule*) const = &World::isSelected; // needed for type resolution of overloaded function
579 MoleculeVector_t::iterator iter =
580 std::remove_if(invertedSelection.begin(), invertedSelection.end(),
581 std::bind1st(std::mem_fun(predicate), this));
582 invertedSelection.erase(iter, invertedSelection.end());
583 // apply new selection
584 selectedMolecules.clear();
585 void (World::*selector)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
586 std::for_each(invertedSelection.begin(),invertedSelection.end(),
587 std::bind1st(std::mem_fun(selector),this)); // func is select... see above
588}
589
[e4afb4]590void World::selectMolecule(const molecule *_mol){
[69643a]591 OBSERVE;
592 NOTIFY(SelectionChanged);
[e4afb4]593 // molecule * is unchanged in this function, but we do store entity as changeable
594 ASSERT(_mol,"Invalid pointer to molecule in selection");
595 selectedMolecules[_mol->getId()]=const_cast<molecule *>(_mol);
[90c4280]596}
597
[e4afb4]598void World::selectMolecule(const moleculeId_t id){
[69643a]599 OBSERVE;
600 NOTIFY(SelectionChanged);
[90c4280]601 ASSERT(molecules.count(id),"Molecule Id selected that was not in the world");
602 selectedMolecules[id]=molecules[id];
603}
604
[e472eab]605void World::selectAllMolecules(MoleculeDescriptor descr){
[69643a]606 OBSERVE;
607 NOTIFY(SelectionChanged);
[90c4280]608 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
609 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]610 void (World::*func)(const molecule*) = &World::selectMolecule; // needed for type resolution of overloaded function
[90c4280]611 for_each(begin,end,bind1st(mem_fun(func),this)); // func is select... see above
612}
613
[e4afb4]614void World::selectMoleculeOfAtom(const atom *_atom){
[69643a]615 OBSERVE;
616 NOTIFY(SelectionChanged);
[e4afb4]617 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
618 molecule *mol=_atom->getMolecule();
[90c4280]619 // the atom might not be part of a molecule
620 if(mol){
621 selectMolecule(mol);
622 }
623}
624
[e4afb4]625void World::selectMoleculeOfAtom(const atomId_t id){
[69643a]626 OBSERVE;
627 NOTIFY(SelectionChanged);
[90c4280]628 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
629 selectMoleculeOfAtom(atoms[id]);
630}
631
[e4afb4]632void World::unselectMolecule(const molecule *_mol){
[69643a]633 OBSERVE;
634 NOTIFY(SelectionChanged);
[e4afb4]635 ASSERT(_mol,"invalid pointer in unselection of molecule");
636 unselectMolecule(_mol->getId());
[61d655e]637}
638
[e4afb4]639void World::unselectMolecule(const moleculeId_t id){
[69643a]640 OBSERVE;
641 NOTIFY(SelectionChanged);
[61d655e]642 ASSERT(molecules.count(id),"No such molecule with ID in unselection");
643 selectedMolecules.erase(id);
644}
645
[e472eab]646void World::unselectAllMolecules(MoleculeDescriptor descr){
[69643a]647 OBSERVE;
648 NOTIFY(SelectionChanged);
[61d655e]649 internal_MoleculeIterator begin = getMoleculeIter_internal(descr);
650 internal_MoleculeIterator end = moleculeEnd_internal();
[e4afb4]651 void (World::*func)(const molecule*) = &World::unselectMolecule; // needed for type resolution of overloaded function
[61d655e]652 for_each(begin,end,bind1st(mem_fun(func),this)); // func is unselect... see above
653}
654
[e4afb4]655void World::unselectMoleculeOfAtom(const atom *_atom){
[69643a]656 OBSERVE;
657 NOTIFY(SelectionChanged);
[e4afb4]658 ASSERT(_atom,"Invalid atom pointer in selection of MoleculeOfAtom");
659 molecule *mol=_atom->getMolecule();
[61d655e]660 // the atom might not be part of a molecule
661 if(mol){
662 unselectMolecule(mol);
663 }
664}
665
[e4afb4]666void World::unselectMoleculeOfAtom(const atomId_t id){
[69643a]667 OBSERVE;
668 NOTIFY(SelectionChanged);
[61d655e]669 ASSERT(atoms.count(id),"No such atom with given ID in selection of Molecules of Atom");\
670 unselectMoleculeOfAtom(atoms[id]);
671}
672
[e472eab]673size_t World::countSelectedMolecules() const {
[eacc3b]674 size_t count = 0;
[e472eab]675 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
[eacc3b]676 count++;
677 return count;
678}
679
[e4afb4]680bool World::isSelected(const molecule *_mol) const {
[89643d]681 return isMoleculeSelected(_mol->getId());
682}
683
684bool World::isMoleculeSelected(const moleculeId_t no) const {
685 return selectedMolecules.find(no) != selectedMolecules.end();
[e0e156]686}
687
[e472eab]688const std::vector<molecule *> World::getSelectedMolecules() const {
689 std::vector<molecule *> returnMolecules;
690 returnMolecules.resize(countSelectedMolecules());
691 int count = 0;
692 for (MoleculeSet::const_iterator iter = selectedMolecules.begin(); iter != selectedMolecules.end(); ++iter)
693 returnMolecules[count++] = iter->second;
694 return returnMolecules;
695}
696
[3839e5]697/******************* Iterators over Selection *****************************/
698World::AtomSelectionIterator World::beginAtomSelection(){
699 return selectedAtoms.begin();
700}
701
702World::AtomSelectionIterator World::endAtomSelection(){
703 return selectedAtoms.end();
704}
705
[38f991]706World::AtomSelectionConstIterator World::beginAtomSelection() const{
707 return selectedAtoms.begin();
708}
709
710World::AtomSelectionConstIterator World::endAtomSelection() const{
711 return selectedAtoms.end();
712}
713
[3839e5]714
715World::MoleculeSelectionIterator World::beginMoleculeSelection(){
716 return selectedMolecules.begin();
717}
718
719World::MoleculeSelectionIterator World::endMoleculeSelection(){
720 return selectedMolecules.end();
721}
722
[38f991]723World::MoleculeSelectionConstIterator World::beginMoleculeSelection() const{
724 return selectedMolecules.begin();
725}
726
727World::MoleculeSelectionConstIterator World::endMoleculeSelection() const{
728 return selectedMolecules.end();
729}
730
[5d1611]731/******************************* Singleton Stuff **************************/
732
[7a1ce5]733World::World() :
[cd5047]734 Observable("World"),
[f71baf]735 BG(new BondGraph(true)), // assume Angstroem for the moment
[4ae823]736 periode(new periodentafel(true)),
[8e1f7af]737 configuration(new config),
[43dad6]738 Thermostats(new ThermoStatContainer),
[e4b5de]739 ExitFlag(0),
[fa0b18]740 atoms(this),
[90c4280]741 selectedAtoms(this),
[3e4fb6]742 atomIdPool(0, 20, 100),
[51be2a]743 molecules(this),
[90c4280]744 selectedMolecules(this),
[3e4fb6]745 moleculeIdPool(0, 20,100),
[24a5e0]746 molecules_deprecated(new MoleculeListClass(this))
[7dad10]747{
[84c494]748 cell_size = new Box;
[cca9ef]749 RealSpaceMatrix domain;
[84c494]750 domain.at(0,0) = 20;
751 domain.at(1,1) = 20;
752 domain.at(2,2) = 20;
753 cell_size->setM(domain);
[4834f4]754 LCcontroller = new LinkedCell::LinkedCell_Controller(*cell_size);
[387b36]755 defaultName = "none";
[02ce36]756 Channels *OurChannel = new Channels;
757 NotificationChannels.insert( std::make_pair( this, OurChannel) );
[7188b1]758 for (size_t type = 0; type < (size_t)NotificationType_MAX; ++type)
[02ce36]759 OurChannel->addChannel(type);
[7dad10]760 molecules_deprecated->signOn(this);
761}
[5d1611]762
763World::~World()
[354859]764{
[028c2e]765 molecules_deprecated->signOff(this);
[4834f4]766 delete LCcontroller;
[84c494]767 delete cell_size;
[46d958]768 delete molecules_deprecated;
[cbc5fb]769 MoleculeSet::iterator molIter;
770 for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
771 DeleteMolecule((*molIter).second);
772 }
773 molecules.clear();
774 AtomSet::iterator atIter;
775 for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
776 DeleteAtom((*atIter).second);
[46d958]777 }
778 atoms.clear();
[7188b1]779
780 // empty notifications
[02ce36]781 std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
782 ASSERT(iter != NotificationChannels.end(),
783 "World::~World() - cannot find our Channels in NotificationChannels.");
784 delete iter->second;
785 NotificationChannels.erase(iter);
[7188b1]786
[f71baf]787 delete BG;
[6cb9c76]788 delete periode;
789 delete configuration;
790 delete Thermostats;
[354859]791}
[5d1611]792
[23b547]793// Explicit instantiation of the singleton mechanism at this point
[5d1611]794
[3e4fb6]795// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
[b97a60]796CONSTRUCT_IDPOOL(atomId_t, uniqueId)
797CONSTRUCT_IDPOOL(moleculeId_t, continuousId)
[3e4fb6]798
[23b547]799CONSTRUCT_SINGLETON(World)
[5d1611]800
[5f1d5b8]801CONSTRUCT_OBSERVEDCONTAINER(World::AtomSTLSet)
802
803CONSTRUCT_OBSERVEDCONTAINER(World::MoleculeSTLSet)
804
[5d1611]805/******************************* deprecated Legacy Stuff ***********************/
806
[354859]807MoleculeListClass *&World::getMolecules() {
808 return molecules_deprecated;
[5d1611]809}
Note: See TracBrowser for help on using the repository browser.