Scine::Readuct  4.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) const final {
48 
49  // Read and delete special settings
50  bool stopOnError = stopOnErrorExtraction(taskSettings);
51  bool silentCalculator = taskSettings.extract("silent_stdout_calculator", true);
52  if (!taskSettings.empty()) {
53  throw std::logic_error(falseTaskSettingsErrorMessage(name()));
54  }
55  // If no errors encountered until here, the basic settings should be alright
56  if (testRunOnly) {
57  return true;
58  }
59 
60  // Note: _input is guaranteed not to be empty by Task constructor
61  auto calc = copyCalculator(systems, _input.front(), name());
62  Utils::CalculationRoutines::setLog(*calc, true, true, !silentCalculator);
63 
64  // Calculate bond orders and energy if not present in the results yet
65  if (!calc->results().has<Utils::Property::BondOrderMatrix>()) {
66  calc->setRequiredProperties(Utils::Property::BondOrderMatrix | Utils::Property::Energy);
67  try {
68  calc->calculate(name());
69  if (!calc->results().get<Utils::Property::SuccessfulCalculation>()) {
70  throw std::runtime_error(name() + " was not successful");
71  }
72  }
73  catch (...) {
74  if (stopOnError) {
75  throw;
76  }
77  _logger->warning
78  << " " + name() + " was not successful with error:\n " + boost::current_exception_diagnostic_information()
79  << Core::Log::endl;
80  return false;
81  }
82  }
83 
84  auto energy = calc->results().get<Utils::Property::Energy>();
85  auto bos = calc->results().get<Utils::Property::BondOrderMatrix>();
86 
87  // Print
88  auto cout = _logger->output;
89  cout.printf(" The (electronic) energy is: %+16.9f hartree\n\n\n", energy);
90  cout << " Showing all bond orders >0.3 a.u.:\n\n";
91  cout << " Atom#1 Atom#2 Bond Order\n\n";
92  const auto& mat = bos.getMatrix();
93  for (int i = 0; i < mat.outerSize(); i++) {
94  for (typename Eigen::SparseMatrix<double>::InnerIterator it(mat, i); it; ++it) {
95  if (it.value() > 0.3 && it.row() < it.col()) {
96  cout.printf(" %6d %6d %+16.9f\n", it.row(), it.col(), it.value());
97  }
98  }
99  }
100  cout << Core::Log::nl << Core::Log::endl;
101 
102  // Store result
103  if (!_output.empty()) {
104  systems[_output.front()] = std::move(calc);
105  }
106  else {
107  systems[_input.front()] = std::move(calc);
108  }
109 
110  return true;
111  }
112 };
113 
114 } // namespace Readuct
115 } // namespace Scine
116 
117 #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:99
std::string name() const override
Getter for the tasks name.
Definition: BondOrderTask.h:41
static std::ostream & endl(std::ostream &os)
Definition: BondOrderTask.h:26
const std::vector< std::string > & input() const
Getter for the expected names of the input systems.
Definition: Task.h:77
static std::ostream & nl(std::ostream &os)
bool run(SystemsMap &systems, Utils::UniversalSettings::ValueCollection taskSettings, bool testRunOnly=false) const final
Executes the actual task represented by this class.
Definition: BondOrderTask.h:45
void warningIfMultipleInputsGiven() const
Warn if more than one input system was specified.
Definition: Task.h:90
const std::vector< std::string > & output() const
Getter for the names of the output systems generated by this task.
Definition: Task.h:84
The base class for all tasks in Readuct.
Definition: Task.h:28