source: src/Actions/FragmentationAction/FragmentationAutomationAction.cpp@ 758e56

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 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_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 758e56 was 758e56, checked in by Frederik Heber <heber@…>, 13 years ago

printReceivedFullResults() now multiplies long-range potential times charge distribution.

  • Property mode set to 100644
File size: 26.0 KB
RevLine 
[edecba]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[94d5ac6]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/>.
[edecba]21 */
22
23/*
24 * FragmentationAutomationAction.cpp
25 *
26 * Created on: May 18, 2012
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include <boost/archive/text_iarchive.hpp>
36// boost asio needs specific operator new
37#include <boost/asio.hpp>
38
39#include "CodePatterns/MemDebug.hpp"
40
[fb881a]41#include <boost/mpl/remove.hpp>
[c9f9bb]42#include <boost/lambda/lambda.hpp>
[fb881a]43
[6ca578]44#include "CodePatterns/Assert.hpp"
[edecba]45#include "CodePatterns/Info.hpp"
46#include "CodePatterns/Log.hpp"
47#include "JobMarket/Jobs/FragmentJob.hpp"
48
[ffe057]49#include "Fragmentation/Automation/MPQCFragmentController.hpp"
50#include "Fragmentation/Automation/VMGFragmentController.hpp"
[edecba]51#include "Fragmentation/EnergyMatrix.hpp"
52#include "Fragmentation/ForceMatrix.hpp"
53#include "Fragmentation/Fragmentation.hpp"
[184943]54#include "Fragmentation/SetValues/Fragment.hpp"
[e06820]55#include "Fragmentation/SetValues/Histogram.hpp"
[e13990b]56#include "Fragmentation/SetValues/IndexedVectors.hpp"
[edecba]57#include "Fragmentation/HydrogenSaturation_enum.hpp"
[6ca578]58#include "Fragmentation/KeySet.hpp"
[edecba]59#include "Fragmentation/KeySetsContainer.hpp"
[0398bd]60#include "Fragmentation/Summation/OrthogonalSumUpPerLevel.hpp"
61#include "Fragmentation/Summation/SumUpPerLevel.hpp"
[358ddb]62#include "Fragmentation/Summation/OrthogonalFullSummator.hpp"
[27afbf]63#include "Fragmentation/Summation/writeTable.hpp"
[edecba]64#include "Graph/DepthFirstSearchAnalysis.hpp"
[8b58ac]65#include "Helpers/defs.hpp"
[28e894]66#include "Jobs/MPQCJob.hpp"
[4bc75d]67#include "Jobs/MPQCData.hpp"
[1f66c7]68#include "Jobs/MPQCData_printKeyNames.hpp"
[849cd8]69#include "Jobs/Grid/SamplingGrid.hpp"
[69c733]70#ifdef HAVE_VMG
71#include "Jobs/VMGJob.hpp"
[358ddb]72#include "Jobs/VMGData.hpp"
73#include "Jobs/VMGDataFused.hpp"
74#include "Jobs/VMGDataMap.hpp"
75#include "Jobs/VMGData_printKeyNames.hpp"
[69c733]76#endif
[edecba]77#include "World.hpp"
78
79#include <iostream>
80#include <string>
81#include <vector>
82
[8cae4c]83#include <boost/mpl/for_each.hpp>
84
[edecba]85#include "Actions/FragmentationAction/FragmentationAutomationAction.hpp"
86
87using namespace MoleCuilder;
88
89// and construct the stuff
90#include "FragmentationAutomationAction.def"
91#include "Action_impl_pre.hpp"
92/** =========== define the function ====================== */
93
94class controller_AddOn;
95
96// needs to be defined for using the FragmentController
97controller_AddOn *getAddOn()
98{
99 return NULL;
100}
101
102/** Helper function to get number of atoms somehow.
103 *
104 * Here, we just parse the number of lines in the adjacency file as
105 * it should correspond to the number of atoms, except when some atoms
106 * are not bonded, but then fragmentation makes no sense.
107 *
108 * @param path path to the adjacency file
109 */
110size_t getNoAtomsFromAdjacencyFile(const std::string &path)
111{
112 size_t NoAtoms = 0;
113
114 // parse in special file to get atom count (from line count)
115 std::string filename(path);
116 filename += FRAGMENTPREFIX;
117 filename += ADJACENCYFILE;
118 std::ifstream adjacency(filename.c_str());
119 if (adjacency.fail()) {
120 LOG(0, endl << "getNoAtomsFromAdjacencyFile() - Unable to open " << filename << ", is the directory correct?");
121 return false;
122 }
123 std::string buffer;
124 while (getline(adjacency, buffer))
125 NoAtoms++;
126 LOG(1, "INFO: There are " << NoAtoms << " atoms.");
127
128 return NoAtoms;
129}
130
131
[c4ee08]132/** Creates a lookup from FragmentJob::id to the true fragment number.
[edecba]133 *
[995e2f]134 * @param jobids vector with job ids
[c4ee08]135 * @param FragmentCounter total number of fragments on return
[3dd32f]136 * @return Lookup up-map
[edecba]137 */
[3dd32f]138std::map< JobId_t, size_t > createMatrixNrLookup(
[995e2f]139 const std::vector<JobId_t> &jobids,
[c4ee08]140 size_t &FragmentCounter)
[edecba]141{
142 // align fragments
[3dd32f]143 std::map< JobId_t, size_t > MatrixNrLookup;
[c4ee08]144 FragmentCounter = 0;
[995e2f]145 for (std::vector<JobId_t>::const_iterator iter = jobids.begin();
146 iter != jobids.end(); ++iter) {
[343401]147 LOG(3, "DEBUG: Inserting (" << *iter << "," << FragmentCounter << ").");
[995e2f]148#ifndef NDEBUG
149 std::pair< std::map< JobId_t, size_t >::iterator, bool> inserter =
150#endif
151 MatrixNrLookup.insert( std::make_pair(*iter, FragmentCounter++) );
152 ASSERT( inserter.second,
153 "createMatrixNrLookup() - two results have same id "
154 +toString(*iter)+".");
[edecba]155 }
156 LOG(1, "INFO: There are " << FragmentCounter << " fragments.");
[3dd32f]157 return MatrixNrLookup;
[c4ee08]158}
[edecba]159
[c4ee08]160/** Place results from FragmentResult into EnergyMatrix and ForceMatrix.
161 *
162 * @param fragmentData MPQCData resulting from the jobs
163 * @param MatrixNrLookup Lookup up-map from job id to fragment number
164 * @param FragmentCounter total number of fragments
165 * @param NoAtoms total number of atoms
166 * @param Energy energy matrix to be filled on return
167 * @param Force force matrix to be filled on return
168 * @return true - everything ok, false - else
169 */
170bool putResultsintoMatrices(
[c9f9bb]171 const std::map<JobId_t, MPQCData> &fragmentData,
[3dd32f]172 const std::map< JobId_t, size_t > &MatrixNrLookup,
[c4ee08]173 const size_t FragmentCounter,
174 const size_t NoAtoms,
175 EnergyMatrix &Energy,
176 ForceMatrix &Force)
177{
[c9f9bb]178 for (std::map<JobId_t, MPQCData>::const_iterator dataiter = fragmentData.begin();
179 dataiter != fragmentData.end(); ++dataiter) {
180 const MPQCData &extractedData = dataiter->second;
181 const JobId_t &jobid = dataiter->first;
[3dd32f]182 std::map< JobId_t, size_t >::const_iterator nriter = MatrixNrLookup.find(jobid);
183 ASSERT( nriter != MatrixNrLookup.end(),
184 "putResultsintoMatrices() - MatrixNrLookup does not contain id "
185 +toString(jobid)+".");
[edecba]186 // place results into EnergyMatrix ...
187 {
188 MatrixContainer::MatrixArray matrix;
189 matrix.resize(1);
[a9558f]190 matrix[0].resize(1, extractedData.energies.total);
[edecba]191 if (!Energy.AddMatrix(
[c9f9bb]192 std::string("MPQCJob ")+toString(jobid),
[edecba]193 matrix,
[3dd32f]194 nriter->second)) {
[edecba]195 ELOG(1, "Adding energy matrix failed.");
196 return false;
197 }
198 }
199 // ... and ForceMatrix (with two empty columns in front)
200 {
201 MatrixContainer::MatrixArray matrix;
202 const size_t rows = extractedData.forces.size();
203 matrix.resize(rows);
204 for (size_t i=0;i<rows;++i) {
205 const size_t columns = 2+extractedData.forces[i].size();
206 matrix[i].resize(columns, 0.);
207 // for (size_t j=0;j<2;++j)
208 // matrix[i][j] = 0.;
209 for (size_t j=2;j<columns;++j)
210 matrix[i][j] = extractedData.forces[i][j-2];
211 }
212 if (!Force.AddMatrix(
[c9f9bb]213 std::string("MPQCJob ")+toString(jobid),
[edecba]214 matrix,
[3dd32f]215 nriter->second)) {
[edecba]216 ELOG(1, "Adding force matrix failed.");
217 return false;
218 }
219 }
220 }
221 // add one more matrix (not required for energy)
222 MatrixContainer::MatrixArray matrix;
223 matrix.resize(1);
224 matrix[0].resize(1, 0.);
225 if (!Energy.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
226 return false;
227 // but for energy because we need to know total number of atoms
228 matrix.resize(NoAtoms);
229 for (size_t i = 0; i< NoAtoms; ++i)
230 matrix[i].resize(2+NDIM, 0.);
231 if (!Force.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
232 return false;
233
[c4ee08]234 return true;
235}
236/** Print MPQCData from received results.
237 *
[c9f9bb]238 * @param fragmentData MPQCData resulting from the jobs, each associated to a job
[c4ee08]239 * @param KeySetFilename filename with keysets to associate forces correctly
240 * @param NoAtoms total number of atoms
[184943]241 * @param full_sample summed up charge density of electrons from fragments on return
242 * @param full_fragment summed up positions and charges of nuclei from fragments on return
[849cd8]243 */
244bool sumUpChargeDensity(
[c9f9bb]245 const std::map<JobId_t,MPQCData> &fragmentData,
[849cd8]246 const std::string &KeySetFilename,
[184943]247 SamplingGrid &full_sample,
248 Fragment &full_fragment)
[849cd8]249{
[c9f9bb]250 // create a vector of all job ids
251 std::vector<JobId_t> jobids;
252 std::transform(fragmentData.begin(),fragmentData.end(),
253 std::back_inserter(jobids),
254 boost::bind( &std::map<JobId_t,MPQCData>::value_type::first, boost::lambda::_1 )
255 );
256
[849cd8]257 // create lookup from job nr to fragment number
258 size_t FragmentCounter = 0;
[3dd32f]259 const std::map< JobId_t, size_t > MatrixNrLookup =
260 createMatrixNrLookup(jobids, FragmentCounter);
[849cd8]261
262 // initialise keysets
263 KeySetsContainer KeySet;
264 {
265 // else needs keysets without hydrogens
266 std::stringstream filename;
267 filename << FRAGMENTPREFIX << KEYSETFILE;
268 if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
269 }
270
271 /// prepare for OrthogonalSummation
272
273 // convert KeySetContainer to IndexSetContainer
274 IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
275 // create the map of all keysets
276 SubsetMap::ptr subsetmap(new SubsetMap(*container));
277
278 /// convert all MPQCData to MPQCDataMap_t
279 std::vector<MPQCDataGridMap_t> Result_Grid_fused(
[358ddb]280 OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
[c9f9bb]281 fragmentData, MatrixNrLookup, container, subsetmap));
[184943]282 std::vector<MPQCDataFragmentMap_t> Result_Fragment_fused(
[358ddb]283 OrthogonalSumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
[c9f9bb]284 fragmentData, MatrixNrLookup, container, subsetmap));
[849cd8]285 // obtain full grid
286 full_sample = boost::fusion::at_key<MPQCDataFused::sampled_grid>(Result_Grid_fused.back());
[184943]287 full_fragment = boost::fusion::at_key<MPQCDataFused::fragment>(Result_Fragment_fused.back());
[849cd8]288
289 return true;
290}
291
292/** Print MPQCData from received results.
293 *
[c9f9bb]294 * @param fragmentData MPQCData resulting from the jobs, associated to job id
[849cd8]295 * @param KeySetFilename filename with keysets to associate forces correctly
296 * @param NoAtoms total number of atoms
297 * @param full_sample summed up charge from fragments on return
[c4ee08]298 */
299bool printReceivedMPQCResults(
[c9f9bb]300 const std::map<JobId_t, MPQCData> &fragmentData,
[c4ee08]301 const std::string &KeySetFilename,
[849cd8]302 size_t NoAtoms,
303 SamplingGrid &full_sample)
[c4ee08]304{
[c9f9bb]305 // create a vector of all job ids
306 std::vector<JobId_t> jobids;
307 std::transform(fragmentData.begin(),fragmentData.end(),
308 std::back_inserter(jobids),
309 boost::bind( &std::map<JobId_t,MPQCData>::value_type::first, boost::lambda::_1 )
310 );
311
[c4ee08]312 // create lookup from job nr to fragment number
313 size_t FragmentCounter = 0;
[3dd32f]314 const std::map< JobId_t, size_t > MatrixNrLookup=
315 createMatrixNrLookup(jobids, FragmentCounter);
[c4ee08]316
317 // place results into maps
318 EnergyMatrix Energy;
319 ForceMatrix Force;
[c9f9bb]320 if (!putResultsintoMatrices(fragmentData, MatrixNrLookup, FragmentCounter, NoAtoms, Energy, Force))
[c4ee08]321 return false;
322
323 // initialise keysets
[6ca578]324 KeySetsContainer KeySet;
[8b58ac]325 KeySetsContainer ForceKeySet;
[edecba]326 if (!Energy.InitialiseIndices()) return false;
327
328 if (!Force.ParseIndices(KeySetFilename.c_str())) return false;
329
[8b58ac]330 {
[c4ee08]331 // else needs keysets without hydrogens
[8b58ac]332 std::stringstream filename;
333 filename << FRAGMENTPREFIX << KEYSETFILE;
334 if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
335 }
[edecba]336
[8b58ac]337 {
[c4ee08]338 // forces need keysets including hydrogens
[8b58ac]339 std::stringstream filename;
340 filename << FRAGMENTPREFIX << FORCESFILE;
341 if (!ForceKeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
342 }
[6ca578]343
[a67a04]344 /// prepare for OrthogonalSummation
[fb69e9]345
346 // convert KeySetContainer to IndexSetContainer
347 IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
[6ca578]348 // create the map of all keysets
349 SubsetMap::ptr subsetmap(new SubsetMap(*container));
350
[e13990b]351 /// convert all MPQCData to MPQCDataMap_t
[8cae4c]352 {
[a67a04]353 ASSERT( ForceKeySet.KeySets.size() == fragmentData.size(),
354 "FragmentationAutomationAction::performCall() - ForceKeySet's KeySets and fragmentData differ in size.");
[6ca578]355
[358ddb]356 typedef boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type MPQCDataEnergyVector_noeigenvalues_t;
[94d530f]357 std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
[358ddb]358 OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
[c9f9bb]359 fragmentData, MatrixNrLookup, container, subsetmap));
[94d530f]360 std::vector<MPQCDataGridMap_t> Result_Grid_fused(
[358ddb]361 OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
[c9f9bb]362 fragmentData, MatrixNrLookup, container, subsetmap));
[94d530f]363 std::vector<MPQCDataTimeMap_t> Result_Time_fused(
364 SumUpPerLevel<MPQCDataTimeMap_t, MPQCDataTimeVector_t>(
[c9f9bb]365 fragmentData, MatrixNrLookup, container, subsetmap));
[94d530f]366
367 // force has extra converter
[c9f9bb]368 std::map<JobId_t, MPQCDataForceMap_t> MPQCData_Force_fused;
[c4ee08]369 convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
[ff9963]370 std::vector<MPQCDataForceMap_t> Result_Force_fused(subsetmap->getMaximumSubsetLevel());
371 AllLevelOrthogonalSummator<MPQCDataForceMap_t> forceSummer(
[a3a382]372 subsetmap,
373 MPQCData_Force_fused,
374 container->getContainer(),
[ff9963]375 MatrixNrLookup,
376 Result_Force_fused);
[a3a382]377 boost::mpl::for_each<MPQCDataForceVector_t>(boost::ref(forceSummer));
[20b3df]378
[849cd8]379 // obtain full grid
380 full_sample = boost::fusion::at_key<MPQCDataFused::sampled_grid>(Result_Grid_fused.back());
381
[fb881a]382 // print tables (without eigenvalues, they go extra)
[27afbf]383 const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
384 const std::string energyresult =
[fb881a]385 writeTable<MPQCDataEnergyMap_t, MPQCDataEnergyVector_noeigenvalues_t >()(
[27afbf]386 Result_Energy_fused, MaxLevel);
387 LOG(0, "Energy table is \n" << energyresult);
[fb881a]388 const std::string eigenvalueresult;
389
390 LOG(0, "Eigenvalue table is \n" << eigenvalueresult);
[27afbf]391 const std::string forceresult =
392 writeTable<MPQCDataForceMap_t, MPQCDataForceVector_t>()(
393 Result_Force_fused, MaxLevel);
394 LOG(0, "Force table is \n" << forceresult);
395 // we don't want to print grid to a table
[fb881a]396 // print times (without flops for now)
397 typedef boost::mpl::remove<MPQCDataTimeVector_t, MPQCDataFused::times_flops>::type MPQCDataTimeVector_noflops_t;
[27afbf]398 const std::string timesresult =
[fb881a]399 writeTable<MPQCDataTimeMap_t, MPQCDataTimeVector_noflops_t >()(
[27afbf]400 Result_Time_fused, MaxLevel);
401 LOG(0, "Times table is \n" << timesresult);
[8cae4c]402 }
[56df37]403
[6ca578]404 // combine all found data
[edecba]405 if (!KeySet.ParseManyBodyTerms()) return false;
406
[c4ee08]407 EnergyMatrix EnergyFragments;
408 ForceMatrix ForceFragments;
[edecba]409 if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return false;
410 if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return false;
411
412 if(!Energy.SetLastMatrix(0., 0)) return false;
413 if(!Force.SetLastMatrix(0., 2)) return false;
414
415 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
416 // --------- sum up energy --------------------
417 LOG(1, "INFO: Summing energy of order " << BondOrder+1 << " ...");
418 if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return false;
419 if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return false;
420
421 // --------- sum up Forces --------------------
422 LOG(1, "INFO: Summing forces of order " << BondOrder+1 << " ...");
423 if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return false;
424 if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return false;
425 }
426
427 // for debugging print resulting energy and forces
428 LOG(1, "INFO: Resulting energy is " << Energy.Matrix[ FragmentCounter ][0][0]);
429 std::stringstream output;
430 for (int i=0; i< Force.RowCounter[FragmentCounter]; ++i) {
431 for (int j=0; j< Force.ColumnCounter[FragmentCounter]; ++j)
432 output << Force.Matrix[ FragmentCounter ][i][j] << " ";
433 output << "\n";
434 }
435 LOG(1, "INFO: Resulting forces are " << std::endl << output.str());
436
437 return true;
438}
439
[343401]440template <typename T>
441std::vector<JobId_t> extractJobIds(const std::map<JobId_t, T> &iddata)
442{
443 // create a vector of all job ids
444 std::vector<JobId_t> jobids;
445 std::transform(iddata.begin(),iddata.end(),
446 std::back_inserter(jobids),
447 boost::bind(&std::map<JobId_t,T>::value_type::first, boost::lambda::_1 )
448 );
449 return jobids;
450}
451
[358ddb]452/** Print MPQCData from received results.
453 *
454 * @param fragmentData MPQCData resulting from the jobs
455 * @param longrangeData VMGData resulting from long-range jobs
[1f76f3]456 * @param fullsolutionData VMGData resulting from long-range of full problem
[358ddb]457 * @param KeySetFilename filename with keysets to associate forces correctly
458 * @param NoAtoms total number of atoms
459 * @param full_sample summed up charge from fragments on return
460 */
461bool printReceivedFullResults(
[c9f9bb]462 const std::map<JobId_t,MPQCData> &fragmentData,
463 const std::map<JobId_t,VMGData> &longrangeData,
[1f76f3]464 const VMGData &fullsolutionData,
[358ddb]465 const std::string &KeySetFilename,
466 size_t NoAtoms,
467 SamplingGrid &full_sample)
468{
469 // create lookup from job nr to fragment number
[343401]470 size_t MPQCFragmentCounter = 0;
471 const std::vector<JobId_t> mpqcjobids = extractJobIds<MPQCData>(fragmentData);
472 const std::map< JobId_t, size_t > MPQCMatrixNrLookup =
473 createMatrixNrLookup(mpqcjobids, MPQCFragmentCounter);
474
475 size_t VMGFragmentCounter = 0;
476 const std::vector<JobId_t> vmgjobids = extractJobIds<VMGData>(longrangeData);
477 const std::map< JobId_t, size_t > VMGMatrixNrLookup =
478 createMatrixNrLookup(vmgjobids, VMGFragmentCounter);
[358ddb]479
480 // initialise keysets
481 KeySetsContainer KeySet;
482 KeySetsContainer ForceKeySet;
483 {
484 // else needs keysets without hydrogens
485 std::stringstream filename;
486 filename << FRAGMENTPREFIX << KEYSETFILE;
[343401]487 if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), MPQCFragmentCounter)) return false;
[358ddb]488 }
489
490 {
491 // forces need keysets including hydrogens
492 std::stringstream filename;
493 filename << FRAGMENTPREFIX << FORCESFILE;
[343401]494 if (!ForceKeySet.ParseKeySets(KeySetFilename, filename.str(), MPQCFragmentCounter)) return false;
[358ddb]495 }
496
497 /// prepare for OrthogonalSummation
498
499 // convert KeySetContainer to IndexSetContainer
500 IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
501 // create the map of all keysets
502 SubsetMap::ptr subsetmap(new SubsetMap(*container));
503
504 /// convert all MPQCData to MPQCDataMap_t
505 {
506 typedef boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type MPQCDataEnergyVector_noeigenvalues_t;
507 std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
508 OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
[343401]509 fragmentData, MPQCMatrixNrLookup, container, subsetmap));
[358ddb]510 std::vector<MPQCDataGridMap_t> Result_Grid_fused(
511 OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
[343401]512 fragmentData, MPQCMatrixNrLookup, container, subsetmap));
[358ddb]513 std::vector<MPQCDataTimeMap_t> Result_Time_fused(
514 SumUpPerLevel<MPQCDataTimeMap_t, MPQCDataTimeVector_t>(
[343401]515 fragmentData, MPQCMatrixNrLookup, container, subsetmap));
[06865e]516 std::vector<MPQCDataFragmentMap_t> Result_Fragment_fused(
517 OrthogonalSumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
[343401]518 fragmentData, MPQCMatrixNrLookup, container, subsetmap));
[358ddb]519
520 // force has extra converter
[c9f9bb]521 std::map<JobId_t, MPQCDataForceMap_t> MPQCData_Force_fused;
[358ddb]522 convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
523 std::vector<MPQCDataForceMap_t> Result_Force_fused(subsetmap->getMaximumSubsetLevel());
524 AllLevelOrthogonalSummator<MPQCDataForceMap_t> forceSummer(
525 subsetmap,
526 MPQCData_Force_fused,
527 container->getContainer(),
[343401]528 MPQCMatrixNrLookup,
[358ddb]529 Result_Force_fused);
530 boost::mpl::for_each<MPQCDataForceVector_t>(boost::ref(forceSummer));
531
532 // obtain full grid
[c9f9bb]533 std::map<JobId_t, VMGDataMap_t> VMGData_Potential_fused;
[1f76f3]534 convertDataTo<VMGData, VMGDataMap_t>(longrangeData, VMGData_Potential_fused);
[358ddb]535 OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::sampled_potential> potentialSummer(
536 subsetmap,
537 VMGData_Potential_fused,
538 container->getContainer(),
[343401]539 VMGMatrixNrLookup);
[358ddb]540 potentialSummer(subsetmap->getMaximumSubsetLevel());
[c5feef]541 OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::energy_potential> epotentialSummer(
542 subsetmap,
543 VMGData_Potential_fused,
544 container->getContainer(),
[343401]545 VMGMatrixNrLookup);
[c5feef]546 epotentialSummer(subsetmap->getMaximumSubsetLevel());
[758e56]547 SamplingGrid full_sample_solution = fullsolutionData.sampled_potential;
548// LOG(0, "Remaining long-range energy from energy_potential is " << full_sample_solution.integral()-epotentialSummer.getFullContribution() << ".");
549 full_sample_solution -= potentialSummer.getFullContribution();
550 // multiply element-wise with charge distribution
551 LOG(0, "Remaining long-range potential integral is " << full_sample_solution.integral() << ".");
552 full_sample_solution *= full_sample;
553 LOG(0, "Remaining long-range energy from potential integral is " << full_sample_solution.integral() << ".");
[358ddb]554
[c5feef]555
[358ddb]556 OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::energy_long> elongSummer(
557 subsetmap,
558 VMGData_Potential_fused,
559 container->getContainer(),
[343401]560 VMGMatrixNrLookup);
[358ddb]561 elongSummer(subsetmap->getMaximumSubsetLevel());
[1f76f3]562 double e_long = fullsolutionData.e_long;
[06865e]563 e_long -= elongSummer.getFullContribution();
[358ddb]564 LOG(0, "Remaining long-range energy is " << e_long << ".");
565
566 // print tables (without eigenvalues, they go extra)
567 const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
568 const std::string energyresult =
569 writeTable<MPQCDataEnergyMap_t, MPQCDataEnergyVector_noeigenvalues_t >()(
570 Result_Energy_fused, MaxLevel);
571 LOG(0, "Energy table is \n" << energyresult);
572 const std::string eigenvalueresult;
573
574 LOG(0, "Eigenvalue table is \n" << eigenvalueresult);
575 const std::string forceresult =
576 writeTable<MPQCDataForceMap_t, MPQCDataForceVector_t>()(
577 Result_Force_fused, MaxLevel);
578 LOG(0, "Force table is \n" << forceresult);
579 // we don't want to print grid to a table
580 // print times (without flops for now)
581 typedef boost::mpl::remove<MPQCDataTimeVector_t, MPQCDataFused::times_flops>::type MPQCDataTimeVector_noflops_t;
582 const std::string timesresult =
583 writeTable<MPQCDataTimeMap_t, MPQCDataTimeVector_noflops_t >()(
584 Result_Time_fused, MaxLevel);
585 LOG(0, "Times table is \n" << timesresult);
586 }
587
588 return true;
589}
590
[edecba]591
[c5324f]592Action::state_ptr FragmentationFragmentationAutomationAction::performCall() {
593 boost::asio::io_service io_service;
[ffe057]594 MPQCFragmentController mpqccontroller(io_service);
595 mpqccontroller.setHost(params.host.get());
596 mpqccontroller.setPort(params.port.get());
597 VMGFragmentController vmgcontroller(io_service);
598 vmgcontroller.setHost(params.host.get());
599 vmgcontroller.setPort(params.port.get());
[c5324f]600
601 // TODO: Have io_service run in second thread and merge with current again eventually
602
603 // Phase One: obtain ids
604 std::vector< boost::filesystem::path > jobfiles = params.jobfiles.get();
[ffe057]605 mpqccontroller.requestIds(jobfiles.size());
[c5324f]606
[69c733]607 // Phase Two: create and add MPQCJobs
[ffe057]608 if (!mpqccontroller.addJobsFromFiles(params.executable.get().string(), jobfiles))
[c5324f]609 return Action::failure;
610
611 // Phase Three: calculate result
[ffe057]612 mpqccontroller.waitforResults(jobfiles.size());
[c9f9bb]613 std::map<JobId_t, MPQCData> fragmentData;
[ffe057]614 mpqccontroller.getResults(fragmentData);
[c5324f]615
[69c733]616#ifdef HAVE_VMG
617 if (params.DoLongrange.get()) {
[06865e]618 ASSERT( World::getInstance().getAllAtoms().size() != 0,
619 "FragmentationFragmentationAutomationAction::performCall() - please load the full molecule into the World before.");
620
[849cd8]621 // obtain combined charge density
622 LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
623 SamplingGrid full_sample;
[184943]624 Fragment full_fragment;
[849cd8]625 sumUpChargeDensity(
626 fragmentData,
627 params.path.get(),
[184943]628 full_sample,
629 full_fragment);
[849cd8]630
[69c733]631 // Phase Four: obtain more ids
[ffe057]632 vmgcontroller.requestIds(fragmentData.size()+1);
[69c733]633
634 // Phase Five: create VMGJobs
[ffe057]635 if (!vmgcontroller.createLongRangeJobs(fragmentData, full_sample, full_fragment))
[69c733]636 return Action::failure;
637
638 // Phase Six: calculate result
[ffe057]639 vmgcontroller.waitforResults(fragmentData.size()+1);
[c9f9bb]640 std::map<JobId_t, VMGData> longrangeData;
[ffe057]641 vmgcontroller.getResults(longrangeData);
642 ASSERT( fragmentData.size()+1 == longrangeData.size(),
643 "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresults+1 "
644 +toString(fragmentData.size()+1)+" and VMGresults "+toString(longrangeData.size())+" don't match.");
645
[c9f9bb]646 // remove full solution from map (must be highest id), has to be treated extra
647 VMGData fullsolutionData = (--longrangeData.end())->second;
648 longrangeData.erase(--longrangeData.end());
[358ddb]649
[2764e0]650 // Final phase: print result
651 {
652 LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
[358ddb]653 printReceivedFullResults(
[2764e0]654 fragmentData,
[358ddb]655 longrangeData,
[1f76f3]656 fullsolutionData,
[2764e0]657 params.path.get(),
[849cd8]658 getNoAtomsFromAdjacencyFile(params.path.get()),
659 full_sample);
[2764e0]660 }
[69c733]661 }
[358ddb]662#else
663 // Final phase: print result
664 {
665 LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
666 printReceivedMPQCResults(
667 fragmentData,
668 params.path.get(),
669 getNoAtomsFromAdjacencyFile(params.path.get()),
670 full_sample);
671 }
[69c733]672#endif
[ffe057]673 size_t Exitflag = vmgcontroller.getExitflag() + mpqccontroller.getExitflag();
[edecba]674
675 return (Exitflag == 0) ? Action::success : Action::failure;
676}
677
678Action::state_ptr FragmentationFragmentationAutomationAction::performUndo(Action::state_ptr _state) {
679 return Action::success;
680}
681
682Action::state_ptr FragmentationFragmentationAutomationAction::performRedo(Action::state_ptr _state){
683 return Action::success;
684}
685
686bool FragmentationFragmentationAutomationAction::canUndo() {
687 return false;
688}
689
690bool FragmentationFragmentationAutomationAction::shouldUndo() {
691 return false;
692}
693/** =========== end of function ====================== */
Note: See TracBrowser for help on using the repository browser.