/* * 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 headers that implement a archive in simple text format #include #include // //#include //#include //#include #include "CodePatterns/Assert.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "JobMarket/Jobs/FragmentJob.hpp" #include "Fragmentation/Automation/FragmentJobQueue.hpp" #include "Fragmentation/Automation/MPQCFragmentController.hpp" #include "Fragmentation/Summation/Containers/FragmentationChargeDensity.hpp" #include "Fragmentation/Summation/Containers/FragmentationLongRangeResults.hpp" #include "Fragmentation/Summation/Containers/FragmentationResultContainer.hpp" #include "Fragmentation/Summation/Containers/FragmentationShortRangeResults.hpp" #include "Fragmentation/Summation/Containers/MPQCData.hpp" #include "Fragmentation/KeySetsContainer.hpp" #ifdef HAVE_VMG #include "Fragmentation/Automation/VMGDebugGridFragmentController.hpp" #include "Fragmentation/Automation/VMGFragmentController.hpp" #include "Fragmentation/Summation/Containers/VMGData.hpp" #include "Fragmentation/Summation/Containers/VMGDataFused.hpp" #include "Fragmentation/Summation/Containers/VMGDataMap.hpp" #include "Fragmentation/Summation/Containers/VMGData_printKeyNames.hpp" #endif #include "World.hpp" #include #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; } Action::state_ptr FragmentationFragmentationAutomationAction::performCall() { boost::asio::io_service io_service; // TODO: Have io_service run in second thread and merge with current again eventually FragmentationResultContainer &container = FragmentationResultContainer::getInstance(); const KeySetsContainer& keysets = FragmentJobQueue::getInstance().getKeySets(); const KeySetsContainer& forcekeysets = FragmentJobQueue::getInstance().getFullKeySets(); size_t Exitflag = 0; std::map shortrangedata; { const size_t NumberJobs = FragmentJobQueue::getInstance().size(); MPQCFragmentController mpqccontroller(io_service); mpqccontroller.setHost(params.host.get()); mpqccontroller.setPort(params.port.get()); // Phase One: obtain ids mpqccontroller.requestIds(NumberJobs); // Phase Two: add MPQCJobs and send const size_t NoJobs = mpqccontroller.addJobsFromQueue( params.DoLongrange.get() ? MPQCData::DoSampleDensity : MPQCData::DontSampleDensity, params.DoValenceOnly.get() ? MPQCData::DoSampleValenceOnly : MPQCData::DontSampleValenceOnly ); LOG(1, "INFO: Added " << NoJobs << " from FragmentJobsQueue."); mpqccontroller.run(); // Phase Three: calculate result mpqccontroller.waitforResults(NumberJobs); mpqccontroller.getResults(shortrangedata); Exitflag += mpqccontroller.getExitflag(); } #ifdef HAVE_VMG if (params.DoLongrange.get()) { if ( World::getInstance().getAllAtoms().size() == 0) { ELOG(1, "Please load the full molecule into the world before starting this action."); return Action::failure; } // obtain combined charge density FragmentationChargeDensity summedChargeDensity( shortrangedata, FragmentJobQueue::getInstance().getKeySets()); const std::vector full_sample = summedChargeDensity.getFullSampledGrid(); LOG(1, "INFO: There are " << shortrangedata.size() << " short-range and " << full_sample.size() << " level-wise long-range jobs."); // Phase Four: obtain more ids std::map longrangedata; { VMGFragmentController vmgcontroller(io_service); vmgcontroller.setHost(params.host.get()); vmgcontroller.setPort(params.port.get()); const size_t NoJobs = shortrangedata.size()+full_sample.size(); vmgcontroller.requestIds(NoJobs); // Phase Five: create VMGJobs const size_t near_field_cells = params.near_field_cells.get(); const size_t interpolation_degree = params.interpolation_degree.get(); if (!vmgcontroller.createLongRangeJobs( shortrangedata, full_sample, near_field_cells, interpolation_degree, params.DoValenceOnly.get() ? MPQCData::DoSampleValenceOnly : MPQCData::DontSampleValenceOnly, params.DoPrintDebug.get())) // can't use the summed up fragment due to saturation hydrogens // summedChargeDensity.getFragment(), return Action::failure; // Phase Six: calculate result vmgcontroller.waitforResults(NoJobs); vmgcontroller.getResults(longrangedata); ASSERT( NoJobs == longrangedata.size(), "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresults+" +toString(full_sample.size())+"="+toString(NoJobs) +" and VMGresults "+toString(longrangedata.size())+" don't match."); Exitflag += vmgcontroller.getExitflag(); } if (params.DoPrintDebug.get()) { std::map debugData; { if (!full_sample.empty()) { // create debug jobs for each level to print the summed-up potential to vtk files VMGDebugGridFragmentController debugcontroller(io_service); debugcontroller.setHost(params.host.get()); debugcontroller.setPort(params.port.get()); debugcontroller.requestIds(full_sample.size()); if (!debugcontroller.createDebugJobs(full_sample)) return Action::failure; debugcontroller.waitforResults(full_sample.size()); debugcontroller.getResults(debugData); Exitflag += debugcontroller.getExitflag(); } } } container.addFullResults(keysets, forcekeysets, shortrangedata, longrangedata); } else { container.addShortRangeResults(keysets, forcekeysets, shortrangedata); } #else container.addShortRangeResults(keysets, forcekeysets, shortrangedata); #endif // now clear all present jobs as we are done FragmentJobQueue::getInstance().clear(); // if file is given, advise results container to store to file if (!params.resultsfile.get().empty()) { boost::filesystem::path resultsfile = params.resultsfile.get(); std::ofstream returnstream(resultsfile.string().c_str()); if (returnstream.good()) { boost::archive::text_oarchive oa(returnstream); oa << container; } Exitflag += (int)(!returnstream.good()); returnstream.close(); } 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 ====================== */