Scine::Readuct  6.0.0
This is the SCINE module ReaDuct.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
BondOrderTask.h
Go to the documentation of this file.
1 
7 #ifndef READUCT_BONDORDERTASK_H_
8 #define READUCT_BONDORDERTASK_H_
9 
10 /* Readuct */
11 #include "Tasks/Task.h"
12 /* Scine */
14 #include <Utils/CalculatorBasics.h>
15 /* External */
16 #include "boost/exception/diagnostic_information.hpp"
17 #include <boost/filesystem.hpp>
18 /* std c++ */
19 #include <cstdio>
20 #include <fstream>
21 #include <iostream>
22 
23 namespace Scine {
24 namespace Readuct {
25 
26 class BondOrderTask : public Task {
27  public:
37  BondOrderTask(std::vector<std::string> input, std::vector<std::string> output, std::shared_ptr<Core::Log> logger = nullptr)
38  : Task(std::move(input), std::move(output), std::move(logger)) {
39  }
40 
41  std::string name() const override {
42  return "Bond Order Calculation";
43  }
44 
45  bool run(SystemsMap& systems, Utils::UniversalSettings::ValueCollection taskSettings, bool testRunOnly = false,
46  std::vector<std::function<void(const int&, const Utils::AtomCollection&, const Utils::Results&, const std::string&)>>
47  observers = {}) const final {
50 
51  // Read and delete special settings
52  bool stopOnError = stopOnErrorExtraction(taskSettings);
53  bool silentCalculator = taskSettings.extract("silent_stdout_calculator", true);
54  if (!taskSettings.empty()) {
55  throw std::logic_error(falseTaskSettingsErrorMessage(name()));
56  }
57  if (observers.size() > 0) {
58  throw std::logic_error("BondOrderTask does not feature algorithm accepting observers, yet one was given");
59  }
60  // If no errors encountered until here, the basic settings should be alright
61  if (testRunOnly) {
62  return true;
63  }
64 
65  // Note: _input is guaranteed not to be empty by Task constructor
66  auto calc = copyCalculator(systems, _input.front(), name());
67  const auto previousResults = calc->results();
68  Utils::CalculationRoutines::setLog(*calc, true, true, !silentCalculator);
69 
70  // Calculate bond orders and energy if not present in the results yet
71  if (!calc->results().has<Utils::Property::BondOrderMatrix>()) {
72  calc->setRequiredProperties(Utils::Property::BondOrderMatrix | Utils::Property::Energy);
73  try {
74  calc->calculate(name());
75  if (!calc->results().get<Utils::Property::SuccessfulCalculation>()) {
76  throw std::runtime_error(name() + " was not successful");
77  }
78  }
79  catch (...) {
80  if (stopOnError) {
81  throw;
82  }
83  _logger->warning
84  << " " + name() + " was not successful with error:\n " + boost::current_exception_diagnostic_information()
85  << Core::Log::endl;
86  calc->results() = previousResults + calc->results();
87  return false;
88  }
89  }
90 
91  auto energy = calc->results().get<Utils::Property::Energy>();
92  auto bos = calc->results().get<Utils::Property::BondOrderMatrix>();
93 
94  // Print
95  auto cout = _logger->output;
96  cout.printf(" The (electronic) energy is: %+16.9f hartree\n\n\n", energy);
97  cout << " Showing all bond orders >0.3 a.u.:\n\n";
98  cout << " Atom#1 Atom#2 Bond Order\n\n";
99  const auto& mat = bos.getMatrix();
100  for (int i = 0; i < mat.outerSize(); i++) {
101  for (typename Eigen::SparseMatrix<double>::InnerIterator it(mat, i); it; ++it) {
102  if (it.value() > 0.3 && it.row() < it.col()) {
103  cout.printf(" %6d %6d %+16.9f\n", it.row(), it.col(), it.value());
104  }
105  }
106  }
107  cout << Core::Log::nl << Core::Log::endl;
108 
109  calc->results() = previousResults + calc->results();
110  // Store result
111  if (!_output.empty()) {
112  systems[_output.front()] = std::move(calc);
113  }
114  else {
115  systems[_input.front()] = std::move(calc);
116  }
117 
118  return true;
119  }
120 };
121 
122 } // namespace Readuct
123 } // namespace Scine
124 
125 #endif // READUCT_BONDORDERTASK_H_
BondOrderTask(std::vector< std::string > input, std::vector< std::string > output, std::shared_ptr< Core::Log > logger=nullptr)
Construct a new BondOrderTask.
Definition: BondOrderTask.h:37
void warningIfMultipleOutputsGiven() const
Warn if more than one output system was specified.
Definition: Task.h:107
std::string name() const override
Getter for the tasks name.
Definition: BondOrderTask.h:41
static std::ostream & endl(std::ostream &os)
bool run(SystemsMap &systems, Utils::UniversalSettings::ValueCollection taskSettings, bool testRunOnly=false, std::vector< std::function< void(const int &, const Utils::AtomCollection &, const Utils::Results &, const std::string &)>> observers={}) const final
Executes the actual task represented by this class.
Definition: BondOrderTask.h:45
Definition: BondOrderTask.h:26
const std::vector< std::string > & input() const
Getter for the expected names of the input systems.
Definition: Task.h:85
static std::ostream & nl(std::ostream &os)
void warningIfMultipleInputsGiven() const
Warn if more than one input system was specified.
Definition: Task.h:98
const std::vector< std::string > & output() const
Getter for the names of the output systems generated by this task.
Definition: Task.h:92
The base class for all tasks in Readuct.
Definition: Task.h:29