Changeset 6c438f for src/molecule.cpp
- Timestamp:
- Aug 28, 2010, 3:21:11 AM (15 years ago)
- Branches:
- 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, Candidate_v1.7.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
- Children:
- a6e6b5, f8982c
- Parents:
- 2ad482 (diff), fd4905 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - git-author:
- Frederik Heber <heber@…> (08/28/10 03:17:48)
- git-committer:
- Frederik Heber <heber@…> (08/28/10 03:21:11)
- File:
-
- 1 edited
-
src/molecule.cpp (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
r2ad482 r6c438f 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 1 8 /** \file molecules.cpp 2 9 * … … 5 12 */ 6 13 14 // include config.h 7 15 #ifdef HAVE_CONFIG_H 8 16 #include <config.h> … … 24 32 #include "element.hpp" 25 33 #include "graph.hpp" 26 #include " helpers.hpp"34 #include "Helpers/helpers.hpp" 27 35 #include "leastsquaremin.hpp" 28 36 #include "linkedcell.hpp" 29 37 #include "lists.hpp" 30 #include " log.hpp"38 #include "Helpers/Log.hpp" 31 39 #include "molecule.hpp" 32 40 … … 34 42 #include "stackclass.hpp" 35 43 #include "tesselation.hpp" 36 #include " vector.hpp"37 #include " Matrix.hpp"44 #include "LinearAlgebra/Vector.hpp" 45 #include "LinearAlgebra/Matrix.hpp" 38 46 #include "World.hpp" 39 47 #include "Box.hpp" 40 #include " Plane.hpp"48 #include "LinearAlgebra/Plane.hpp" 41 49 #include "Exceptions/LinearDependenceException.hpp" 42 50 … … 75 83 76 84 // getter and setter 77 const std::string molecule::getName() {85 const std::string molecule::getName() const{ 78 86 return std::string(name); 79 87 } … … 89 97 } 90 98 91 moleculeId_t molecule::getId(){ 99 bool molecule::changeId(moleculeId_t newId){ 100 // first we move ourselves in the world 101 // the world lets us know if that succeeded 102 if(World::getInstance().changeMoleculeId(id,newId,this)){ 103 id = newId; 104 return true; 105 } 106 else{ 107 return false; 108 } 109 } 110 111 112 moleculeId_t molecule::getId() const { 92 113 return id; 93 114 } … … 97 118 } 98 119 99 const Formula &molecule::getFormula() {120 const Formula &molecule::getFormula() const { 100 121 return formula; 101 122 } 102 123 103 unsigned int molecule::getElementCount() {124 unsigned int molecule::getElementCount() const{ 104 125 return formula.getElementCount(); 105 126 } … … 151 172 molecule::const_iterator molecule::erase( const_iterator loc ) 152 173 { 174 OBSERVE; 153 175 molecule::const_iterator iter = loc; 154 176 iter--; … … 156 178 atomIds.erase( atom->getId() ); 157 179 atoms.remove( atom ); 180 formula-=atom->getType(); 158 181 atom->removeFromMolecule(); 159 182 return iter; … … 162 185 molecule::const_iterator molecule::erase( atom * key ) 163 186 { 187 OBSERVE; 164 188 molecule::const_iterator iter = find(key); 165 189 if (iter != end()){ 166 190 atomIds.erase( key->getId() ); 167 191 atoms.remove( key ); 192 formula-=key->getType(); 168 193 key->removeFromMolecule(); 169 194 } … … 183 208 pair<molecule::iterator,bool> molecule::insert ( atom * const key ) 184 209 { 210 OBSERVE; 185 211 pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId()); 186 212 if (res.second) { // push atom if went well 187 213 atoms.push_back(key); 214 formula+=key->getType(); 188 215 return pair<iterator,bool>(molecule::iterator(--end()),res.second); 189 216 } else { … … 206 233 if (pointer != NULL) { 207 234 pointer->sort = &pointer->nr; 208 if (pointer->type != NULL) { 209 formula += pointer->type; 210 if (pointer->type->Z != 1) 235 if (pointer->getType() != NULL) { 236 if (pointer->getType()->getAtomicNumber() != 1) 211 237 NoNonHydrogen++; 212 238 if(pointer->getName() == "Unknown"){ 213 239 stringstream sstr; 214 sstr << pointer-> type->symbol<< pointer->nr+1;240 sstr << pointer->getType()->getSymbol() << pointer->nr+1; 215 241 pointer->setName(sstr.str()); 216 242 } … … 236 262 walker->nr = last_atom++; // increase number within molecule 237 263 insert(walker); 238 if ((pointer-> type != NULL) && (pointer->type->Z!= 1))264 if ((pointer->getType() != NULL) && (pointer->getType()->getAtomicNumber() != 1)) 239 265 NoNonHydrogen++; 266 walker->setMolecule(this); 240 267 retval=walker; 241 268 } … … 294 321 // Log() << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; 295 322 // create vector in direction of bond 296 InBondvector = TopReplacement-> x - TopOrigin->x;323 InBondvector = TopReplacement->getPosition() - TopOrigin->getPosition(); 297 324 bondlength = InBondvector.Norm(); 298 325 … … 306 333 Orthovector1.Zero(); 307 334 for (int i=NDIM;i--;) { 308 l = TopReplacement-> x[i] - TopOrigin->x[i];335 l = TopReplacement->at(i) - TopOrigin->at(i); 309 336 if (fabs(l) > BondDistance) { // is component greater than bond distance 310 337 Orthovector1[i] = (l < 0) ? -1. : +1.; … … 321 348 InBondvector.Normalize(); 322 349 // get typical bond length and store as scale factor for later 323 ASSERT(TopOrigin-> type!= NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given.");324 BondRescale = TopOrigin-> type->HBondDistance[TopBond->BondDegree-1];350 ASSERT(TopOrigin->getType() != NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given."); 351 BondRescale = TopOrigin->getType()->getHBondDistance(TopBond->BondDegree-1); 325 352 if (BondRescale == -1) { 326 353 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 336 363 case 1: 337 364 FirstOtherAtom = World::getInstance().createAtom(); // new atom 338 FirstOtherAtom-> type = elemente->FindElement(1); // element is Hydrogen339 FirstOtherAtom-> v = TopReplacement->v; // copy velocity365 FirstOtherAtom->setType(1); // element is Hydrogen 366 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 340 367 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 341 if (TopReplacement-> type->Z== 1) { // neither rescale nor replace if it's already hydrogen368 if (TopReplacement->getType()->getAtomicNumber() == 1) { // neither rescale nor replace if it's already hydrogen 342 369 FirstOtherAtom->father = TopReplacement; 343 370 BondRescale = bondlength; … … 346 373 } 347 374 InBondvector *= BondRescale; // rescale the distance vector to Hydrogen bond length 348 FirstOtherAtom->x = TopOrigin->x; // set coordination to origin ... 349 FirstOtherAtom->x += InBondvector; // ... and add distance vector to replacement atom 375 FirstOtherAtom->setPosition(TopOrigin->getPosition() + InBondvector); // set coordination to origin and add distance vector to replacement atom 350 376 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); 351 377 // Log() << Verbose(4) << "Added " << *FirstOtherAtom << " at: "; … … 380 406 // determine the plane of these two with the *origin 381 407 try { 382 Orthovector1 =Plane(TopOrigin-> x, FirstOtherAtom->x, SecondOtherAtom->x).getNormal();408 Orthovector1 =Plane(TopOrigin->getPosition(), FirstOtherAtom->getPosition(), SecondOtherAtom->getPosition()).getNormal(); 383 409 } 384 410 catch(LinearDependenceException &excp){ … … 401 427 FirstOtherAtom = World::getInstance().createAtom(); 402 428 SecondOtherAtom = World::getInstance().createAtom(); 403 FirstOtherAtom-> type = elemente->FindElement(1);404 SecondOtherAtom-> type = elemente->FindElement(1);405 FirstOtherAtom-> v = TopReplacement->v; // copy velocity429 FirstOtherAtom->setType(1); 430 SecondOtherAtom->setType(1); 431 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 406 432 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 407 SecondOtherAtom-> v = TopReplacement->v; // copy velocity433 SecondOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 408 434 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 409 435 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father 410 436 SecondOtherAtom->father = NULL; // we are just an added hydrogen with no father 411 bondangle = TopOrigin-> type->HBondAngle[1];437 bondangle = TopOrigin->getType()->getHBondAngle(1); 412 438 if (bondangle == -1) { 413 439 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 423 449 // Log() << Verbose(0) << endl; 424 450 // Log() << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl; 425 FirstOtherAtom-> x.Zero();426 SecondOtherAtom-> x.Zero();451 FirstOtherAtom->Zero(); 452 SecondOtherAtom->Zero(); 427 453 for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction) 428 FirstOtherAtom-> x[i] = InBondvector[i] * cos(bondangle) + Orthovector1[i] * (sin(bondangle));429 SecondOtherAtom-> x[i] = InBondvector[i] * cos(bondangle) + Orthovector1[i] * (-sin(bondangle));430 } 431 FirstOtherAtom-> x *= BondRescale; // rescale by correct BondDistance432 SecondOtherAtom-> x *= BondRescale;454 FirstOtherAtom->set(i, InBondvector[i] * cos(bondangle) + Orthovector1[i] * (sin(bondangle))); 455 SecondOtherAtom->set(i, InBondvector[i] * cos(bondangle) + Orthovector1[i] * (-sin(bondangle))); 456 } 457 FirstOtherAtom->Scale(BondRescale); // rescale by correct BondDistance 458 SecondOtherAtom->Scale(BondRescale); 433 459 //Log() << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl; 434 for(int i=NDIM;i--;) { // and make relative to origin atom 435 FirstOtherAtom->x[i] += TopOrigin->x[i]; 436 SecondOtherAtom->x[i] += TopOrigin->x[i]; 437 } 460 *FirstOtherAtom += TopOrigin->getPosition(); 461 *SecondOtherAtom += TopOrigin->getPosition(); 438 462 // ... and add to molecule 439 463 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); … … 457 481 SecondOtherAtom = World::getInstance().createAtom(); 458 482 ThirdOtherAtom = World::getInstance().createAtom(); 459 FirstOtherAtom-> type = elemente->FindElement(1);460 SecondOtherAtom-> type = elemente->FindElement(1);461 ThirdOtherAtom-> type = elemente->FindElement(1);462 FirstOtherAtom-> v = TopReplacement->v; // copy velocity483 FirstOtherAtom->setType(1); 484 SecondOtherAtom->setType(1); 485 ThirdOtherAtom->setType(1); 486 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 463 487 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 464 SecondOtherAtom-> v = TopReplacement->v; // copy velocity488 SecondOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 465 489 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 466 ThirdOtherAtom-> v = TopReplacement->v; // copy velocity490 ThirdOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 467 491 ThirdOtherAtom->FixedIon = TopReplacement->FixedIon; 468 492 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father … … 487 511 488 512 // create correct coordination for the three atoms 489 alpha = (TopOrigin-> type->HBondAngle[2])/180.*M_PI/2.; // retrieve triple bond angle from database513 alpha = (TopOrigin->getType()->getHBondAngle(2))/180.*M_PI/2.; // retrieve triple bond angle from database 490 514 l = BondRescale; // desired bond length 491 515 b = 2.*l*sin(alpha); // base length of isosceles triangle … … 498 522 factors[1] = f; 499 523 factors[2] = 0.; 500 FirstOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);524 FirstOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 501 525 factors[1] = -0.5*f; 502 526 factors[2] = g; 503 SecondOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);527 SecondOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 504 528 factors[2] = -g; 505 ThirdOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);529 ThirdOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 506 530 507 531 // rescale each to correct BondDistance … … 511 535 512 536 // and relative to *origin atom 513 FirstOtherAtom->x += TopOrigin->x;514 SecondOtherAtom->x += TopOrigin->x;515 ThirdOtherAtom->x += TopOrigin->x;537 *FirstOtherAtom += TopOrigin->getPosition(); 538 *SecondOtherAtom += TopOrigin->getPosition(); 539 *ThirdOtherAtom += TopOrigin->getPosition(); 516 540 517 541 // ... and add to molecule … … 589 613 *item >> x[1]; 590 614 *item >> x[2]; 591 Walker-> type = elemente->FindElement(shorthand);592 if (Walker-> type== NULL) {615 Walker->setType(elemente->FindElement(shorthand)); 616 if (Walker->getType() == NULL) { 593 617 DoeLog(1) && (eLog()<< Verbose(1) << "Could not parse the element at line: '" << line << "', setting to H."); 594 Walker-> type = elemente->FindElement(1);618 Walker->setType(1); 595 619 } 596 620 if (Walker->Trajectory.R.size() <= (unsigned int)MDSteps) { … … 599 623 Walker->Trajectory.F.resize(MDSteps+10); 600 624 } 625 Walker->setPosition(Vector(x)); 601 626 for(j=NDIM;j--;) { 602 Walker->x[j] = x[j];603 627 Walker->Trajectory.R.at(MDSteps-1)[j] = x[j]; 604 628 Walker->Trajectory.U.at(MDSteps-1)[j] = 0; … … 619 643 { 620 644 molecule *copy = World::getInstance().createMolecule(); 621 atom *LeftAtom = NULL, *RightAtom = NULL;622 645 623 646 // copy all atoms 624 ActOnCopyWithEachAtom ( &molecule::AddCopyAtom, copy);647 for_each(atoms.begin(),atoms.end(),bind1st(mem_fun(&molecule::AddCopyAtom),copy)); 625 648 626 649 // copy all bonds 627 bond *Binder = NULL;628 bond *NewBond = NULL;629 650 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 630 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin())651 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); BondRunner != (*AtomRunner)->ListOfBonds.end(); ++BondRunner) 631 652 if ((*BondRunner)->leftatom == *AtomRunner) { 632 Binder = (*BondRunner); 633 653 bond *Binder = (*BondRunner); 634 654 // get the pendant atoms of current bond in the copy molecule 635 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 636 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 637 638 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 655 atomSet::iterator leftiter=find_if(copy->atoms.begin(),copy->atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->leftatom)); 656 atomSet::iterator rightiter=find_if(copy->atoms.begin(),copy->atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->rightatom)); 657 ASSERT(leftiter!=copy->atoms.end(),"No copy of original left atom for bond copy found"); 658 ASSERT(leftiter!=copy->atoms.end(),"No copy of original right atom for bond copy found"); 659 atom *LeftAtom = *leftiter; 660 atom *RightAtom = *rightiter; 661 662 bond *NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 639 663 NewBond->Cyclic = Binder->Cyclic; 640 664 if (Binder->Cyclic) … … 643 667 } 644 668 // correct fathers 645 ActOnAllAtoms( &atom::CorrectFather);669 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::CorrectFather)); 646 670 647 671 // copy values … … 689 713 ASSERT(atom2, "Second atom in bond-creation was an invalid pointer"); 690 714 ASSERT(FindAtom(atom1->nr),"First atom in bond-creation was not part of molecule"); 691 ASSERT(FindAtom(atom2->nr),"Second atom in bond-creation was not part oof molecule");715 ASSERT(FindAtom(atom2->nr),"Second atom in bond-creation was not part of molecule"); 692 716 693 717 Binder = new bond(atom1, atom2, degree, BondCount++); 694 718 atom1->RegisterBond(Binder); 695 719 atom2->RegisterBond(Binder); 696 if ((atom1-> type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z!= 1))720 if ((atom1->getType() != NULL) && (atom1->getType()->getAtomicNumber() != 1) && (atom2->getType() != NULL) && (atom2->getType()->getAtomicNumber() != 1)) 697 721 NoNonBonds++; 698 722 … … 760 784 }; 761 785 762 /** Removes atom from molecule list and deletes it.786 /** Removes atom from molecule list and removes all of its bonds. 763 787 * \param *pointer atom to be removed 764 788 * \return true - succeeded, false - atom not found in list … … 768 792 ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom()."); 769 793 OBSERVE; 770 formula-=pointer->type;771 794 RemoveBonds(pointer); 772 795 erase(pointer); … … 782 805 if (pointer == NULL) 783 806 return false; 784 formula-=pointer->type;785 807 erase(pointer); 786 808 return true; … … 793 815 { 794 816 for (molecule::iterator iter = begin(); !empty(); iter = begin()) 795 erase(iter);817 erase(*iter); 796 818 return empty(); 797 819 }; … … 852 874 * \param *out output stream 853 875 */ 854 bool molecule::Output(ofstream * const output) 855 { 856 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS]; 857 858 for (int i=0;i<MAX_ELEMENTS;++i) { 859 AtomNo[i] = 0; 860 ElementNo[i] = 0; 861 } 876 bool molecule::Output(ostream * const output) 877 { 862 878 if (output == NULL) { 863 879 return false; 864 880 } else { 881 int AtomNo[MAX_ELEMENTS]; 882 memset(AtomNo,0,(MAX_ELEMENTS-1)*sizeof(*AtomNo)); 883 enumeration<const element*> elementLookup = formula.enumerateElements(); 865 884 *output << "#Ion_TypeNr._Nr.R[0] R[1] R[2] MoveType (0 MoveIon, 1 FixedIon)" << endl; 866 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 867 int current=1; 868 for (int i=0;i<MAX_ELEMENTS;++i) { 869 if (ElementNo[i] == 1) 870 ElementNo[i] = current++; 871 } 872 ActOnAllAtoms( &atom::OutputArrayIndexed, (ostream * const) output, (const int *)ElementNo, (int *)AtomNo, (const char *) NULL ); 885 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputArrayIndexed,_1,output,elementLookup,AtomNo,(const char*)0)); 873 886 return true; 874 887 } … … 880 893 bool molecule::OutputTrajectories(ofstream * const output) 881 894 { 882 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];883 884 895 if (output == NULL) { 885 896 return false; … … 891 902 *output << "# ====== MD step " << step << " =========" << endl; 892 903 } 893 for (int i=0;i<MAX_ELEMENTS;++i) { 894 AtomNo[i] = 0; 895 ElementNo[i] = 0; 896 } 897 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 898 int current=1; 899 for (int i=0;i<MAX_ELEMENTS;++i) { 900 if (ElementNo[i] == 1) 901 ElementNo[i] = current++; 902 } 903 ActOnAllAtoms( &atom::OutputTrajectory, output, (const int *)ElementNo, AtomNo, (const int)step ); 904 int AtomNo[MAX_ELEMENTS]; 905 memset(AtomNo,0,(MAX_ELEMENTS-1)*sizeof(*AtomNo)); 906 enumeration<const element*> elementLookup = formula.enumerateElements(); 907 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectory,_1,output,elementLookup, AtomNo, (const int)step)); 904 908 } 905 909 return true; … … 913 917 { 914 918 DoLog(2) && (Log() << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl); 915 ActOnAllAtoms (&atom::OutputBondOfAtom);919 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::OutputBondOfAtom)); 916 920 DoLog(0) && (Log() << Verbose(0) << endl); 917 921 }; … … 936 940 for (int step=0;step<MDSteps;step++) { 937 941 *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 938 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step);942 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectoryXYZ,_1,output,step)); 939 943 } 940 944 return true; … … 953 957 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 954 958 *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now); 955 ActOnAllAtoms( &atom::OutputXYZLine, output);959 for_each(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::OutputXYZLine),output)); 956 960 return true; 957 961 } else … … 969 973 for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 970 974 (*iter)->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 971 if ((*iter)-> type->Z!= 1) // count non-hydrogen atoms whilst at it975 if ((*iter)->getType()->getAtomicNumber() != 1) // count non-hydrogen atoms whilst at it 972 976 NoNonHydrogen++; 973 977 stringstream sstr; 974 sstr << (*iter)-> type->symbol<< (*iter)->nr+1;978 sstr << (*iter)->getType()->getSymbol() << (*iter)->nr+1; 975 979 (*iter)->setName(sstr.str()); 976 980 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl); … … 978 982 } 979 983 return res; 980 };981 982 /** Determines whether two molecules actually contain the same atoms and coordination.983 * \param *out output stream for debugging984 * \param *OtherMolecule the molecule to compare this one to985 * \param threshold upper limit of difference when comparing the coordination.986 * \return NULL - not equal, otherwise an allocated (molecule::AtomCount) permutation map of the atom numbers (which corresponds to which)987 */988 int * molecule::IsEqualToWithinThreshold(molecule *OtherMolecule, double threshold)989 {990 int flag;991 double *Distances = NULL, *OtherDistances = NULL;992 Vector CenterOfGravity, OtherCenterOfGravity;993 size_t *PermMap = NULL, *OtherPermMap = NULL;994 int *PermutationMap = NULL;995 bool result = true; // status of comparison996 997 DoLog(3) && (Log() << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl);998 /// first count both their atoms and elements and update lists thereby ...999 //Log() << Verbose(0) << "Counting atoms, updating list" << endl;1000 1001 /// ... and compare:1002 /// -# AtomCount1003 if (result) {1004 if (getAtomCount() != OtherMolecule->getAtomCount()) {1005 DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl);1006 result = false;1007 } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl;1008 }1009 /// -# Formula1010 if (result) {1011 if (formula != OtherMolecule->formula) {1012 DoLog(4) && (Log() << Verbose(4) << "Formulas don't match: " << formula << " == " << OtherMolecule->formula << endl);1013 result = false;1014 } else Log() << Verbose(4) << "Formulas match: " << formula << " == " << OtherMolecule->formula << endl;1015 }1016 /// then determine and compare center of gravity for each molecule ...1017 if (result) {1018 DoLog(5) && (Log() << Verbose(5) << "Calculating Centers of Gravity" << endl);1019 DeterminePeriodicCenter(CenterOfGravity);1020 OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);1021 DoLog(5) && (Log() << Verbose(5) << "Center of Gravity: " << CenterOfGravity << endl);1022 DoLog(5) && (Log() << Verbose(5) << "Other Center of Gravity: " << OtherCenterOfGravity << endl);1023 if (CenterOfGravity.DistanceSquared(OtherCenterOfGravity) > threshold*threshold) {1024 DoLog(4) && (Log() << Verbose(4) << "Centers of gravity don't match." << endl);1025 result = false;1026 }1027 }1028 1029 /// ... then make a list with the euclidian distance to this center for each atom of both molecules1030 if (result) {1031 DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl);1032 Distances = new double[getAtomCount()];1033 OtherDistances = new double[getAtomCount()];1034 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1035 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1036 for(int i=0;i<getAtomCount();i++) {1037 Distances[i] = 0.;1038 OtherDistances[i] = 0.;1039 }1040 1041 /// ... sort each list (using heapsort (o(N log N)) from GSL)1042 DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl);1043 PermMap = new size_t[getAtomCount()];1044 OtherPermMap = new size_t[getAtomCount()];1045 for(int i=0;i<getAtomCount();i++) {1046 PermMap[i] = 0;1047 OtherPermMap[i] = 0;1048 }1049 gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles);1050 gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles);1051 PermutationMap = new int[getAtomCount()];1052 for(int i=0;i<getAtomCount();i++)1053 PermutationMap[i] = 0;1054 DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl);1055 for(int i=getAtomCount();i--;)1056 PermutationMap[PermMap[i]] = (int) OtherPermMap[i];1057 1058 /// ... and compare them step by step, whether the difference is individually(!) below \a threshold for all1059 DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl);1060 flag = 0;1061 for (int i=0;i<getAtomCount();i++) {1062 DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " << threshold << endl);1063 if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)1064 flag = 1;1065 }1066 1067 // free memory1068 delete[](PermMap);1069 delete[](OtherPermMap);1070 delete[](Distances);1071 delete[](OtherDistances);1072 if (flag) { // if not equal1073 delete[](PermutationMap);1074 result = false;1075 }1076 }1077 /// return pointer to map if all distances were below \a threshold1078 DoLog(3) && (Log() << Verbose(3) << "End of IsEqualToWithinThreshold." << endl);1079 if (result) {1080 DoLog(3) && (Log() << Verbose(3) << "Result: Equal." << endl);1081 return PermutationMap;1082 } else {1083 DoLog(3) && (Log() << Verbose(3) << "Result: Not equal." << endl);1084 return NULL;1085 }1086 984 }; 1087 985 … … 1142 1040 *output << "# Step Temperature [K] Temperature [a.u.]" << endl; 1143 1041 for (int step=startstep;step < endstep; step++) { // loop over all time steps 1144 temperature = 0.; 1145 ActOnAllAtoms( &TrajectoryParticle::AddKineticToTemperature, &temperature, step); 1042 temperature = atoms.totalTemperatureAtStep(step); 1146 1043 *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl; 1147 1044 } 1148 1045 return true; 1149 };1150 1151 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const1152 {1153 for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {1154 array[((*iter)->*index)] = (*iter);1155 }1156 1046 }; 1157 1047
Note:
See TracChangeset
for help on using the changeset viewer.
