Ignore:
Timestamp:
Feb 2, 2016, 5:50:29 PM (9 years ago)
Author:
Frederik Heber <heber@…>
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:
9ae11c
Parents:
d1831e (diff), 62d092 (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.
Message:

Merge branch 'Enhancing_Interdistance' into Candidate_v1.5.1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Interfragmenter.cpp

    rd1831e r3690e4  
    3737#include "Interfragmenter.hpp"
    3838
    39 #include <list>
    40 #include <map>
    41 
    4239#include "CodePatterns/Assert.hpp"
    4340#include "CodePatterns/Log.hpp"
     
    4542#include "LinearAlgebra/Vector.hpp"
    4643
    47 #include "AtomIdSet.hpp"
     44#include "Descriptors/AtomDescriptor.hpp"
    4845#include "Element/element.hpp"
    4946#include "Fragmentation/Graph.hpp"
     
    5350#include "World.hpp"
    5451
    55 void Interfragmenter::operator()(
    56     size_t MaxOrder,
    57     double Rcut,
    58     const enum HydrogenTreatment treatment)
     52
     53Interfragmenter::atomkeyset_t Interfragmenter::getAtomKeySetMap(
     54    size_t _MaxOrder
     55    ) const
    5956{
    6057  /// create a map of atom to keyset (below equal MaxOrder)
    61   typedef std::list<const KeySet *> keysets_t;
    62   typedef std::map<const atom *, keysets_t > atomkeyset_t;
    6358  atomkeyset_t atomkeyset;
    6459  LOG(1, "INFO: Placing all atoms and their keysets into a map.");
     
    6964    const AtomIdSet atoms(keyset);
    7065    const size_t atoms_size = atoms.getAtomIds().size();
    71     if ((atoms_size > MaxOrder) || (atoms_size == 0))
     66    if ((atoms_size > _MaxOrder) || (atoms_size == 0))
    7267      continue;
    7368    for (AtomIdSet::const_iterator atomiter = atoms.begin();
     
    8782  LOG(2, "DEBUG: There are " << atomkeyset.size() << " entries in lookup.");
    8883
     84  return atomkeyset;
     85}
     86
     87static Vector getAtomIdSetCenter(
     88    const AtomIdSet &_atoms)
     89{
     90  const molecule * const _mol = (*_atoms.begin())->getMolecule();
     91  const size_t atoms_size = _atoms.getAtomIds().size();
     92  Vector center;
     93  for (AtomIdSet::const_iterator iter = _atoms.begin();
     94      iter != _atoms.end(); ++iter) {
     95    center += (*iter)->getPosition();
     96    ASSERT ( _mol == (*iter)->getMolecule(),
     97        "getAtomIdSetCenter() - ids in same keyset belong to different molecule.");
     98  }
     99  center *= 1./(double)atoms_size;
     100
     101  return center;
     102}
     103
     104Interfragmenter::candidates_t Interfragmenter::getNeighborsOutsideMolecule(
     105    const AtomIdSet &_atoms,
     106    double _Rcut,
     107    const enum HydrogenTreatment _treatment) const
     108{
     109  /// go through linked cell and get all neighboring atoms up to Rcut
     110  const LinkedCell::LinkedCell_View view = World::getInstance().getLinkedCell(_Rcut);
     111  const Vector center = getAtomIdSetCenter(_atoms);
     112  const LinkedCell::LinkedList neighbors = view.getAllNeighbors(_Rcut, center);
     113  LOG(4, "DEBUG: Obtained " << neighbors.size() << " neighbors in distance of "
     114      << _Rcut << " around " << center << ".");
     115
     116  /// remove all atoms that belong to same molecule as does one of the
     117  /// fragment's atoms
     118  const molecule * const _mol = (*_atoms.begin())->getMolecule();
     119  candidates_t candidates;
     120  candidates.reserve(neighbors.size());
     121  for (LinkedCell::LinkedList::const_iterator iter = neighbors.begin();
     122      iter != neighbors.end(); ++iter) {
     123    const atom * const _atom = static_cast<const atom * const >(*iter);
     124    ASSERT( _atom != NULL,
     125        "Interfragmenter::getNeighborsOutsideMolecule() - a neighbor is not actually an atom?");
     126    if ((_atom->getMolecule() != _mol)
     127        && (_atom->getPosition().DistanceSquared(center) < _Rcut*_Rcut)
     128        && ((_treatment == IncludeHydrogen) || (_atom->getType()->getAtomicNumber() != 1))) {
     129      candidates.push_back(_atom);
     130    }
     131  }
     132  LOG(3, "DEBUG: There remain " << candidates.size() << " candidates.");
     133
     134  return candidates;
     135}
     136
     137Interfragmenter::atomkeyset_t Interfragmenter::getCandidatesSpecificKeySetMap(
     138    const candidates_t &_candidates,
     139    const atomkeyset_t &_atomkeyset) const
     140{
     141  atomkeyset_t fragmentmap;
     142  for (candidates_t::const_iterator candidateiter = _candidates.begin();
     143      candidateiter != _candidates.end(); ++candidateiter) {
     144    const atom * _atom = *candidateiter;
     145    atomkeyset_t::const_iterator iter = _atomkeyset.find(_atom);
     146    ASSERT( iter != _atomkeyset.end(),
     147        "Interfragmenter::getAtomSpecificKeySetMap() - could not find atom "
     148        +toString(_atom->getId())+" in lookup.");
     149    fragmentmap.insert( std::make_pair( _atom, iter->second) );
     150  }
     151  LOG(4, "DEBUG: Copied part of lookup map contains " << fragmentmap.size() << " keys.");
     152
     153  return fragmentmap;
     154}
     155
     156void Interfragmenter::combineFragments(
     157    const size_t _MaxOrder,
     158    const candidates_t &_candidates,
     159    atomkeyset_t &_fragmentmap,
     160    const KeySet &_keyset,
     161    Graph &_InterFragments,
     162    int &_counter)
     163{
     164  for (candidates_t::const_iterator candidateiter = _candidates.begin();
     165      candidateiter != _candidates.end(); ++candidateiter) {
     166    const atom *_atom = *candidateiter;
     167    LOG(3, "DEBUG: Current candidate is " << *_atom << ".");
     168    atomkeyset_t::iterator finditer = _fragmentmap.find(_atom);
     169    ASSERT( finditer != _fragmentmap.end(),
     170        "Interfragmenter::combineFragments() - could not find atom "
     171        +toString(_atom->getId())+" in fragment specific lookup.");
     172    keysets_t &othersets = finditer->second;
     173    ASSERT( !othersets.empty(),
     174        "Interfragmenter::combineFragments() - keysets to "+toString(_atom->getId())+
     175        "is empty.");
     176    keysets_t::iterator otheriter = othersets.begin();
     177    while (otheriter != othersets.end()) {
     178      const KeySet &otherset = **otheriter;
     179      LOG(3, "DEBUG: Current keyset is " << otherset << ".");
     180      // only add them one way round and not the other
     181      if (otherset < _keyset) {
     182        ++otheriter;
     183        continue;
     184      }
     185      // only add if combined they don't exceed the desired maxorder
     186      if (otherset.size() + _keyset.size() > _MaxOrder) {
     187        LOG(3, "INFO: Rejecting " << otherset << " as in sum their orders exceed " << _MaxOrder);
     188        ++otheriter;
     189        continue;
     190      }
     191      KeySet newset(otherset);
     192      newset.insert(_keyset.begin(), _keyset.end());
     193      LOG(3, "DEBUG: Inserting new combined set " << newset << ".");
     194      _InterFragments.insert( std::make_pair(newset, std::make_pair(++_counter, 1.)));
     195      // finally, remove the set such that no other combination exists
     196      otheriter = othersets.erase(otheriter);
     197    }
     198  }
     199}
     200
     201void Interfragmenter::operator()(
     202    const size_t MaxOrder,
     203    const double Rcut,
     204    const enum HydrogenTreatment treatment)
     205{
     206  atomkeyset_t atomkeyset = getAtomKeySetMap(MaxOrder);
     207
    89208  Graph InterFragments;
    90209  int counter = TotalGraph.size();
     
    101220      continue;
    102221
    103     /// go through linked cell and get all neighboring atoms up to Rcut
    104     Vector center;
    105     const molecule *_mol = (*atoms.begin())->getMolecule();
    106     for (AtomIdSet::const_iterator iter = atoms.begin();
    107         iter != atoms.end(); ++iter) {
    108       center += (*iter)->getPosition();
    109       ASSERT ( _mol == (*iter)->getMolecule(),
    110           "Interfragmenter::operator() - ids in same keyset belong to different molecule.");
    111     }
    112     center *= 1./(double)atoms_size;
    113     LinkedCell::LinkedCell_View view = World::getInstance().getLinkedCell(Rcut);
    114     LinkedCell::LinkedList neighbors = view.getAllNeighbors(Rcut, center);
    115     LOG(4, "DEBUG: Obtained " << neighbors.size() << " neighbors in distance of "
    116         << Rcut << " around " << center << ".");
    117 
    118     /// remove all atoms that belong to same molecule as does one of the
    119     /// fragment's atoms
    120     typedef std::vector<const atom *> candidates_t;
    121     candidates_t candidates;
    122     candidates.reserve(neighbors.size());
    123     for (LinkedCell::LinkedList::const_iterator iter = neighbors.begin();
    124         iter != neighbors.end(); ++iter) {
    125       const atom * const _atom = static_cast<const atom * const >(*iter);
    126       ASSERT( _atom != NULL,
    127           "Interfragmenter::operator() - a neighbor is not actually an atom?");
    128       if ((_atom->getMolecule() != _mol)
    129           && (_atom->getPosition().DistanceSquared(center) < Rcut*Rcut)
    130           && ((treatment == IncludeHydrogen) || (_atom->getType()->getAtomicNumber() != 1))) {
    131         candidates.push_back(_atom);
    132       }
    133     }
    134     LOG(3, "DEBUG: There remain " << candidates.size() << " candidates.");
     222    // get neighboring atoms outside the current molecule
     223    candidates_t candidates = getNeighborsOutsideMolecule(atoms, Rcut, treatment);
    135224
    136225    // create a lookup specific to this fragment
    137     atomkeyset_t fragmentmap;
    138     for (candidates_t::const_iterator candidateiter = candidates.begin();
    139         candidateiter != candidates.end(); ++candidateiter) {
    140       const atom * _atom = *candidateiter;
    141       atomkeyset_t::const_iterator iter = atomkeyset.find(_atom);
    142       ASSERT( iter != atomkeyset.end(),
    143           "Interfragmenter::operator() - could not find atom "
    144           +toString(_atom->getId())+" in lookup.");
    145       fragmentmap.insert( std::make_pair( _atom, iter->second) );
    146     }
    147     LOG(4, "DEBUG: Copied part of lookup map contains " << fragmentmap.size() << " keys.");
     226    atomkeyset_t fragmentmap = getCandidatesSpecificKeySetMap(candidates, atomkeyset);
    148227
    149228    /// combine each remaining fragment with current fragment to a new fragment
    150     /// if keyset is less
    151     for (candidates_t::const_iterator candidateiter = candidates.begin();
    152         candidateiter != candidates.end(); ++candidateiter) {
    153       const atom *_atom = *candidateiter;
    154       LOG(3, "DEBUG: Current candidate is " << *_atom << ".");
    155       atomkeyset_t::iterator finditer = fragmentmap.find(_atom);
    156       ASSERT( finditer != fragmentmap.end(),
    157           "Interfragmenter::operator() - could not find atom "
    158           +toString(_atom->getId())+" in fragment specific lookup.");
    159       keysets_t &othersets = finditer->second;
    160       keysets_t::iterator otheriter = othersets.begin();
    161       while (otheriter != othersets.end()) {
    162         const KeySet &otherset = **otheriter;
    163         LOG(3, "DEBUG: Current keyset is " << otherset << ".");
    164         // only add them one way round and not the other
    165         if (otherset < keyset) {
    166           ++otheriter;
    167           continue;
    168         }
    169         KeySet newset(otherset);
    170         newset.insert(keyset.begin(), keyset.end());
    171         LOG(3, "DEBUG: Inserting new combined set " << newset << ".");
    172         InterFragments.insert( std::make_pair(newset, std::make_pair(++counter, 1.)));
    173         // finally, remove the set such that no other combination exists
    174         otheriter = othersets.erase(otheriter);
    175       }
    176     }
     229    /// if keyset is less (to prevent addding same inter-fragment twice)
     230    combineFragments(MaxOrder, candidates, fragmentmap, keyset, InterFragments, counter);
    177231  }
    178232
     
    181235  TotalGraph.InsertGraph(InterFragments, counter);
    182236}
     237
     238double Interfragmenter::findLargestCutoff(
     239    const size_t _MaxOrder,
     240    const double _upperbound,
     241    const enum HydrogenTreatment _treatment) const
     242{
     243  double Rcut = _upperbound*_upperbound;
     244  std::pair<atomId_t, atomId_t> ClosestPair;
     245  // place all atoms into LC grid with some upper bound
     246  const LinkedCell::LinkedCell_View view = World::getInstance().getLinkedCell(_upperbound);
     247
     248  atomkeyset_t atomkeyset = getAtomKeySetMap(_MaxOrder);
     249
     250  // go through each atom and find closest atom not in the same keyset
     251  for (Graph::const_iterator keysetiter = TotalGraph.begin();
     252      keysetiter != TotalGraph.end(); ++keysetiter) {
     253    const KeySet &keyset = keysetiter->first;
     254    LOG(2, "DEBUG: Current keyset is " << keyset);
     255    const AtomIdSet atoms(keyset);
     256
     257    // get neighboring atoms outside the current molecule
     258    const candidates_t candidates = getNeighborsOutsideMolecule(atoms, _upperbound, _treatment);
     259    const Vector center = getAtomIdSetCenter(atoms);
     260
     261    for (candidates_t::const_iterator candidateiter = candidates.begin();
     262        candidateiter != candidates.end(); ++candidateiter) {
     263      atom const * const Walker = *candidateiter;
     264      // go through each atom in set and pick minimal distance
     265      for (AtomIdSet::const_iterator setiter = atoms.begin(); setiter != atoms.end(); ++setiter) {
     266        const double distanceSquared = Walker->getPosition().DistanceSquared(center);
     267        // pick the smallest compared to current Rcut if smaller
     268        if (distanceSquared < Rcut) {
     269          Rcut = distanceSquared;
     270          ClosestPair.first = (*setiter)->getId();
     271          ClosestPair.second = Walker->getId();
     272          LOG(2, "DEBUG: Found new pair " << ClosestPair << " with distance " << sqrt(Rcut));
     273        }
     274      }
     275    }
     276  }
     277  const double largest_distance = sqrt(Rcut);
     278  LOG(1, "INFO: Largest inter-fragment distance to cause no additional fragments: "
     279      << largest_distance);
     280
     281  return largest_distance;
     282}
Note: See TracChangeset for help on using the changeset viewer.