source: src/Fragmentation/Summation/Containers/FragmentationLongRangeResults.cpp@ 6c4b69

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
Last change on this file since 6c4b69 was ff347f, checked in by Frederik Heber <heber@…>, 9 years ago

Added gathering of full and longrange forces into extra file.

  • added new structs to VMGDataFusedMap for summation.
  • tempcommit: we do not have the full index set available, hence it just accumulated all indices from all fragments into a sorted set and use this in lieu of the full index set. We need to check how the full solution is constructed and how indices to the particles and their force vectors can be assigned.
  • extended printFullSolution() by another table with short- and long-range forces.
  • Property mode set to 100644
File size: 12.8 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{
107 MaxLevel = subsetmap->getMaximumSetLevel();
108 LOG(1, "INFO: Summing up results till level " << MaxLevel << ".");
109 /// convert all MPQCData to MPQCDataMap_t
110 {
111 ASSERT( ForceKeySet.KeySets.size() == fragmentData.size(),
112 "FragmentationLongRangeResults::FragmentationLongRangeResults() - ForceKeySet's KeySets and fragmentData differ in size.");
113
114 OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCData, MPQCDataGridVector_t>(
115 fragmentData, MPQCMatrixNrLookup, container, subsetmap,
116 Result_Grid_fused, Result_perIndexSet_Grid);
117
118 // multiply each short-range potential with the respective charge
119 std::map<JobId_t,MPQCData>::const_iterator mpqciter = fragmentData.begin();
120 std::map<JobId_t,VMGData>::iterator vmgiter = longrangeData.begin();
121 for (; vmgiter != longrangeData.end(); ++mpqciter, ++vmgiter) {
122 vmgiter->second.sampled_potential *= mpqciter->second.sampled_grid;
123 }
124 // then sum up
125 OrthogonalSumUpPerLevel<VMGDataMap_t, VMGData, VMGDataVector_t>(
126 longrangeData, VMGMatrixNrLookup, container, subsetmap,
127 Result_LongRange_fused, Result_perIndexSet_LongRange);
128
129 IndexedVectors::indices_t fullindices;
130 if (hasLongRangeForces()) {
131 // force has extra data converter (this is similar to MPQCData's forces
132 std::map<JobId_t, VMGDataForceMap_t> VMGData_Force_fused;
133 convertDatatoForceMap<VMGData, VMGDataForceMap_t, VMGDataFused>(
134 longrangeData, ForceKeySet, VMGData_Force_fused);
135 Result_ForceLongRange_fused.resize(MaxLevel); // we need the results of correct size already
136 AllLevelOrthogonalSummator<VMGDataForceMap_t> forceSummer(
137 subsetmap,
138 VMGData_Force_fused,
139 container->getContainer(),
140 VMGMatrixNrLookup,
141 Result_ForceLongRange_fused,
142 Result_perIndexSet_LongRange_Force);
143 boost::mpl::for_each<VMGDataForceVector_t>(boost::ref(forceSummer));
144 // build full force index set
145 KeySetsContainer::ArrayOfIntVectors::const_iterator arrayiter = ForceKeySet.KeySets.begin();
146 std::set<IndexedVectors::index_t> sorted_indices;
147 for (;arrayiter != ForceKeySet.KeySets.end(); ++arrayiter) {
148 sorted_indices.insert(arrayiter->begin(), arrayiter->end());
149 }
150 sorted_indices.erase(-1);
151 fullindices.insert(fullindices.begin(), sorted_indices.begin(), sorted_indices.end());
152 }
153
154 // then sum up
155 OrthogonalSumUpPerLevel<VMGDataGridMap_t, VMGData, VMGDataGridVector_t>(
156 longrangeData, VMGMatrixNrLookup, container, subsetmap,
157 Result_GridLongRange_fused, Result_perIndexSet_LongRange_Grid);
158
159 Result_LongRangeIntegrated_fused.reserve(MaxLevel);
160 // NOTE: potential for level 1 is wrongly calculated within a molecule
161 // as saturation hydrogen are not removed on this level yet
162 for (size_t level = 1; level <= MaxLevel; ++level) {
163 // We have calculated three different contributions: e-e, e-n+n-n, and n-n.
164 // And we want to have e-e+e-n, n-n+n-e (where e-n = n-e).
165 // For each of these three contributions we have a full solution and summed
166 // up short range solutions.
167
168 // first we obtain the full e-e energy as potential times charge on the
169 // respective level.
170 const SamplingGrid &charge_weight =
171 boost::fusion::at_key<MPQCDataFused::sampled_grid>(Result_Grid_fused[level-1]);
172 SamplingGrid full_sample_solution = fullsolutionData[level-1].sampled_potential;
173 full_sample_solution *= charge_weight;
174 double electron_solution_energy = full_sample_solution.integral();
175
176 // then we subtract the summed-up short-range e-e interaction energy from
177 // the full solution.
178 const SamplingGrid &short_range_correction =
179 boost::fusion::at_key<VMGDataFused::sampled_potential>(Result_GridLongRange_fused[level-1]);
180 double electron_short_range_energy = short_range_correction.integral();
181 full_sample_solution -= short_range_correction;
182 electron_solution_energy -= electron_short_range_energy;
183 ASSERT( fabs(electron_solution_energy - full_sample_solution.integral()) < 1e-7,
184 "FragmentationLongRangeResults::operator() - integral and energy are not exchangeable.");
185
186 // then, we obtain the e-n+n-n full solution in the same way
187 double nuclei_solution_energy = fullsolutionData[level-1].nuclei_long;
188 double nuclei_short_range_energy =
189 boost::fusion::at_key<VMGDataFused::nuclei_long>(Result_LongRange_fused[level-1]);
190 nuclei_solution_energy -= nuclei_short_range_energy;
191
192 // and also the e-n full solution
193 double both_solution_energy = fullsolutionData[level-1].electron_long;
194 double both_short_range_energy =
195 boost::fusion::at_key<VMGDataFused::electron_long>(Result_LongRange_fused[level-1]);
196 both_solution_energy -= both_short_range_energy;
197
198 // energies from interpolation at nuclei position has factor of 1/2 already
199 electron_solution_energy *= .5;
200 electron_short_range_energy *= .5;
201
202 // At last, we subtract e-n from n-n+e-n for full solution and short-range
203 // correction.
204 nuclei_solution_energy -= both_solution_energy;
205 nuclei_short_range_energy -= both_short_range_energy;
206
207 VMGDataLongRangeMap_t instance;
208 boost::fusion::at_key<VMGDataFused::electron_longrange>(instance) = electron_solution_energy;
209// LOG(0, "Remaining long-range potential integral of level " << level << " is "
210// << full_sample_solution.integral() << ".");
211 boost::fusion::at_key<VMGDataFused::electron_shortrange>(instance) = electron_short_range_energy;
212// LOG(0, "Short-range correction potential integral of level " << level << " is "
213// << short_range_correction.integral() << ".");
214 boost::fusion::at_key<VMGDataFused::mixed_longrange>(instance) = both_solution_energy;
215// LOG(0, "Remaining long-range energy from potential integral of level " << level << " is "
216// << full_solution_energy << ".");
217 boost::fusion::at_key<VMGDataFused::mixed_shortrange>(instance) = both_short_range_energy;
218// LOG(0, "Short-range correction energy from potential integral of level " << level << " is "
219// << short_range_energy << ".");
220 boost::fusion::at_key<VMGDataFused::nuclei_longrange>(instance) = nuclei_solution_energy;
221// LOG(0, "Remaining long-range energy from potential integral of level " << level << " is "
222// << full_solution_energy << ".");
223 boost::fusion::at_key<VMGDataFused::nuclei_shortrange>(instance) = nuclei_short_range_energy;
224// LOG(0, "Short-range correction energy from potential integral of level " << level << " is "
225// << short_range_energy << ".");
226 boost::fusion::at_key<VMGDataFused::total_longrange>(instance) =
227 boost::fusion::at_key<VMGDataFused::electron_longrange>(instance)
228 + 2.*boost::fusion::at_key<VMGDataFused::mixed_longrange>(instance)
229 + boost::fusion::at_key<VMGDataFused::nuclei_longrange>(instance);
230 boost::fusion::at_key<VMGDataFused::total_shortrange>(instance) =
231 boost::fusion::at_key<VMGDataFused::electron_shortrange>(instance)
232 + 2.*boost::fusion::at_key<VMGDataFused::mixed_shortrange>(instance)
233 + boost::fusion::at_key<VMGDataFused::nuclei_shortrange>(instance);
234 Result_LongRangeIntegrated_fused.push_back(instance);
235
236 if (hasLongRangeForces()) {
237 VMGDataLongRangeForceMap_t forceinstance;
238 IndexedVectors fullforces( fullindices, fullsolutionData[level-1].forces);
239 IndexedVectors longrangeforces =
240 boost::fusion::at_key<VMGDataFused::forces>(Result_ForceLongRange_fused[level-1]);
241 boost::fusion::at_key<VMGDataFused::forces_shortrange>(forceinstance) =
242 fullforces;
243 fullforces -= longrangeforces;
244 boost::fusion::at_key<VMGDataFused::forces_longrange>(forceinstance) =
245 fullforces;
246 Result_ForcesLongRangeIntegrated_fused.push_back(forceinstance);
247 }
248 }
249// {
250// // LOG(0, "Remaining long-range energy from energy_potential is " << full_sample_solution.integral()-epotentialSummer.getFullContribution() << ".");
251// SamplingGrid full_sample_solution = fullsolutionData.back().sampled_potential;
252// const SamplingGrid &short_range_correction =
253// boost::fusion::at_key<VMGDataFused::sampled_potential>(Result_GridLongRange_fused.back()).getFullContribution();
254// full_sample_solution -= short_range_correction;
255// // multiply element-wise with charge distribution
256// LOG(0, "Remaining long-range potential integral is " << full_sample_solution.integral() << ".");
257// LOG(0, "Short-range correction potential integral of level is " << short_range_correction.integral() << ".");
258// LOG(0, "Remaining long-range energy from potential integral is "
259// << full_sample_solution.integral(full_sample.back()) << ".");
260// LOG(0, "Short-range correction energy from potential integral is "
261// << short_range_correction.integral(full_sample.back()) << ".");
262//
263// double e_long = fullsolutionData.back().e_long;
264// e_long -= boost::fusion::at_key<VMGDataFused::energy_long>(Result_LongRange_fused.back()).getFullContribution();
265// LOG(0, "Remaining long-range energy is " << e_long << ".");
266// }
267
268 // TODO: Extract long-range corrections to forces
269 // NOTE: potential is in atomic length units, NOT IN ANGSTROEM!
270
271 }
272}
Note: See TracBrowser for help on using the repository browser.