votca 2024.2-dev
Loading...
Searching...
No Matches
eqm.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2023 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20#include <filesystem>
21
22// Third party includes
23#include <boost/format.hpp>
24#include <boost/math/constants/constants.hpp>
25
26// Local VOTCA includes
29
30// Local private VOTCA includes
31#include "eqm.h"
32
33using boost::format;
34
35namespace votca {
36namespace xtp {
37
39
41
42 // job tasks
43 std::string tasks_string = options.get(".tasks").as<std::string>();
44
45 // We split either on a space or a comma
46 tools::Tokenizer tokenizedTasks(tasks_string, " ,");
47 std::vector<std::string> tasks = tokenizedTasks.ToVector();
48
49 do_dft_input_ = std::find(tasks.begin(), tasks.end(), "input") != tasks.end();
50 do_dft_run_ = std::find(tasks.begin(), tasks.end(), "dft") != tasks.end();
51 do_dft_parse_ = std::find(tasks.begin(), tasks.end(), "parse") != tasks.end();
52 do_gwbse_ = std::find(tasks.begin(), tasks.end(), "gwbse") != tasks.end();
53 do_esp_ = std::find(tasks.begin(), tasks.end(), "esp") != tasks.end();
54
55 // set the basis sets and functional for DFT and GWBSE
56 gwbse_options_ = options.get("gwbse");
57 package_options_ = options.get("dftpackage");
58 esp_options_ = options.get(".esp_options");
59}
60
61void EQM::WriteJobFile(const Topology& top) {
62
63 std::cout << "\n... ... Writing job file: " << jobfile_ << std::flush;
64 std::ofstream ofs;
65 ofs.open(jobfile_, std::ofstream::out);
66 if (!ofs.is_open()) {
67 throw std::runtime_error("\nERROR: bad file handle: " + jobfile_);
68 }
69 ofs << "<jobs>" << std::endl;
70 Index jobCount = 0;
71
72 const std::vector<Segment>& segments = top.Segments();
73 for (const Segment& segment : segments) {
74 Index id = segment.getId();
75 std::string tag = "";
76 tools::Property Input;
77 tools::Property& pInput = Input.add("input", "");
78 tools::Property& pSegment =
79 pInput.add("segment", (format("%1$s") % segment.getId()).str());
80 pSegment.setAttribute<std::string>("type", segment.getType());
81 pSegment.setAttribute<Index>("id", segment.getId());
82 Job job(id, tag, Input, Job::AVAILABLE);
83 job.ToStream(ofs);
84 jobCount++;
85 }
86
87 ofs << "</jobs>" << std::endl;
88 ofs.close();
89
90 std::cout << " with " << jobCount << " jobs" << std::flush;
91}
92
94 const std::string& errormessage) {
95 XTP_LOG(Log::error, pLog) << errormessage << std::flush;
96 std::cout << pLog;
97 jres.setError(errormessage);
99}
100
101void EQM::WriteLoggerToFile(const std::string& logfile, Logger& logger) {
102 std::ofstream ofs;
103 ofs.open(logfile, std::ofstream::out);
104 if (!ofs.is_open()) {
105 throw std::runtime_error("Bad file handle: " + logfile);
106 }
107 ofs << logger << std::endl;
108 ofs.close();
109}
110
111Job::JobResult EQM::EvalJob(const Topology& top, Job& job, QMThread& opThread) {
112 Orbitals orbitals;
114 tools::Property job_input_ = job.getInput();
115 std::vector<tools::Property*> lSegments = job_input_.Select("segment");
116 Index segId = lSegments.front()->getAttribute<Index>("id");
117 std::string segType = lSegments.front()->getAttribute<std::string>("type");
118 std::string qmgeo_state = "n";
119 if (lSegments.front()->exists("qm_geometry")) {
120 qmgeo_state = lSegments.front()->getAttribute<std::string>("qm_geometry");
121 }
122
123 QMState state(qmgeo_state);
124 const Segment& seg = top.getSegment(segId);
125
126 Logger& pLog = opThread.getLogger();
127 QMMapper mapper(pLog);
129 orbitals.QMAtoms() = mapper.map(seg, state);
130 XTP_LOG(Log::error, pLog)
131 << TimeStamp() << " Evaluating site " << seg.getId() << std::flush;
132
133 // directories and files
134 std::filesystem::path arg_path;
135 std::string eqm_work_dir = "OR_FILES";
136 std::string frame_dir =
137 "frame_" + boost::lexical_cast<std::string>(top.getStep());
138 std::string orb_file =
139 (format("%1%_%2%%3%") % "molecule" % segId % ".orb").str();
140 std::string mol_dir = (format("%1%%2%%3%") % "molecule" % "_" % segId).str();
141 std::string package_append = "workdir_" + Identify();
142 std::string work_dir =
143 (arg_path / eqm_work_dir / package_append / frame_dir / mol_dir)
144 .generic_string();
145
146 tools::Property job_summary;
147 tools::Property& output_summary = job_summary.add("output", "");
148 tools::Property& segment_summary = output_summary.add("segment", "");
149 std::string segName = seg.getType();
150 segId = seg.getId();
151 segment_summary.setAttribute("id", segId);
152 segment_summary.setAttribute("type", segName);
154 XTP_LOG(Log::error, pLog) << "Running DFT" << std::flush;
156 dft_logger.setMultithreading(false);
157 dft_logger.setPreface(Log::info, (format("\nDFT INF ...")).str());
158 dft_logger.setPreface(Log::error, (format("\nDFT ERR ...")).str());
159 dft_logger.setPreface(Log::warning, (format("\nDFT WAR ...")).str());
160 dft_logger.setPreface(Log::debug, (format("\nDFT DBG ...")).str());
161 std::string package = package_options_.get(".name").as<std::string>();
162 std::unique_ptr<QMPackage> qmpackage = QMPackageFactory().Create(package);
163 qmpackage->setLog(&dft_logger);
164 qmpackage->setRunDir(work_dir);
165 qmpackage->Initialize(package_options_);
166
167 // create input for DFT
168 if (do_dft_input_) {
169 std::filesystem::create_directories(work_dir);
170 qmpackage->WriteInputFile(orbitals);
171 }
172
173 if (do_dft_run_) {
174 bool run_dft_status = qmpackage->Run();
175 if (!run_dft_status) {
176 std::string output = "DFT run failed";
177 SetJobToFailed(jres, pLog, output);
178 return jres;
179 }
180 }
181
182 // parse the log/orbitals files
183 if (do_dft_parse_) {
184 bool parse_log_status = qmpackage->ParseLogFile(orbitals);
185 if (!parse_log_status) {
186 std::string output = "log incomplete; ";
187 SetJobToFailed(jres, pLog, output);
188 return jres;
189 }
190 bool parse_orbitals_status = qmpackage->ParseMOsFile(orbitals);
191 if (!parse_orbitals_status) {
192 std::string output = "orbfile failed; ";
193 SetJobToFailed(jres, pLog, output);
194 return jres;
195 }
196 // additionally copy *.gbw files for orca (-> iqm guess)
197 if (qmpackage->getPackageName() == "orca") {
198 std::string DIR = eqm_work_dir + "/molecules/" + frame_dir;
199 std::filesystem::create_directories(DIR);
200 std::string gbw_file =
201 (format("%1%_%2%%3%") % "molecule" % segId % ".gbw").str();
202 std::string GBWFILE = DIR + "/" + gbw_file;
203 XTP_LOG(Log::error, pLog)
204 << "Copying MO data to " << gbw_file << std::flush;
205 std::string GBWFILE_workdir =
206 work_dir + "/" +
207 package_options_.get("temporary_file").as<std::string>() + ".gbw";
208 std::filesystem::copy_file(
209 GBWFILE_workdir, GBWFILE,
210 std::filesystem::copy_options::overwrite_existing);
211 }
212
213 } // end of the parse orbitals/log
214 qmpackage->CleanUp();
215 WriteLoggerToFile(work_dir + "/dft.log", dft_logger);
216 }
217
218 if (!do_dft_parse_ && (do_gwbse_ || do_esp_)) {
219 // load the DFT data from serialized orbitals object
220 std::string ORB_FILE =
221 eqm_work_dir + "/molecules/" + frame_dir + "/" + orb_file;
222 XTP_LOG(Log::error, pLog)
223 << TimeStamp() << " Loading DFT data from " << ORB_FILE << std::flush;
224 orbitals.ReadFromCpt(ORB_FILE);
225 }
226
227 if (do_gwbse_) {
228 XTP_LOG(Log::error, pLog) << "Running GWBSE" << std::flush;
229 try {
230 GWBSE gwbse = GWBSE(orbitals);
231 Logger gwbse_logger(votca::Log::current_level);
232 gwbse_logger.setMultithreading(false);
233 gwbse_logger.setPreface(Log::info, (format("\nGWBSE INF ...")).str());
234 gwbse_logger.setPreface(Log::error, (format("\nGWBSE ERR ...")).str());
235 gwbse_logger.setPreface(Log::warning, (format("\nGWBSE WAR ...")).str());
236 gwbse_logger.setPreface(Log::debug, (format("\nGWBSE DBG ...")).str());
237 gwbse.setLogger(&gwbse_logger);
239 gwbse.Evaluate();
240 gwbse.addoutput(segment_summary);
241 WriteLoggerToFile(work_dir + "/gwbse.log", gwbse_logger);
242 } catch (std::runtime_error& error) {
243 std::string errormessage(error.what());
244 SetJobToFailed(jres, pLog, "GWBSE:" + errormessage);
245 return jres;
246 }
247 }
248
249 if (do_esp_) {
250 XTP_LOG(Log::error, pLog) << "Running ESPFIT" << std::flush;
251 try {
252 Esp2multipole esp2multipole = Esp2multipole(pLog);
253 esp2multipole.Initialize(esp_options_);
254 std::string ESPDIR =
255 "MP_FILES/" + frame_dir + "/" + esp2multipole.GetStateString();
256 StaticSegment seg2 = esp2multipole.Extractingcharges(orbitals);
257 std::string mps_file = (format("%1%_%2%_%3%.mps") % segType % segId %
258 esp2multipole.GetStateString())
259 .str();
260 std::filesystem::create_directories(ESPDIR);
261 seg2.WriteMPS(ESPDIR + "/" + mps_file,
262 "Generated by eqm:" + esp2multipole.GetStateString());
263 XTP_LOG(Log::error, pLog)
264 << "Written charges to " << (ESPDIR + "/" + mps_file) << std::flush;
265 segment_summary.add("partialcharges", (ESPDIR + "/" + mps_file));
266 } catch (std::runtime_error& error) {
267 std::string errormessage(error.what());
268 SetJobToFailed(jres, pLog, "ESPFIT:" + errormessage);
269 return jres;
270 }
271 }
272 XTP_LOG(Log::error, pLog) << TimeStamp() << " Finished evaluating site "
273 << seg.getId() << std::flush;
274
275 if (do_dft_parse_ || do_gwbse_) {
276 XTP_LOG(Log::error, pLog) << "Saving data to " << orb_file << std::flush;
277 std::string DIR = eqm_work_dir + "/molecules/" + frame_dir;
278 std::filesystem::create_directories(DIR);
279 std::string ORBFILE = DIR + "/" + orb_file;
280 orbitals.WriteToCpt(ORBFILE);
281 }
282
283 // output of the JOB
284 jres.setOutput(job_summary);
286
287 return jres;
288}
289} // namespace xtp
290} // namespace votca
virtual std::unique_ptr< T > Create(const key_t &key, args_t &&...arguments)
class to manage program options with xml serialization functionality
Definition property.h:55
Property & add(const std::string &key, const std::string &value)
add a new property to structure
Definition property.cc:108
Property & get(const std::string &key)
get existing property
Definition property.cc:79
T as() const
return value as type
Definition property.h:283
std::vector< Property * > Select(const std::string &filter)
select property based on a filter
Definition property.cc:185
void setAttribute(const std::string &attribute, const T &value)
set an attribute
Definition property.h:314
break string into words
Definition tokenizer.h:72
const std::string & getType() const
void WriteMPS(std::string filename, std::string header) const
bool do_dft_run_
Definition eqm.h:66
void WriteJobFile(const Topology &top)
Definition eqm.cc:61
tools::Property package_options_
Definition eqm.h:60
void SetJobToFailed(Job::JobResult &jres, Logger &pLog, const std::string &errormessage)
Definition eqm.cc:93
void WriteLoggerToFile(const std::string &logfile, Logger &logger)
Definition eqm.cc:101
bool do_esp_
Definition eqm.h:69
bool do_gwbse_
Definition eqm.h:68
Job::JobResult EvalJob(const Topology &top, Job &job, QMThread &opThread)
Definition eqm.cc:111
tools::Property esp_options_
Definition eqm.h:62
bool do_dft_parse_
Definition eqm.h:67
tools::Property gwbse_options_
Definition eqm.h:61
void ParseSpecificOptions(const tools::Property &user_options)
Definition eqm.cc:38
bool do_dft_input_
Definition eqm.h:65
std::string Identify() const
Calculator name.
Definition eqm.h:43
void Initialize(tools::Property &options)
std::string GetStateString() const
StaticSegment Extractingcharges(const Orbitals &orbitals) const
Electronic excitations from GW-BSE.
Definition gwbse.h:56
bool Evaluate()
Definition gwbse.cc:544
void addoutput(tools::Property &summary)
Definition gwbse.cc:422
void Initialize(tools::Property &options)
Definition gwbse.cc:60
void setLogger(Logger *pLog)
Definition gwbse.h:63
void setError(std::string error)
Definition job.h:67
void setOutput(std::string output)
Definition job.h:50
void setStatus(JobStatus stat)
Definition job.h:49
tools::Property & getInput()
Definition job.h:87
void ToStream(std::ofstream &ofs) const
Definition job.cc:121
Logger is used for thread-safe output of messages.
Definition logger.h:164
void setPreface(Log::Level level, const std::string &preface)
Definition logger.h:194
void setMultithreading(bool maverick)
Definition logger.h:186
container for molecular orbitals
Definition orbitals.h:46
const QMMolecule & QMAtoms() const
Definition orbitals.h:172
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:692
void WriteToCpt(const std::string &filename) const
Definition orbitals.cc:615
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
Definition qmstate.h:132
Logger & getLogger()
Definition qmthread.h:55
void LoadMappingFile(const std::string &mapfile)
AtomContainer map(const Segment &seg, const SegId &segid) const
Timestamp returns the current time as a string Example: cout << TimeStamp()
Definition logger.h:224
Container for segments and box and atoms.
Definition topology.h:41
Index getStep() const
Definition topology.h:75
std::vector< Segment > & Segments()
Definition topology.h:58
Segment & getSegment(Index id)
Definition topology.h:55
#define XTP_LOG(level, log)
Definition logger.h:40
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
static Level current_level
Definition globals.h:30