Changeset 4f04ab8 for src/Graph/BondGraph.cpp
- Timestamp:
- Apr 18, 2013, 4:23:26 PM (12 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, 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:
- 53c579
- Parents:
- 326000
- git-author:
- Frederik Heber <heber@…> (03/21/13 09:33:31)
- git-committer:
- Frederik Heber <heber@…> (04/18/13 16:23:26)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Graph/BondGraph.cpp
r326000 r4f04ab8 33 33 #endif 34 34 35 // boost::graph uses placement new 36 #include <boost/graph/adjacency_list.hpp> 37 35 38 #include "CodePatterns/MemDebug.hpp" 36 39 40 #include <algorithm> 41 #include <boost/bimap.hpp> 42 #include <boost/bind.hpp> 43 #include <boost/foreach.hpp> 44 #include <boost/function.hpp> 45 #include <boost/graph/max_cardinality_matching.hpp> 37 46 #include <deque> 38 47 #include <iostream> … … 320 329 return treeedges; 321 330 } 331 332 struct hasDelta { 333 bool operator()(atom *_atom) { 334 const double delta = 335 _atom->getType()->getNoValenceOrbitals() - _atom->CountBonds(); 336 return (fabs(delta) > 0); 337 } 338 }; 339 340 typedef std::set<atom *> deltaatoms_t; 341 typedef std::set<bond::ptr> deltaedges_t; 342 343 static int gatherAllDeltaAtoms( 344 const deltaatoms_t &allatoms, 345 deltaatoms_t &deltaatoms) 346 { 347 static hasDelta delta; 348 deltaatoms.clear(); 349 for (deltaatoms_t::const_iterator iter = allatoms.begin(); 350 iter != allatoms.end(); ++iter) { 351 if (delta(*iter)) 352 deltaatoms.insert(*iter); 353 } 354 return deltaatoms.size(); 355 } 356 357 typedef boost::bimap<int,atom*> AtomIndexLookup_t; 358 359 static AtomIndexLookup_t createAtomIndexLookup( 360 const deltaedges_t &edges) 361 { 362 AtomIndexLookup_t AtomIndexLookup; 363 size_t index = 0; 364 for (deltaedges_t::const_iterator edgeiter = edges.begin(); 365 edgeiter != edges.end(); ++edgeiter) { 366 const bond::ptr & _bond = *edgeiter; 367 368 // insert left into lookup 369 std::pair< AtomIndexLookup_t::iterator, bool > inserter = 370 AtomIndexLookup.insert( AtomIndexLookup_t::value_type(index, _bond->leftatom) ); 371 if (inserter.second) 372 ++index; 373 374 // insert right into lookup 375 inserter = AtomIndexLookup.insert( AtomIndexLookup_t::value_type(index, _bond->rightatom) ); 376 if (inserter.second) 377 ++index; 378 } 379 return AtomIndexLookup; 380 } 381 382 typedef std::map< std::pair<atom *, atom*>, bond::ptr> BondLookup_t; 383 static BondLookup_t createBondLookup( 384 const deltaedges_t &edges) 385 { 386 BondLookup_t BondLookup; 387 for (deltaedges_t::const_iterator edgeiter = edges.begin(); 388 edgeiter != edges.end(); ++edgeiter) { 389 const bond::ptr & _bond = *edgeiter; 390 391 // insert bond into pair lookup 392 BondLookup.insert( 393 std::make_pair( 394 std::make_pair(_bond->leftatom, _bond->rightatom), 395 _bond) 396 ); 397 } 398 return BondLookup; 399 } 400 401 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> graph_t; 402 typedef std::vector<boost::graph_traits<graph_t>::vertex_descriptor> mate_t; 403 404 static void fillEdgesIntoMatching( 405 graph_t &g, 406 mate_t &mate, 407 const AtomIndexLookup_t &AtomIndexLookup, 408 const BondLookup_t &BondLookup, 409 deltaedges_t &matching 410 ) 411 { 412 matching.clear(); 413 boost::graph_traits<graph_t>::vertex_iterator vi, vi_end; 414 for(tie(vi,vi_end) = boost::vertices(g); vi != vi_end; ++vi) 415 if (mate[*vi] != boost::graph_traits<graph_t>::null_vertex() && *vi < mate[*vi]) { 416 atom * leftatom = AtomIndexLookup.left.at(*vi); 417 atom * rightatom = AtomIndexLookup.left.at(mate[*vi]); 418 std::pair<atom *,atom *> AtomPair(leftatom, rightatom); 419 std::pair<atom *,atom *> reverseAtomPair(rightatom, leftatom); 420 BondLookup_t::const_iterator iter = BondLookup.find(AtomPair); 421 if (iter != BondLookup.end()) { 422 matching.insert(iter->second); 423 } else { 424 iter = BondLookup.find(reverseAtomPair); 425 if (iter != BondLookup.end()) { 426 matching.insert(iter->second); 427 } else 428 ASSERT(0, "fillEdgesIntoMatching() - cannot find ("+toString(*vi)+"," 429 +toString(mate[*vi])+") in BondLookup."); 430 } 431 } 432 } 433 434 static bool createMatching( 435 deltaedges_t &deltaedges, 436 deltaedges_t &matching 437 ) 438 { 439 // gather all vertices for graph in a lookup structure 440 // to translate the graphs indices to atoms and also to associated bonds 441 AtomIndexLookup_t AtomIndexLookup = createAtomIndexLookup(deltaedges); 442 BondLookup_t BondLookup = createBondLookup(deltaedges); 443 const int n_vertices = AtomIndexLookup.size(); 444 445 // construct graph 446 graph_t g(n_vertices); 447 448 // add edges to graph 449 for (deltaedges_t::const_iterator edgeiter = deltaedges.begin(); 450 edgeiter != deltaedges.end(); ++edgeiter) { 451 const bond::ptr & _bond = *edgeiter; 452 boost::add_edge( 453 AtomIndexLookup.right.at(_bond->leftatom), 454 AtomIndexLookup.right.at(_bond->rightatom), 455 g); 456 } 457 458 // mate structure contains unique edge partner to every vertex in matching 459 mate_t mate(n_vertices); 460 461 // get maximum matching over given edges 462 bool success = boost::checked_edmonds_maximum_cardinality_matching(g, &mate[0]); 463 464 if (success) { 465 LOG(1, "STATUS: Found a matching of size " << matching_size(g, &mate[0]) << "."); 466 fillEdgesIntoMatching(g, mate, AtomIndexLookup, BondLookup, matching); 467 } else { 468 ELOG(2, "Failed to find maximum matching."); 469 } 470 471 return success; 472 } 473 474 475 int BondGraph::calculateBondDegree(const deltaatoms_t &allatoms) const 476 { 477 deltaatoms_t deltaatoms; 478 deltaedges_t deltaedges; 479 deltaedges_t matching; 480 481 LOG(1, "STATUS: Calculating bond degrees."); 482 if (DoLog(2)) { 483 std::stringstream output; 484 output << "INFO: All atoms are: "; 485 BOOST_FOREACH( atom *_atom, allatoms) { 486 output << *_atom << " "; 487 } 488 LOG(2, output.str()); 489 } 490 491 size_t IterCount = 0; 492 // 1. gather all atoms with delta > 0 493 while ((gatherAllDeltaAtoms(allatoms, deltaatoms) != 0) && (IterCount < 100)) { 494 if (DoLog(3)) { 495 std::stringstream output; 496 output << "DEBUG: Current delta atoms are: "; 497 BOOST_FOREACH( atom *_atom, deltaatoms) { 498 output << *_atom << " "; 499 } 500 LOG(3, output.str()); 501 } 502 503 // 2. gather all edges that connect atoms with both(!) having delta > 0 504 deltaedges.clear(); 505 for (deltaatoms_t::const_iterator atomiter = deltaatoms.begin(); 506 atomiter != deltaatoms.end(); ++atomiter) { 507 const atom * const _atom = *atomiter; 508 const BondList& ListOfBonds = (*atomiter)->getListOfBonds(); 509 for (BondList::const_iterator bonditer = ListOfBonds.begin(); 510 bonditer != ListOfBonds.end();++bonditer) { 511 const bond::ptr _bond = *bonditer; 512 if ((_bond->leftatom == _atom) && (deltaatoms.find(_bond->rightatom) != deltaatoms.end())) 513 deltaedges.insert(_bond); 514 else if ((_bond->rightatom == _atom) && (deltaatoms.find(_bond->leftatom) != deltaatoms.end())) 515 deltaedges.insert(_bond); 516 } 517 } 518 if (DoLog(3)) { 519 std::stringstream output; 520 output << "DEBUG: Current delta bonds are: "; 521 BOOST_FOREACH( bond::ptr _bond, deltaedges) { 522 output << *_bond << " "; 523 } 524 LOG(3, output.str()); 525 } 526 if (deltaedges.empty()) 527 break; 528 529 // 3. build matching over these edges 530 if (!createMatching(deltaedges, matching)) 531 break; 532 if (DoLog(2)) { 533 std::stringstream output; 534 output << "DEBUG: Resulting matching is: "; 535 BOOST_FOREACH( bond::ptr _bond, matching) { 536 output << *_bond << " "; 537 } 538 LOG(2, output.str()); 539 } 540 541 // 4. increase degree for each edge of the matching 542 LOG(2, "DEBUG: Increasing bond degrees by one."); 543 for (deltaedges_t::iterator edgeiter = matching.begin(); 544 edgeiter != matching.end(); ++edgeiter) { 545 (*edgeiter)->setDegree( (*edgeiter)->getDegree()+1 ); 546 } 547 548 // 6. stop after a given number of iterations or when all atoms are happy. 549 ++IterCount; 550 }; 551 552 // check whether we still have deltaatoms 553 { 554 hasDelta delta; 555 for (deltaatoms_t::const_iterator iter = allatoms.begin(); 556 iter != allatoms.end(); ++iter) 557 if (delta(*iter)) 558 ELOG(2, "Could not find satisfy charge neutrality for atom " << **iter << "."); 559 } 560 561 return deltaedges.size(); 562 }
Note:
See TracChangeset
for help on using the changeset viewer.