/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* FragmentationAutomationAction.cpp
*
* Created on: May 18, 2012
* Author: heber
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include
// boost asio needs specific operator new
#include
#include "CodePatterns/MemDebug.hpp"
#include
#include
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Info.hpp"
#include "CodePatterns/Log.hpp"
#include "JobMarket/Jobs/FragmentJob.hpp"
#include "Fragmentation/Automation/extractJobIds.hpp"
#include "Fragmentation/Automation/MPQCFragmentController.hpp"
#include "Fragmentation/Automation/VMGDebugGridFragmentController.hpp"
#include "Fragmentation/Automation/VMGFragmentController.hpp"
#include "Fragmentation/EnergyMatrix.hpp"
#include "Fragmentation/ForceMatrix.hpp"
#include "Fragmentation/Fragmentation.hpp"
#include "Fragmentation/SetValues/Fragment.hpp"
#include "Fragmentation/SetValues/Histogram.hpp"
#include "Fragmentation/SetValues/IndexedVectors.hpp"
#include "Fragmentation/HydrogenSaturation_enum.hpp"
#include "Fragmentation/KeySet.hpp"
#include "Fragmentation/KeySetsContainer.hpp"
#include "Fragmentation/Summation/OrthogonalSumUpPerLevel.hpp"
#include "Fragmentation/Summation/SumUpPerLevel.hpp"
#include "Fragmentation/Summation/OrthogonalFullSummator.hpp"
#include "Fragmentation/Summation/writeTable.hpp"
#include "Graph/DepthFirstSearchAnalysis.hpp"
#include "Helpers/defs.hpp"
#include "Jobs/MPQCJob.hpp"
#include "Jobs/MPQCData.hpp"
#include "Jobs/MPQCData_printKeyNames.hpp"
#include "Jobs/Grid/SamplingGrid.hpp"
#ifdef HAVE_VMG
#include "Jobs/VMGDebugGridJob.hpp"
#include "Jobs/VMGJob.hpp"
#include "Jobs/VMGData.hpp"
#include "Jobs/VMGDataFused.hpp"
#include "Jobs/VMGDataMap.hpp"
#include "Jobs/VMGData_printKeyNames.hpp"
#endif
#include "World.hpp"
#include
#include
#include
#include
#include "Actions/FragmentationAction/FragmentationAutomationAction.hpp"
using namespace MoleCuilder;
// and construct the stuff
#include "FragmentationAutomationAction.def"
#include "Action_impl_pre.hpp"
/** =========== define the function ====================== */
class controller_AddOn;
// needs to be defined for using the FragmentController
controller_AddOn *getAddOn()
{
return NULL;
}
/** Helper function to get number of atoms somehow.
*
* Here, we just parse the number of lines in the adjacency file as
* it should correspond to the number of atoms, except when some atoms
* are not bonded, but then fragmentation makes no sense.
*
* @param path path to the adjacency file
*/
size_t getNoAtomsFromAdjacencyFile(const std::string &path)
{
size_t NoAtoms = 0;
// parse in special file to get atom count (from line count)
std::string filename(path);
filename += FRAGMENTPREFIX;
filename += ADJACENCYFILE;
std::ifstream adjacency(filename.c_str());
if (adjacency.fail()) {
LOG(0, endl << "getNoAtomsFromAdjacencyFile() - Unable to open " << filename << ", is the directory correct?");
return false;
}
std::string buffer;
while (getline(adjacency, buffer))
NoAtoms++;
LOG(1, "INFO: There are " << NoAtoms << " atoms.");
return NoAtoms;
}
/** Creates a lookup from FragmentJob::id to the true fragment number.
*
* @param jobids vector with job ids
* @param FragmentCounter total number of fragments on return
* @return Lookup up-map
*/
std::map< JobId_t, size_t > createMatrixNrLookup(
const std::vector &jobids,
size_t &FragmentCounter)
{
// align fragments
std::map< JobId_t, size_t > MatrixNrLookup;
FragmentCounter = 0;
for (std::vector::const_iterator iter = jobids.begin();
iter != jobids.end(); ++iter) {
LOG(3, "DEBUG: Inserting (" << *iter << "," << FragmentCounter << ").");
#ifndef NDEBUG
std::pair< std::map< JobId_t, size_t >::iterator, bool> inserter =
#endif
MatrixNrLookup.insert( std::make_pair(*iter, FragmentCounter++) );
ASSERT( inserter.second,
"createMatrixNrLookup() - two results have same id "
+toString(*iter)+".");
}
LOG(1, "INFO: There are " << FragmentCounter << " fragments.");
return MatrixNrLookup;
}
/** Place results from FragmentResult into EnergyMatrix and ForceMatrix.
*
* @param fragmentData MPQCData resulting from the jobs
* @param MatrixNrLookup Lookup up-map from job id to fragment number
* @param FragmentCounter total number of fragments
* @param NoAtoms total number of atoms
* @param Energy energy matrix to be filled on return
* @param Force force matrix to be filled on return
* @return true - everything ok, false - else
*/
bool putResultsintoMatrices(
const std::map &fragmentData,
const std::map< JobId_t, size_t > &MatrixNrLookup,
const size_t FragmentCounter,
const size_t NoAtoms,
EnergyMatrix &Energy,
ForceMatrix &Force)
{
for (std::map::const_iterator dataiter = fragmentData.begin();
dataiter != fragmentData.end(); ++dataiter) {
const MPQCData &extractedData = dataiter->second;
const JobId_t &jobid = dataiter->first;
std::map< JobId_t, size_t >::const_iterator nriter = MatrixNrLookup.find(jobid);
ASSERT( nriter != MatrixNrLookup.end(),
"putResultsintoMatrices() - MatrixNrLookup does not contain id "
+toString(jobid)+".");
// place results into EnergyMatrix ...
{
MatrixContainer::MatrixArray matrix;
matrix.resize(1);
matrix[0].resize(1, extractedData.energies.total);
if (!Energy.AddMatrix(
std::string("MPQCJob ")+toString(jobid),
matrix,
nriter->second)) {
ELOG(1, "Adding energy matrix failed.");
return false;
}
}
// ... and ForceMatrix (with two empty columns in front)
{
MatrixContainer::MatrixArray matrix;
const size_t rows = extractedData.forces.size();
matrix.resize(rows);
for (size_t i=0;isecond)) {
ELOG(1, "Adding force matrix failed.");
return false;
}
}
}
// add one more matrix (not required for energy)
MatrixContainer::MatrixArray matrix;
matrix.resize(1);
matrix[0].resize(1, 0.);
if (!Energy.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
return false;
// but for energy because we need to know total number of atoms
matrix.resize(NoAtoms);
for (size_t i = 0; i< NoAtoms; ++i)
matrix[i].resize(2+NDIM, 0.);
if (!Force.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
return false;
return true;
}
/** Print MPQCData from received results.
*
* @param fragmentData MPQCData resulting from the jobs, each associated to a job
* @param KeySetFilename filename with keysets to associate forces correctly
* @param NoAtoms total number of atoms
* @param full_sample summed up charge density of electrons from fragments on return
* @param full_fragment summed up positions and charges of nuclei from fragments on return
*/
bool sumUpChargeDensity(
const std::map &fragmentData,
const std::string &KeySetFilename,
std::vector &full_sample,
Fragment &full_fragment)
{
// create a vector of all job ids
std::vector jobids;
std::transform(fragmentData.begin(),fragmentData.end(),
std::back_inserter(jobids),
boost::bind( &std::map::value_type::first, boost::lambda::_1 )
);
// create lookup from job nr to fragment number
size_t FragmentCounter = 0;
const std::map< JobId_t, size_t > MatrixNrLookup =
createMatrixNrLookup(jobids, FragmentCounter);
// initialise keysets
KeySetsContainer KeySet;
{
// else needs keysets without hydrogens
std::stringstream filename;
filename << FRAGMENTPREFIX << KEYSETFILE;
if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
}
/// prepare for OrthogonalSummation
// convert KeySetContainer to IndexSetContainer
IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
// create the map of all keysets
SubsetMap::ptr subsetmap(new SubsetMap(*container));
/// convert all MPQCData to MPQCDataMap_t
std::vector Result_Grid_fused(
OrthogonalSumUpPerLevel(
fragmentData, MatrixNrLookup, container, subsetmap));
std::vector Result_Fragment_fused(
OrthogonalSumUpPerLevel(
fragmentData, MatrixNrLookup, container, subsetmap));
// obtain full grid
full_sample.clear();
full_sample.reserve(Result_Grid_fused.size());
for (std::vector::const_iterator iter = ++Result_Grid_fused.begin();
iter !=Result_Grid_fused.end();
++iter)
full_sample.push_back(boost::fusion::at_key((*iter)));
full_fragment = boost::fusion::at_key(Result_Fragment_fused.back());
return true;
}
/** Print MPQCData from received results.
*
* @param fragmentData MPQCData resulting from the jobs, associated to job id
* @param KeySetFilename filename with keysets to associate forces correctly
* @param NoAtoms total number of atoms
* @param full_sample summed up charge from fragments on return
*/
bool printReceivedMPQCResults(
const std::map &fragmentData,
const std::string &KeySetFilename,
size_t NoAtoms,
SamplingGrid &full_sample)
{
// create a vector of all job ids
std::vector jobids;
std::transform(fragmentData.begin(),fragmentData.end(),
std::back_inserter(jobids),
boost::bind( &std::map::value_type::first, boost::lambda::_1 )
);
// create lookup from job nr to fragment number
size_t FragmentCounter = 0;
const std::map< JobId_t, size_t > MatrixNrLookup=
createMatrixNrLookup(jobids, FragmentCounter);
// place results into maps
EnergyMatrix Energy;
ForceMatrix Force;
if (!putResultsintoMatrices(fragmentData, MatrixNrLookup, FragmentCounter, NoAtoms, Energy, Force))
return false;
// initialise keysets
KeySetsContainer KeySet;
KeySetsContainer ForceKeySet;
if (!Energy.InitialiseIndices()) return false;
if (!Force.ParseIndices(KeySetFilename.c_str())) return false;
{
// else needs keysets without hydrogens
std::stringstream filename;
filename << FRAGMENTPREFIX << KEYSETFILE;
if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
}
{
// forces need keysets including hydrogens
std::stringstream filename;
filename << FRAGMENTPREFIX << FORCESFILE;
if (!ForceKeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
}
/// prepare for OrthogonalSummation
// convert KeySetContainer to IndexSetContainer
IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
// create the map of all keysets
SubsetMap::ptr subsetmap(new SubsetMap(*container));
/// convert all MPQCData to MPQCDataMap_t
{
ASSERT( ForceKeySet.KeySets.size() == fragmentData.size(),
"FragmentationAutomationAction::performCall() - ForceKeySet's KeySets and fragmentData differ in size.");
typedef boost::mpl::remove::type MPQCDataEnergyVector_noeigenvalues_t;
std::vector Result_Energy_fused(
OrthogonalSumUpPerLevel(
fragmentData, MatrixNrLookup, container, subsetmap));
std::vector Result_Grid_fused(
OrthogonalSumUpPerLevel(
fragmentData, MatrixNrLookup, container, subsetmap));
std::vector Result_Time_fused(
SumUpPerLevel(
fragmentData, MatrixNrLookup, container, subsetmap));
// force has extra converter
std::map MPQCData_Force_fused;
convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
std::vector Result_Force_fused(subsetmap->getMaximumSubsetLevel());
AllLevelOrthogonalSummator forceSummer(
subsetmap,
MPQCData_Force_fused,
container->getContainer(),
MatrixNrLookup,
Result_Force_fused);
boost::mpl::for_each(boost::ref(forceSummer));
// obtain full grid
full_sample = boost::fusion::at_key(Result_Grid_fused.back());
// print tables (without eigenvalues, they go extra)
const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
const std::string energyresult =
writeTable()(
Result_Energy_fused, MaxLevel);
LOG(0, "Energy table is \n" << energyresult);
const std::string eigenvalueresult;
LOG(0, "Eigenvalue table is \n" << eigenvalueresult);
const std::string forceresult =
writeTable()(
Result_Force_fused, MaxLevel);
LOG(0, "Force table is \n" << forceresult);
// we don't want to print grid to a table
// print times (without flops for now)
typedef boost::mpl::remove<
boost::mpl::remove::type,
MPQCDataFused::times_gather_flops>::type
MPQCDataTimeVector_noflops_t;
const std::string timesresult =
writeTable()(
Result_Time_fused, MaxLevel);
LOG(0, "Times table is \n" << timesresult);
}
// combine all found data
if (!KeySet.ParseManyBodyTerms()) return false;
EnergyMatrix EnergyFragments;
ForceMatrix ForceFragments;
if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return false;
if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return false;
if(!Energy.SetLastMatrix(0., 0)) return false;
if(!Force.SetLastMatrix(0., 2)) return false;
for (int BondOrder=0;BondOrder &fragmentData,
const std::map &longrangeData,
const std::vector &fullsolutionData,
const std::string &KeySetFilename,
size_t NoAtoms,
std::vector &full_sample)
{
// create lookup from job nr to fragment number
size_t MPQCFragmentCounter = 0;
const std::vector mpqcjobids = extractJobIds(fragmentData);
const std::map< JobId_t, size_t > MPQCMatrixNrLookup =
createMatrixNrLookup(mpqcjobids, MPQCFragmentCounter);
size_t VMGFragmentCounter = 0;
const std::vector vmgjobids = extractJobIds(longrangeData);
const std::map< JobId_t, size_t > VMGMatrixNrLookup =
createMatrixNrLookup(vmgjobids, VMGFragmentCounter);
// initialise keysets
KeySetsContainer KeySet;
KeySetsContainer ForceKeySet;
{
// else needs keysets without hydrogens
std::stringstream filename;
filename << FRAGMENTPREFIX << KEYSETFILE;
if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), MPQCFragmentCounter)) return false;
}
{
// forces need keysets including hydrogens
std::stringstream filename;
filename << FRAGMENTPREFIX << FORCESFILE;
if (!ForceKeySet.ParseKeySets(KeySetFilename, filename.str(), MPQCFragmentCounter)) return false;
}
/// prepare for OrthogonalSummation
// convert KeySetContainer to IndexSetContainer
IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
// create the map of all keysets
SubsetMap::ptr subsetmap(new SubsetMap(*container));
/// convert all MPQCData to MPQCDataMap_t
{
typedef boost::mpl::remove::type MPQCDataEnergyVector_noeigenvalues_t;
std::vector Result_Energy_fused(
OrthogonalSumUpPerLevel(
fragmentData, MPQCMatrixNrLookup, container, subsetmap));
std::vector Result_Grid_fused(
OrthogonalSumUpPerLevel(
fragmentData, MPQCMatrixNrLookup, container, subsetmap));
std::vector Result_Time_fused(
SumUpPerLevel(
fragmentData, MPQCMatrixNrLookup, container, subsetmap));
std::vector Result_Fragment_fused(
OrthogonalSumUpPerLevel(
fragmentData, MPQCMatrixNrLookup, container, subsetmap));
// force has extra converter
std::map MPQCData_Force_fused;
convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
std::vector Result_Force_fused(subsetmap->getMaximumSubsetLevel());
AllLevelOrthogonalSummator forceSummer(
subsetmap,
MPQCData_Force_fused,
container->getContainer(),
MPQCMatrixNrLookup,
Result_Force_fused);
boost::mpl::for_each(boost::ref(forceSummer));
// obtain full grid
std::map VMGData_Potential_fused;
convertDataTo(longrangeData, VMGData_Potential_fused);
OrthogonalFullSummator potentialSummer(
subsetmap,
VMGData_Potential_fused,
container->getContainer(),
VMGMatrixNrLookup);
potentialSummer(subsetmap->getMaximumSubsetLevel());
OrthogonalFullSummator epotentialSummer(
subsetmap,
VMGData_Potential_fused,
container->getContainer(),
VMGMatrixNrLookup);
epotentialSummer(subsetmap->getMaximumSubsetLevel());
std::vector Result_LongRange_fused;
Result_LongRange_fused.reserve(subsetmap->getMaximumSubsetLevel());
for (size_t level = 1; level <= subsetmap->getMaximumSubsetLevel(); ++level) {
// weight times correct charge density of the same level
// NOTE: potential for level 1 is not calculated as saturation hydrogen
// are not removed on this level yet
const size_t potentiallevel = level < 2 ? 0 : (level-2);
SamplingGrid charge_weight = boost::fusion::at_key(Result_Grid_fused[level-1]);
SamplingGrid full_sample_solution = fullsolutionData[potentiallevel].sampled_potential;
SamplingGrid short_range_correction = potentialSummer(level);
// LOG(0, "Remaining long-range energy from energy_potential is " << full_sample_solution.integral()-epotentialSummer.getFullContribution() << ".");
full_sample_solution -= short_range_correction;
// multiply element-wise with charge distribution
VMGDataLongRangeMap_t instance;
boost::fusion::at_key(instance) = full_sample_solution.integral();
LOG(0, "Remaining long-range potential integral of level " << level << " is "
<< full_sample_solution.integral() << ".");
boost::fusion::at_key(instance) = short_range_correction.integral();
LOG(0, "Short-range correction potential integral of level " << level << " is "
<< short_range_correction.integral() << ".");
boost::fusion::at_key(instance) = full_sample_solution.integral(charge_weight);
LOG(0, "Remaining long-range energy from potential integral of level " << level << " is "
<< full_sample_solution.integral(charge_weight) << ".");
boost::fusion::at_key(instance) = short_range_correction.integral(charge_weight);
LOG(0, "Short-range correction energy from potential integral of level " << level << " is "
<< short_range_correction.integral(charge_weight) << ".");
Result_LongRange_fused.push_back(instance);
}
{
// LOG(0, "Remaining long-range energy from energy_potential is " << full_sample_solution.integral()-epotentialSummer.getFullContribution() << ".");
SamplingGrid full_sample_solution = fullsolutionData.back().sampled_potential;
SamplingGrid short_range_correction = potentialSummer.getFullContribution();
full_sample_solution -= short_range_correction;
// multiply element-wise with charge distribution
LOG(0, "Remaining long-range potential integral is " << full_sample_solution.integral() << ".");
LOG(0, "Short-range correction potential integral of level is " << short_range_correction.integral() << ".");
LOG(0, "Remaining long-range energy from potential integral is "
<< full_sample_solution.integral(full_sample.back()) << ".");
LOG(0, "Short-range correction energy from potential integral is "
<< short_range_correction.integral(full_sample.back()) << ".");
}
// TODO: Extract long-range corrections to forces
// NOTE: potential is in atomic length units, NOT IN ANGSTROEM!
OrthogonalFullSummator elongSummer(
subsetmap,
VMGData_Potential_fused,
container->getContainer(),
VMGMatrixNrLookup);
elongSummer(subsetmap->getMaximumSubsetLevel());
double e_long = fullsolutionData.back().e_long;
e_long -= elongSummer.getFullContribution();
LOG(0, "Remaining long-range energy is " << e_long << ".");
// print tables (without eigenvalues, they go extra)
const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
const std::string energyresult =
writeTable()(
Result_Energy_fused, MaxLevel);
LOG(0, "Energy table is \n" << energyresult);
const std::string gridresult =
writeTable()(
Result_LongRange_fused, MaxLevel);
LOG(0, "LongRange table is \n" << gridresult);
const std::string eigenvalueresult;
LOG(0, "Eigenvalue table is \n" << eigenvalueresult);
const std::string forceresult =
writeTable()(
Result_Force_fused, MaxLevel);
LOG(0, "Force table is \n" << forceresult);
// we don't want to print grid to a table
// print times (without flops for now)
typedef boost::mpl::remove<
boost::mpl::remove::type,
MPQCDataFused::times_gather_flops>::type
MPQCDataTimeVector_noflops_t;
const std::string timesresult =
writeTable()(
Result_Time_fused, MaxLevel);
LOG(0, "Times table is \n" << timesresult);
}
return true;
}
Action::state_ptr FragmentationFragmentationAutomationAction::performCall() {
boost::asio::io_service io_service;
MPQCFragmentController mpqccontroller(io_service);
mpqccontroller.setHost(params.host.get());
mpqccontroller.setPort(params.port.get());
mpqccontroller.setLevel(params.level.get());
VMGFragmentController vmgcontroller(io_service);
vmgcontroller.setHost(params.host.get());
vmgcontroller.setPort(params.port.get());
VMGDebugGridFragmentController debugcontroller(io_service);
debugcontroller.setHost(params.host.get());
debugcontroller.setPort(params.port.get());
// TODO: Have io_service run in second thread and merge with current again eventually
// Phase One: obtain ids
std::vector< boost::filesystem::path > jobfiles = params.jobfiles.get();
mpqccontroller.requestIds(jobfiles.size());
// Phase Two: create and add MPQCJobs
if (!mpqccontroller.addJobsFromFiles(params.executable.get().string(), jobfiles))
return Action::failure;
// Phase Three: calculate result
mpqccontroller.waitforResults(jobfiles.size());
std::map fragmentData;
mpqccontroller.getResults(fragmentData);
#ifdef HAVE_VMG
if (params.DoLongrange.get()) {
ASSERT( World::getInstance().getAllAtoms().size() != 0,
"FragmentationFragmentationAutomationAction::performCall() - please load the full molecule into the World before.");
// obtain combined charge density
LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
std::vector full_sample; // have charges from level 2 onward summed up
Fragment full_fragment;
sumUpChargeDensity(
fragmentData,
params.path.get(),
full_sample,
full_fragment);
// Phase Four: obtain more ids
vmgcontroller.requestIds(fragmentData.size()+full_sample.size());
// Phase Five: create VMGJobs
const size_t near_field_cells = params.near_field_cells.get();
if (!vmgcontroller.createLongRangeJobs(fragmentData, full_sample, full_fragment, near_field_cells))
return Action::failure;
// Phase Six: calculate result
vmgcontroller.waitforResults(fragmentData.size()+full_sample.size());
std::map longrangeData;
vmgcontroller.getResults(longrangeData);
ASSERT( fragmentData.size()+full_sample.size() == longrangeData.size(),
"FragmentationFragmentationAutomationAction::performCall() - number of MPQCresults+"
+toString(full_sample.size())+" "+toString(fragmentData.size()+full_sample.size())
+" and VMGresults "+toString(longrangeData.size())+" don't match.");
// remove full solution corresponding to full_sample from map (must be highest ids), has to be treated extra
std::map::iterator iter = longrangeData.end();
for (size_t i=0;i::iterator remove_iter = iter;
std::vector fullsolutionData;
for (; iter != longrangeData.end(); ++iter)
fullsolutionData.push_back(iter->second);
longrangeData.erase(remove_iter, longrangeData.end());
// Final phase: print result
{
LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
printReceivedFullResults(
fragmentData,
longrangeData,
fullsolutionData,
params.path.get(),
getNoAtomsFromAdjacencyFile(params.path.get()),
full_sample);
if (!full_sample.empty()) {
// create debug jobs to print the summed-up potential to vtk files
debugcontroller.requestIds(full_sample.size());
if (!debugcontroller.createDebugJobs(full_sample))
return Action::failure;
debugcontroller.waitforResults(full_sample.size());
std::map debugData;
debugcontroller.getResults(debugData);
}
}
}
#else
// Final phase: print result
{
LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
printReceivedMPQCResults(
fragmentData,
params.path.get(),
getNoAtomsFromAdjacencyFile(params.path.get()),
full_sample);
}
#endif
size_t Exitflag = vmgcontroller.getExitflag() + mpqccontroller.getExitflag();
return (Exitflag == 0) ? Action::success : Action::failure;
}
Action::state_ptr FragmentationFragmentationAutomationAction::performUndo(Action::state_ptr _state) {
return Action::success;
}
Action::state_ptr FragmentationFragmentationAutomationAction::performRedo(Action::state_ptr _state){
return Action::success;
}
bool FragmentationFragmentationAutomationAction::canUndo() {
return false;
}
bool FragmentationFragmentationAutomationAction::shouldUndo() {
return false;
}
/** =========== end of function ====================== */