source: src/Actions/PotentialAction/FitPartialChargesAction.cpp@ 91f907

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests 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_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 FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix 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 91f907 was 91f907, checked in by Frederik Heber <heber@…>, 9 years ago

FitPartialChargesAction only makes unique particles.

  • i.e. we give the same particle to two given atom, if the fit for either one has been made to the the same set of graphs.
  • Property mode set to 100644
File size: 19.9 KB
RevLine 
[c4a323]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2013 Frederik Heber. All rights reserved.
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/>.
21 */
22
23/*
[50d49d]24 * FitPartialChargesAction.cpp
[c4a323]25 *
26 * Created on: Jul 03, 2013
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35// needs to come before MemDebug due to placement new
36#include <boost/archive/text_iarchive.hpp>
37
38#include "CodePatterns/MemDebug.hpp"
39
40#include "Atom/atom.hpp"
41#include "CodePatterns/Log.hpp"
42#include "Fragmentation/Exporters/ExportGraph_ToFiles.hpp"
43#include "Fragmentation/Graph.hpp"
44#include "World.hpp"
45
[01120c]46#include <boost/bimap.hpp>
[91f907]47#include <boost/bimap/multiset_of.hpp>
[a9099d]48#include <boost/bind.hpp>
[c4a323]49#include <boost/filesystem.hpp>
50#include <boost/foreach.hpp>
51#include <algorithm>
[9b68fc]52#include <functional>
[c4a323]53#include <iostream>
54#include <string>
55
[50d49d]56#include "Actions/PotentialAction/FitPartialChargesAction.hpp"
[c4a323]57
58#include "Potentials/PartialNucleiChargeFitter.hpp"
59
[01120c]60#include "AtomIdSet.hpp"
61#include "Descriptors/AtomIdDescriptor.hpp"
[c4a323]62#include "Element/element.hpp"
[2082637]63#include "Element/periodentafel.hpp"
[d8ed62]64#include "Fragmentation/Homology/AtomFragmentsMap.hpp"
[c4a323]65#include "Fragmentation/Homology/HomologyContainer.hpp"
66#include "Fragmentation/Homology/HomologyGraph.hpp"
67#include "Fragmentation/Summation/SetValues/SamplingGrid.hpp"
68#include "FunctionApproximation/Extractors.hpp"
69#include "Potentials/PartialNucleiChargeFitter.hpp"
[708ec1]70#include "Potentials/Particles/ParticleFactory.hpp"
71#include "Potentials/Particles/ParticleRegistry.hpp"
[c4a323]72#include "Potentials/SerializablePotential.hpp"
73#include "World.hpp"
74
75using namespace MoleCuilder;
76
77// and construct the stuff
[50d49d]78#include "FitPartialChargesAction.def"
[c4a323]79#include "Action_impl_pre.hpp"
80/** =========== define the function ====================== */
81
[91f907]82namespace detail {
83 typedef std::map<KeySet, HomologyGraph> KeysetsToGraph_t;
84
85 typedef std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> GraphFittedChargeMap_t;
86
87 typedef std::map<atomId_t, double> fitted_charges_t;
88
89 typedef std::map<HomologyGraph, size_t> GraphIndex_t;
90
91 typedef std::set<size_t> AtomsGraphIndices_t;
92 typedef boost::bimaps::bimap<
93 AtomsGraphIndices_t,
94 boost::bimaps::multiset_of<atomId_t> > GraphIndices_t;
95
96 typedef std::map<atomId_t, std::string> AtomParticleNames_t;
97
98 typedef std::map<std::set<size_t>, std::string> GraphToNameMap_t;
99};
100
[01120c]101static void enforceZeroTotalCharge(
[d8ed62]102 PartialNucleiChargeFitter::charges_t &_averaged_charges)
103{
104 double charge_sum = 0.;
105 charge_sum = std::accumulate(_averaged_charges.begin(), _averaged_charges.end(), charge_sum);
106 if (fabs(charge_sum) > MYEPSILON) {
107 std::transform(
108 _averaged_charges.begin(), _averaged_charges.end(),
109 _averaged_charges.begin(),
110 boost::bind(std::minus<double>(), _1, charge_sum/_averaged_charges.size()));
[c4a323]111 }
[d8ed62]112 charge_sum = 0.;
113 charge_sum = std::accumulate(_averaged_charges.begin(), _averaged_charges.end(), charge_sum);
114 ASSERT( fabs(charge_sum) < MYEPSILON,
115 "enforceZeroTotalCharge() - enforcing neutral net charge failed, "
116 +toString(charge_sum)+" is the remaining net charge.");
[01120c]117
118 LOG(2, "DEBUG: final charges with net zero charge are " << _averaged_charges);
[d8ed62]119}
[9b68fc]120
[01120c]121static size_t obtainAverageChargesOverFragments(
[d8ed62]122 PartialNucleiChargeFitter::charges_t &_average_charges,
123 const std::pair<
124 HomologyContainer::const_iterator,
125 HomologyContainer::const_iterator> &_range,
126 const double _radius
127 )
128{
129 HomologyContainer::const_iterator iter = _range.first;
[c4a323]130 if (!iter->second.containsGrids) {
[d8ed62]131 ELOG(1, "This HomologyGraph does not contain sampled grids.");
132 return 0;
[c4a323]133 }
[d8ed62]134 _average_charges.resize(iter->second.fragment.getCharges().size(), 0.);
[9b68fc]135 size_t NoFragments = 0;
136 for (;
[d8ed62]137 iter != _range.second; ++iter, ++NoFragments) {
[9b68fc]138 if (!iter->second.containsGrids) {
139 ELOG(2, "This HomologyGraph does not contain sampled grids,\ndid you forget to add '--store-grids 1' to AnalyseFragmentResults.");
[d8ed62]140 return 0;
[9b68fc]141 }
142 const Fragment &fragment = iter->second.fragment;
143 // const double &energy = iter->second.energy;
144 // const SamplingGrid &charge = iter->second.charge_distribution;
145 const SamplingGrid &potential = iter->second.potential_distribution;
146 if ((potential.level == 0)
147 || ((potential.begin[0] == potential.end[0])
148 && (potential.begin[1] == potential.end[1])
149 && (potential.begin[2] == potential.end[2]))) {
150 ELOG(1, "Sampled grid contains grid made of zero points.");
[d8ed62]151 return 0;
[9b68fc]152 }
153
154 // then we extract positions from fragment
155 PartialNucleiChargeFitter::positions_t positions;
156 Fragment::positions_t fragmentpositions = fragment.getPositions();
157 positions.reserve(fragmentpositions.size());
158 BOOST_FOREACH( Fragment::position_t pos, fragmentpositions) {
159 positions.push_back( Vector(pos[0], pos[1], pos[2]) );
160 }
[d8ed62]161 PartialNucleiChargeFitter fitter(potential, positions, _radius);
[9b68fc]162 fitter();
163 PartialNucleiChargeFitter::charges_t return_charges = fitter.getSolutionAsCharges_t();
[d8ed62]164 LOG(2, "DEBUG: fitted charges are " << return_charges);
[9b68fc]165 std::transform(
166 return_charges.begin(), return_charges.end(),
[d8ed62]167 _average_charges.begin(),
168 _average_charges.begin(),
[9b68fc]169 std::plus<PartialNucleiChargeFitter::charge_t>());
[c4a323]170 }
[d8ed62]171 if (NoFragments != 0)
172 std::transform(_average_charges.begin(), _average_charges.end(),
173 _average_charges.begin(),
174 std::bind1st(std::multiplies<PartialNucleiChargeFitter::charge_t>(),1./(double)NoFragments)
175 );
176 LOG(2, "DEBUG: final averaged charges are " << _average_charges);
177
178 return NoFragments;
179}
180
[01120c]181inline SerializablePotential::ParticleTypes_t
182getParticleTypesForAtomIdSet(const AtomIdSet &_atoms)
183{
184 SerializablePotential::ParticleTypes_t particletypes;
185 particletypes.resize(_atoms.size());
186 std::transform(
187 _atoms.begin(), _atoms.end(),
188 particletypes.begin(),
189 boost::bind(&atom::getElementNo, _1));
190 return particletypes;
191}
192
[c1ec8e]193static
194std::set<KeySet> accumulateKeySetsForAtoms(
195 const AtomFragmentsMap::AtomFragmentsMap_t &_atommap,
196 const std::vector<const atom *> &_selected_atoms)
[d8ed62]197{
[01120c]198 std::set<KeySet> fragments;
[c1ec8e]199 for (std::vector<const atom *>::const_iterator iter = _selected_atoms.begin();
200 iter != _selected_atoms.end(); ++iter) {
201 const atomId_t atomid = (*iter)->getId();
[d8ed62]202 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator atomiter =
[c1ec8e]203 _atommap.find(atomid);
204 if ((*iter)->getElementNo() != 1) {
205 if (atomiter == _atommap.end()) {
206 ELOG(2, "There are no fragments associated to " << atomid << ".");
[01120c]207 continue;
208 }
209 const AtomFragmentsMap::keysets_t &keysets = atomiter->second;
[c1ec8e]210 LOG(2, "DEBUG: atom " << atomid << " has " << keysets.size() << " fragments.");
[01120c]211 fragments.insert( keysets.begin(), keysets.end() );
212 } else {
[c1ec8e]213 LOG(3, "DEBUG: Skipping atom " << atomid << " as it's hydrogen.");
[a9099d]214 }
215 }
[c1ec8e]216 return fragments;
217}
[a9099d]218
[c1ec8e]219static
220void getKeySetsToGraphMapping(
[91f907]221 detail::KeysetsToGraph_t &_keyset_graphs,
222 detail::GraphFittedChargeMap_t &_fittedcharges_per_fragment,
[c1ec8e]223 const std::set<KeySet> &_fragments,
224 const AtomFragmentsMap &_atomfragments)
225{
226 for (std::set<KeySet>::const_iterator fragmentiter = _fragments.begin();
227 fragmentiter != _fragments.end(); ++fragmentiter) {
[01120c]228 const KeySet &keyset = *fragmentiter;
[c1ec8e]229 const AtomFragmentsMap::indices_t &forceindices = _atomfragments.getFullKeyset(keyset);
[01120c]230 ASSERT( !forceindices.empty(),
[c1ec8e]231 "getKeySetsToGraphMapping() - force keyset to "+toString(keyset)+" is empty.");
[01120c]232 KeySet forcekeyset;
233 forcekeyset.insert(forceindices.begin(), forceindices.end());
234 forcekeyset.erase(-1);
235 const HomologyGraph graph(forcekeyset);
236 LOG(2, "DEBUG: Associating keyset " << forcekeyset << " with graph " << graph);
[c1ec8e]237 _keyset_graphs.insert( std::make_pair(keyset, graph) );
238 _fittedcharges_per_fragment.insert( std::make_pair(graph, PartialNucleiChargeFitter::charges_t()) );
[01120c]239 }
[c1ec8e]240}
[d8ed62]241
[c1ec8e]242static
243bool getPartialChargesForAllGraphs(
[91f907]244 detail::GraphFittedChargeMap_t &_fittedcharges_per_fragment,
[c1ec8e]245 const HomologyContainer &_homologies,
246 const double _mask_radius,
247 const bool enforceZeroCharge)
248{
[91f907]249 for (detail::GraphFittedChargeMap_t::iterator graphiter = _fittedcharges_per_fragment.begin();
[c1ec8e]250 graphiter != _fittedcharges_per_fragment.end(); ++graphiter) {
[01120c]251 const HomologyGraph &graph = graphiter->first;
252 LOG(2, "DEBUG: Now fitting charges to graph " << graph);
[c1ec8e]253 const HomologyContainer::range_t range = _homologies.getHomologousGraphs(graph);
[d8ed62]254 if (range.first == range.second) {
[c1ec8e]255 ELOG(0, "HomologyContainer does not contain specified fragment.");
256 return false;
[d8ed62]257 }
258
259 // fit and average partial charges over all homologous fragments
[01120c]260 PartialNucleiChargeFitter::charges_t &averaged_charges = graphiter->second;
[d8ed62]261 const size_t NoFragments =
[c1ec8e]262 obtainAverageChargesOverFragments(averaged_charges, range, _mask_radius);
[d8ed62]263 if ((NoFragments == 0) && (range.first != range.second)) {
[c1ec8e]264 ELOG(0, "Fitting for fragment "+toString(*graphiter)+" failed.");
265 return false;
[d8ed62]266 }
267
268 // make sum of charges zero if desired
[c1ec8e]269 if (enforceZeroCharge)
[d8ed62]270 enforceZeroTotalCharge(averaged_charges);
271
272 // output status info fitted charges
[01120c]273 LOG(2, "DEBUG: For fragment " << *graphiter << " we have fitted the following charges "
[d8ed62]274 << averaged_charges << ", averaged over " << NoFragments << " fragments.");
275 }
[c1ec8e]276 return true;
277}
[d8ed62]278
[c1ec8e]279double fitAverageChargeToAtom(
280 const atom * const _walker,
281 const AtomFragmentsMap &_atomfragments,
[91f907]282 const detail::KeysetsToGraph_t &_keyset_graphs,
283 const detail::GraphFittedChargeMap_t &_fittedcharges_per_fragment)
[c1ec8e]284{
285 const atom * surrogate = _walker;
286 if (surrogate->getElementNo() == 1) {
287 // it's hydrogen, check its bonding and use its bond partner instead to request
288 // keysets
289 const BondList &ListOfBonds = surrogate->getListOfBonds();
290 if ( ListOfBonds.size() != 1) {
291 ELOG(1, "Solitary hydrogen in atom " << surrogate->getId() << " detected, skipping.");
292 return 0.;
[d8ed62]293 }
[c1ec8e]294 surrogate = (*ListOfBonds.begin())->GetOtherAtom(surrogate);
295 }
296 const atomId_t walkerid = surrogate->getId();
297 const AtomFragmentsMap::AtomFragmentsMap_t &atommap = _atomfragments.getMap();
298 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator keysetsiter =
299 atommap.find(walkerid);
300 ASSERT(keysetsiter != atommap.end(),
301 "fitAverageChargeToAtom() - we checked already that "+toString(walkerid)
302 +" should be present!");
303 const AtomFragmentsMap::keysets_t & keysets = keysetsiter->second;
304
305 double average_charge = 0.;
306 size_t NoFragments = 0;
307 // go over all fragments associated to this atom
308 for (AtomFragmentsMap::keysets_t::const_iterator keysetsiter = keysets.begin();
309 keysetsiter != keysets.end(); ++keysetsiter) {
310 const KeySet &keyset = *keysetsiter;
311
312 const AtomFragmentsMap::indices_t &forcekeyset = _atomfragments.getFullKeyset(keyset);
313 ASSERT( !forcekeyset.empty(),
314 "fitAverageChargeToAtom() - force keyset to "+toString(keyset)+" is empty.");
315
316 // find the associated charge in the charge vector
[91f907]317 const std::map<KeySet, HomologyGraph>::const_iterator keysetgraphiter =
[c1ec8e]318 _keyset_graphs.find(keyset);
319 ASSERT( keysetgraphiter != _keyset_graphs.end(),
320 "fitAverageChargeToAtom() - keyset "+toString(keyset)
321 +" not contained in keyset_graphs.");
322 const HomologyGraph &graph = keysetgraphiter->second;
[91f907]323 const detail::GraphFittedChargeMap_t::const_iterator chargesiter =
[c1ec8e]324 _fittedcharges_per_fragment.find(graph);
325 ASSERT(chargesiter != _fittedcharges_per_fragment.end(),
326 "fitAverageChargeToAtom() - no charge to "+toString(keyset)
327 +" any longer present in fittedcharges_per_fragment?");
328 const PartialNucleiChargeFitter::charges_t &charges = chargesiter->second;
329 ASSERT( charges.size() == forcekeyset.size(),
330 "fitAverageChargeToAtom() - charges "+toString(charges.size())+" and keyset "
331 +toString(forcekeyset.size())+" do not have the same length?");
332 PartialNucleiChargeFitter::charges_t::const_iterator chargeiter =
333 charges.begin();
334 const AtomFragmentsMap::indices_t::const_iterator forcekeysetiter =
335 std::find(forcekeyset.begin(), forcekeyset.end(), _walker->getId());
336 ASSERT( forcekeysetiter != forcekeyset.end(),
337 "fitAverageChargeToAtom() - atom "+toString(_walker->getId())
338 +" not contained in force keyset "+toString(forcekeyset));
339 std::advance(chargeiter, std::distance(forcekeyset.begin(), forcekeysetiter));
340
341 // and add onto charge sum
342 const double & charge_in_fragment = *chargeiter;
343 average_charge += charge_in_fragment;
344 ++NoFragments;
[d8ed62]345 }
[c1ec8e]346 // average to obtain final partial charge for this atom
347 average_charge *= 1./(double)NoFragments;
[d8ed62]348
[c1ec8e]349 return average_charge;
350}
351
352void addToParticleRegistry(
353 const ParticleFactory &factory,
354 const periodentafel &periode,
[91f907]355 const detail::fitted_charges_t &_fitted_charges,
356 const detail::GraphIndices_t &_GraphIndices,
357 detail::AtomParticleNames_t &_atom_particlenames)
[c1ec8e]358{
[91f907]359 detail::GraphToNameMap_t GraphToNameMap;
360 for (detail::fitted_charges_t::const_iterator chargeiter = _fitted_charges.begin();
[c1ec8e]361 chargeiter != _fitted_charges.end(); ++chargeiter) {
[91f907]362 const atomId_t &atomid = chargeiter->first;
363 const detail::GraphIndices_t::right_const_iterator graphiter = _GraphIndices.right.find(atomid);
364 const detail::GraphToNameMap_t::const_iterator nameiter = GraphToNameMap.find(graphiter->second);
365 std::string name;
366 if (nameiter != GraphToNameMap.end()) {
367 name = nameiter->second;
368 } else {
369 const atom * const walker = World::getInstance().getAtom(AtomById(atomid));
370 ASSERT( walker != NULL,
371 "addToParticleRegistry() - atom "+toString(atomid)+" not present in the World?");
372 const double &charge = chargeiter->second;
373 const atomicNumber_t elementno = walker->getElementNo();
374 name = Particle::findFreeName(periode, elementno);
375 GraphToNameMap[graphiter->second] = name;
376 LOG(1, "INFO: Adding particle " << name << " for atom "
377 << *walker << " with element " << elementno << ", charge " << charge);
378 factory.createInstance(name, elementno, charge);
379 }
380 _atom_particlenames.insert( std::make_pair(atomid, name) );
[708ec1]381 }
[c1ec8e]382}
383
384ActionState::ptr PotentialFitPartialChargesAction::performCall()
385{
386 // check for selected atoms
387 const World &world = const_cast<const World &>(World::getInstance());
388 if (world.beginAtomSelection() == world.endAtomSelection()) {
389 STATUS("There are no atoms selected for fitting partial charges to.");
390 return Action::failure;
391 }
392
393 /// obtain possible fragments to each selected atom
394 const AtomFragmentsMap &atomfragments = AtomFragmentsMap::getConstInstance();
395 if (!atomfragments.checkCompleteness()) {
396 STATUS("AtomFragmentsMap failed internal consistency check, missing forcekeysets?");
397 return Action::failure;
398 }
399 std::set<KeySet> fragments =
400 accumulateKeySetsForAtoms( atomfragments.getMap(), world.getSelectedAtoms());
401
402 // reduce given fragments to homologous graphs to avoid multiple fittings
[91f907]403 detail::KeysetsToGraph_t keyset_graphs;
404 detail::GraphFittedChargeMap_t fittedcharges_per_fragment;
[c1ec8e]405 getKeySetsToGraphMapping(keyset_graphs, fittedcharges_per_fragment, fragments, atomfragments);
406
407 /// then go through all fragments and get partial charges for each
[91f907]408 const HomologyContainer &homologies = World::getInstance().getHomologies();
[c1ec8e]409 const bool status = getPartialChargesForAllGraphs(
410 fittedcharges_per_fragment,
[91f907]411 homologies,
[c1ec8e]412 params.radius.get(),
413 params.enforceZeroCharge.get());
414 if (!status)
415 return Action::failure;
416
417 /// obtain average charge for each atom the fitted charges over all its fragments
[91f907]418 detail::fitted_charges_t fitted_charges;
[c1ec8e]419 for (World::AtomSelectionConstIterator atomiter = world.beginAtomSelection();
420 atomiter != world.endAtomSelection(); ++atomiter) {
421 const double average_charge = fitAverageChargeToAtom(
422 atomiter->second, atomfragments, keyset_graphs, fittedcharges_per_fragment);
423
424 if (average_charge != 0.) {
425 LOG(2, "DEBUG: For atom " << atomiter->first << " we have an average charge of "
426 << average_charge);
427
428 fitted_charges.insert( std::make_pair(atomiter->first, average_charge) );
429 }
430 }
431
[91f907]432 /// make Particles be used for every atom that was fitted on the same number of graphs
433 detail::GraphIndex_t GraphIndex;
434 size_t index = 0;
435 for (HomologyContainer::const_key_iterator iter = homologies.key_begin();
436 iter != homologies.key_end(); iter = homologies.getNextKey(iter)) {
437 GraphIndex.insert( std::make_pair( *iter, index++));
438 }
439 LOG(2, "DEBUG: There are " << index << " unique graphs in the homology container.");
440
441 // go through every atom, get all graphs, convert to GraphIndex and store
442
443 detail::GraphIndices_t GraphIndices;
444 const AtomFragmentsMap::AtomFragmentsMap_t &atommap = atomfragments.getMap();
445 for (World::AtomSelectionConstIterator atomiter = world.beginAtomSelection();
446 atomiter != world.endAtomSelection(); ++atomiter) {
447 const atomId_t walkerid = atomiter->first;
448 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator keysetsiter =
449 atommap.find(walkerid);
450 ASSERT(keysetsiter != atommap.end(),
451 "PotentialFitPartialChargesAction::performCall() - we checked already that "
452 +toString(walkerid)+" should be present!");
453 const AtomFragmentsMap::keysets_t & keysets = keysetsiter->second;
454
455 detail::AtomsGraphIndices_t AtomsGraphIndices;
456
457 // go over all fragments associated to this atom
458 for (AtomFragmentsMap::keysets_t::const_iterator keysetsiter = keysets.begin();
459 keysetsiter != keysets.end(); ++keysetsiter) {
460 const KeySet &keyset = *keysetsiter;
461 const std::map<KeySet, HomologyGraph>::const_iterator keysetgraphiter =
462 keyset_graphs.find(keyset);
463 ASSERT( keysetgraphiter != keyset_graphs.end(),
464 "PotentialFitPartialChargesAction::performCall() - keyset "+toString(keyset)
465 +" not contained in keyset_graphs.");
466 const HomologyGraph &graph = keysetgraphiter->second;
467 const detail::GraphIndex_t::const_iterator indexiter = GraphIndex.find(graph);
468 ASSERT( indexiter != GraphIndex.end(),
469 "PotentialFitPartialChargesAction::performCall() - graph "+toString(graph)
470 +" not contained in GraphIndex.");
471 AtomsGraphIndices.insert( indexiter->second );
472 }
473 GraphIndices.left.insert( std::make_pair(AtomsGraphIndices, walkerid) );
474 LOG(2, "DEBUG: Atom " << *atomiter->second << " has graph indices " << AtomsGraphIndices);
475 }
476
[c1ec8e]477 /// place all fitted charges into ParticleRegistry
[91f907]478 detail::AtomParticleNames_t atom_particlenames;
[c1ec8e]479 addToParticleRegistry(
480 ParticleFactory::getConstInstance(),
481 *World::getInstance().getPeriode(),
[91f907]482 fitted_charges,
483 GraphIndices,
484 atom_particlenames);
485 LOG(1, "INFO: The atoms received the following particles " << atom_particlenames);
[c4a323]486
487 return Action::success;
488}
489
[50d49d]490ActionState::ptr PotentialFitPartialChargesAction::performUndo(ActionState::ptr _state) {
[c4a323]491 return Action::success;
492}
493
[50d49d]494ActionState::ptr PotentialFitPartialChargesAction::performRedo(ActionState::ptr _state){
[c4a323]495 return Action::success;
496}
497
[50d49d]498bool PotentialFitPartialChargesAction::canUndo() {
[c4a323]499 return false;
500}
501
[50d49d]502bool PotentialFitPartialChargesAction::shouldUndo() {
[c4a323]503 return false;
504}
505/** =========== end of function ====================== */
Note: See TracBrowser for help on using the repository browser.