source: src/Fragmentation/Summation/Containers/FragmentationLongRangeResults.cpp@ 8eafd6

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 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 8eafd6 was 0ba27c9, checked in by Frederik Heber <heber@…>, 9 years ago

FragmentationLongRangeResults now takes additional implicit charge indices.

  • this is required as we obtain more force vectors from the long-range calculations as we have indices for. This is because implicit charges are not associated to any fragment, hence their indices are unknown. However, we nonetheless submit them as extra particles/nuclei to the long-range solver and hence obtain long-range forces for each of them.
  • Property mode set to 100644
File size: 13.1 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * FragmentationLongRangeResults.cpp
26 *
27 * Created on: Aug 31, 2012
28 * Author: heber
29 */
30
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include "FragmentationLongRangeResults.hpp"
40
41#include <boost/mpl/for_each.hpp>
42#include <boost/mpl/remove.hpp>
43#include <sstream>
44
45#include "CodePatterns/Assert.hpp"
46#include "CodePatterns/Log.hpp"
47
48#include "Fragmentation/KeySetsContainer.hpp"
49#include "Fragmentation/parseKeySetFile.hpp"
50#include "Fragmentation/Summation/Converter/DataConverter.hpp"
51#include "Fragmentation/Summation/Containers/createMatrixNrLookup.hpp"
52#include "Fragmentation/Summation/Containers/extractJobIds.hpp"
53#include "Fragmentation/Summation/AllLevelOrthogonalSummator.hpp"
54#include "Fragmentation/Summation/IndexSetContainer.hpp"
55#include "Fragmentation/Summation/OrthogonalSumUpPerLevel.hpp"
56#include "Fragmentation/Summation/SubsetMap.hpp"
57#include "Fragmentation/Summation/SumUpPerLevel.hpp"
58
59#include "Helpers/defs.hpp"
60
61FragmentationLongRangeResults::FragmentationLongRangeResults(
62 const std::map<JobId_t,MPQCData> &fragmentData,
63 std::map<JobId_t,VMGData> &longrangeData,
64 const KeySetsContainer& _KeySet,
65 const KeySetsContainer& _ForceKeySet) :
66 KeySet(_KeySet),
67 ForceKeySet(_ForceKeySet),
68 hasForces((!longrangeData.empty()) && (longrangeData.begin()->second.hasForces))
69{
70 initLookups(fragmentData, longrangeData);
71
72 // convert KeySetContainer to IndexSetContainer
73 container.reset(new IndexSetContainer(KeySet));
74 // create the map of all keysets
75 subsetmap.reset(new SubsetMap(*container));
76}
77
78void FragmentationLongRangeResults::initLookups(
79 const std::map<JobId_t,MPQCData> &fragmentData,
80 std::map<JobId_t,VMGData> &longrangeData
81 )
82{
83 // create lookup from job nr to fragment number
84 {
85 size_t MPQCFragmentCounter = 0;
86 std::vector<bool> ValueMask(fragmentData.size(), true);
87 const std::vector<JobId_t> mpqcjobids = extractJobIds<MPQCData>(fragmentData);
88 MPQCMatrixNrLookup =
89 createMatrixNrLookup(mpqcjobids, MPQCFragmentCounter, ValueMask);
90 }
91
92 {
93 size_t VMGFragmentCounter = 0;
94 std::vector<bool> ValueMask(longrangeData.size(), true);
95 const std::vector<JobId_t> vmgjobids = extractJobIds<VMGData>(longrangeData);
96 VMGMatrixNrLookup =
97 createMatrixNrLookup(vmgjobids, VMGFragmentCounter, ValueMask);
98 }
99}
100
101void FragmentationLongRangeResults::operator()(
102 const std::map<JobId_t,MPQCData> &fragmentData,
103 std::map<JobId_t,VMGData> &longrangeData,
104 const std::vector<VMGData> &fullsolutionData,
105 const std::vector<SamplingGrid> &full_sample,
106 const IndexedVectors::indices_t &_implicit_charges_indices)
107{
108 MaxLevel = subsetmap->getMaximumSetLevel();
109 LOG(1, "INFO: Summing up results till level " << MaxLevel << ".");
110 /// convert all MPQCData to MPQCDataMap_t
111 {
112 ASSERT( ForceKeySet.KeySets.size() == fragmentData.size(),
113 "FragmentationLongRangeResults::FragmentationLongRangeResults() - ForceKeySet's KeySets and fragmentData differ in size.");
114
115 OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCData, MPQCDataGridVector_t>(
116 fragmentData, MPQCMatrixNrLookup, container, subsetmap,
117 Result_Grid_fused, Result_perIndexSet_Grid);
118
119 // multiply each short-range potential with the respective charge
120 std::map<JobId_t,MPQCData>::const_iterator mpqciter = fragmentData.begin();
121 std::map<JobId_t,VMGData>::iterator vmgiter = longrangeData.begin();
122 for (; vmgiter != longrangeData.end(); ++mpqciter, ++vmgiter) {
123 vmgiter->second.sampled_potential *= mpqciter->second.sampled_grid;
124 }
125 // then sum up
126 OrthogonalSumUpPerLevel<VMGDataMap_t, VMGData, VMGDataVector_t>(
127 longrangeData, VMGMatrixNrLookup, container, subsetmap,
128 Result_LongRange_fused, Result_perIndexSet_LongRange);
129
130 IndexedVectors::indices_t fullindices;
131 if (hasLongRangeForces()) {
132 // force has extra data converter (this is similar to MPQCData's forces
133 std::map<JobId_t, VMGDataForceMap_t> VMGData_Force_fused;
134 convertDatatoForceMap<VMGData, VMGDataForceMap_t, VMGDataFused>(
135 longrangeData, ForceKeySet, VMGData_Force_fused);
136 Result_ForceLongRange_fused.resize(MaxLevel); // we need the results of correct size already
137 AllLevelOrthogonalSummator<VMGDataForceMap_t> forceSummer(
138 subsetmap,
139 VMGData_Force_fused,
140 container->getContainer(),
141 VMGMatrixNrLookup,
142 Result_ForceLongRange_fused,
143 Result_perIndexSet_LongRange_Force);
144 boost::mpl::for_each<VMGDataForceVector_t>(boost::ref(forceSummer));
145 // build full force index set
146 KeySetsContainer::ArrayOfIntVectors::const_iterator arrayiter = ForceKeySet.KeySets.begin();
147 std::set<IndexedVectors::index_t> sorted_indices;
148 for (;arrayiter != ForceKeySet.KeySets.end(); ++arrayiter) {
149 sorted_indices.insert(arrayiter->begin(), arrayiter->end());
150 }
151 // add additionally those from implicit charges which are not associated to
152 // any fragment and hence are unknown so far.
153 sorted_indices.insert(_implicit_charges_indices.begin(), _implicit_charges_indices.end());
154 sorted_indices.erase(-1);
155 fullindices.insert(fullindices.begin(), sorted_indices.begin(), sorted_indices.end());
156 }
157
158 // then sum up
159 OrthogonalSumUpPerLevel<VMGDataGridMap_t, VMGData, VMGDataGridVector_t>(
160 longrangeData, VMGMatrixNrLookup, container, subsetmap,
161 Result_GridLongRange_fused, Result_perIndexSet_LongRange_Grid);
162
163 Result_LongRangeIntegrated_fused.reserve(MaxLevel);
164 // NOTE: potential for level 1 is wrongly calculated within a molecule
165 // as saturation hydrogen are not removed on this level yet
166 for (size_t level = 1; level <= MaxLevel; ++level) {
167 // We have calculated three different contributions: e-e, e-n+n-n, and n-n.
168 // And we want to have e-e+e-n, n-n+n-e (where e-n = n-e).
169 // For each of these three contributions we have a full solution and summed
170 // up short range solutions.
171
172 // first we obtain the full e-e energy as potential times charge on the
173 // respective level.
174 const SamplingGrid &charge_weight =
175 boost::fusion::at_key<MPQCDataFused::sampled_grid>(Result_Grid_fused[level-1]);
176 SamplingGrid full_sample_solution = fullsolutionData[level-1].sampled_potential;
177 full_sample_solution *= charge_weight;
178 double electron_solution_energy = full_sample_solution.integral();
179
180 // then we subtract the summed-up short-range e-e interaction energy from
181 // the full solution.
182 const SamplingGrid &short_range_correction =
183 boost::fusion::at_key<VMGDataFused::sampled_potential>(Result_GridLongRange_fused[level-1]);
184 double electron_short_range_energy = short_range_correction.integral();
185 full_sample_solution -= short_range_correction;
186 electron_solution_energy -= electron_short_range_energy;
187 ASSERT( fabs(electron_solution_energy - full_sample_solution.integral()) < 1e-7,
188 "FragmentationLongRangeResults::operator() - integral and energy are not exchangeable.");
189
190 // then, we obtain the e-n+n-n full solution in the same way
191 double nuclei_solution_energy = fullsolutionData[level-1].nuclei_long;
192 double nuclei_short_range_energy =
193 boost::fusion::at_key<VMGDataFused::nuclei_long>(Result_LongRange_fused[level-1]);
194 nuclei_solution_energy -= nuclei_short_range_energy;
195
196 // and also the e-n full solution
197 double both_solution_energy = fullsolutionData[level-1].electron_long;
198 double both_short_range_energy =
199 boost::fusion::at_key<VMGDataFused::electron_long>(Result_LongRange_fused[level-1]);
200 both_solution_energy -= both_short_range_energy;
201
202 // energies from interpolation at nuclei position has factor of 1/2 already
203 electron_solution_energy *= .5;
204 electron_short_range_energy *= .5;
205
206 // At last, we subtract e-n from n-n+e-n for full solution and short-range
207 // correction.
208 nuclei_solution_energy -= both_solution_energy;
209 nuclei_short_range_energy -= both_short_range_energy;
210
211 VMGDataLongRangeMap_t instance;
212 boost::fusion::at_key<VMGDataFused::electron_longrange>(instance) = electron_solution_energy;
213// LOG(0, "Remaining long-range potential integral of level " << level << " is "
214// << full_sample_solution.integral() << ".");
215 boost::fusion::at_key<VMGDataFused::electron_shortrange>(instance) = electron_short_range_energy;
216// LOG(0, "Short-range correction potential integral of level " << level << " is "
217// << short_range_correction.integral() << ".");
218 boost::fusion::at_key<VMGDataFused::mixed_longrange>(instance) = both_solution_energy;
219// LOG(0, "Remaining long-range energy from potential integral of level " << level << " is "
220// << full_solution_energy << ".");
221 boost::fusion::at_key<VMGDataFused::mixed_shortrange>(instance) = both_short_range_energy;
222// LOG(0, "Short-range correction energy from potential integral of level " << level << " is "
223// << short_range_energy << ".");
224 boost::fusion::at_key<VMGDataFused::nuclei_longrange>(instance) = nuclei_solution_energy;
225// LOG(0, "Remaining long-range energy from potential integral of level " << level << " is "
226// << full_solution_energy << ".");
227 boost::fusion::at_key<VMGDataFused::nuclei_shortrange>(instance) = nuclei_short_range_energy;
228// LOG(0, "Short-range correction energy from potential integral of level " << level << " is "
229// << short_range_energy << ".");
230 boost::fusion::at_key<VMGDataFused::total_longrange>(instance) =
231 boost::fusion::at_key<VMGDataFused::electron_longrange>(instance)
232 + 2.*boost::fusion::at_key<VMGDataFused::mixed_longrange>(instance)
233 + boost::fusion::at_key<VMGDataFused::nuclei_longrange>(instance);
234 boost::fusion::at_key<VMGDataFused::total_shortrange>(instance) =
235 boost::fusion::at_key<VMGDataFused::electron_shortrange>(instance)
236 + 2.*boost::fusion::at_key<VMGDataFused::mixed_shortrange>(instance)
237 + boost::fusion::at_key<VMGDataFused::nuclei_shortrange>(instance);
238 Result_LongRangeIntegrated_fused.push_back(instance);
239
240 if (hasLongRangeForces()) {
241 VMGDataLongRangeForceMap_t forceinstance;
242 IndexedVectors fullforces( fullindices, fullsolutionData[level-1].forces);
243 IndexedVectors longrangeforces =
244 boost::fusion::at_key<VMGDataFused::forces>(Result_ForceLongRange_fused[level-1]);
245 boost::fusion::at_key<VMGDataFused::forces_shortrange>(forceinstance) =
246 fullforces;
247 fullforces -= longrangeforces;
248 boost::fusion::at_key<VMGDataFused::forces_longrange>(forceinstance) =
249 fullforces;
250 Result_ForcesLongRangeIntegrated_fused.push_back(forceinstance);
251 }
252 }
253// {
254// // LOG(0, "Remaining long-range energy from energy_potential is " << full_sample_solution.integral()-epotentialSummer.getFullContribution() << ".");
255// SamplingGrid full_sample_solution = fullsolutionData.back().sampled_potential;
256// const SamplingGrid &short_range_correction =
257// boost::fusion::at_key<VMGDataFused::sampled_potential>(Result_GridLongRange_fused.back()).getFullContribution();
258// full_sample_solution -= short_range_correction;
259// // multiply element-wise with charge distribution
260// LOG(0, "Remaining long-range potential integral is " << full_sample_solution.integral() << ".");
261// LOG(0, "Short-range correction potential integral of level is " << short_range_correction.integral() << ".");
262// LOG(0, "Remaining long-range energy from potential integral is "
263// << full_sample_solution.integral(full_sample.back()) << ".");
264// LOG(0, "Short-range correction energy from potential integral is "
265// << short_range_correction.integral(full_sample.back()) << ".");
266//
267// double e_long = fullsolutionData.back().e_long;
268// e_long -= boost::fusion::at_key<VMGDataFused::energy_long>(Result_LongRange_fused.back()).getFullContribution();
269// LOG(0, "Remaining long-range energy is " << e_long << ".");
270// }
271
272 // TODO: Extract long-range corrections to forces
273 // NOTE: potential is in atomic length units, NOT IN ANGSTROEM!
274
275 }
276}
Note: See TracBrowser for help on using the repository browser.