Loading...
Searching...
No Matches
FiniteDifferenceJob.cpp
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
13#include "eon/BaseStructures.h"
14#include "eon/EonLogger.h"
15#include "eon/EpiCenters.h"
16#include "eon/HelperFunctions.h"
17#include "eon/JobResult.h"
18#include "eon/Matter.h"
19#include "eon/PotRegistry.h"
20
21#include <array>
22#include <format>
23#include <fstream>
24#include <stdexcept>
25#include <string>
26
27namespace eonc {
28
29std::vector<std::string> FiniteDifferenceJob::run(void) {
30 auto reactant = std::make_unique<Matter>(pot, params);
31 const std::string posFile = eonc::helpers::getRelevantFile("pos.con");
32 if (!eonc::io::io_ok(reactant->con2matter(posFile))) {
33 EONC_LOG_CRITICAL("Failed to load {}", posFile);
34 throw std::runtime_error("failed to load " + posFile);
35 }
36 AtomMatrix posA = reactant->getPositions();
37
38 constexpr std::array<double, 9> dRs = {1e-7, 1e-6, 1e-5, 1e-4, 1e-3,
39 5e-3, 0.01, 0.05, 0.1};
40
41 AtomMatrix forceA = reactant->getForces();
42
43 const double cutoff = params.structure_comparison_options().neighbor_cutoff;
44 long epicenter =
45 eonc::EpiCenters::minCoordinatedEpiCenter(reactant.get(), cutoff);
46 AtomMatrix displacement;
47 displacement.resize(reactant->numberOfAtoms(), 3);
48 displacement.setZero();
49 std::string displaced;
50 for (int i = 0; i < reactant->numberOfAtoms(); i++) {
51 if (reactant->distance(epicenter, i) <= cutoff) {
52 // getFixed(atom) is true only when every axis is fixed. A column-4
53 // mask that freezes one axis must not enter the step or its norm.
54 if (!displaced.empty()) {
55 displaced.push_back(' ');
56 }
57 displaced += std::to_string(i);
58 for (int j = 0; j < 3; j++) {
59 if (reactant->getFixed(i, j)) {
60 continue;
61 }
62 displacement(i, j) = eonc::rng::randomDouble(1.0);
63 }
64 }
65 }
66 EONC_LOG_INFO("displacing atoms: {}", displaced);
67 const double dispNorm = displacement.norm();
68 if (!(dispNorm > 0.0)) {
69 throw std::runtime_error(
70 "FiniteDifferenceJob: no free atoms in the epicenter neighborhood");
71 }
72 displacement /= dispNorm;
73
75 RunStatus::GOOD, params.potential_options().potential,
76 PotRegistry::get().total_force_calls(), false, 0.0);
77 env.job_type = "finite_difference";
78
79 std::ofstream table("curvature.dat");
80 table << std::format("{:>14s} {:>14s}\n", "dR", "curvature");
81 EONC_LOG_INFO("{:>14} {:>14}", "dR", "curvature");
82 AtomMatrix posB;
83 AtomMatrix forceB;
84 double curvature = 0.0;
85 for (size_t dRi = 0; dRi < dRs.size(); ++dRi) {
86 posB = posA + displacement * dRs[dRi];
87 reactant->setPositions(posB);
88 forceB = reactant->getForces();
89 curvature = matDot(forceB - forceA, displacement) / dRs[dRi];
90 table << std::format("{:14.8f} {:14.8f}\n", dRs[dRi], curvature);
91 env.extras.emplace_back(std::format("dR_{}", dRi), dRs[dRi]);
92 env.extras.emplace_back(std::format("curvature_{}", dRi), curvature);
93 EONC_LOG_INFO("{:14.8f} {:14.8f}", dRs[dRi], curvature);
94 table.flush();
95 }
96
97 env.force_calls = PotRegistry::get().total_force_calls();
98 env.writeResultsDat("results.dat");
99 std::vector<std::string> returnFiles;
100 returnFiles.push_back("results.dat");
101 returnFiles.push_back("curvature.dat");
102 return returnFiles;
103}
104
105} // namespace eonc
double matDot(const AtomMatrix &a, const AtomMatrix &b)
SIMD-optimized dot product for contiguous Eigen matrices.
Definition Eigen.h:50
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
#define EONC_LOG_INFO(...)
Definition EonLogger.h:249
#define EONC_LOG_CRITICAL(...)
Definition EonLogger.h:267
std::vector< std::string > run(void) override
Virtual run; used solely for dynamic dispatch.
std::shared_ptr< Potential > pot
Definition Job.h:63
Parameters params
Definition Job.h:58
static PotRegistry & get() noexcept
Process-lifetime singleton.
size_t total_force_calls() const noexcept
long minCoordinatedEpiCenter(const Matter *matter, double neighborCutoff)
std::string getRelevantFile(std::string filename)
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38
double randomDouble()
RAII resource manager for the ARTn C library with global synchronization.
static JobResultEnvelope fromMinimization(RunStatus status, PotType pot, std::uint64_t fcalls, bool hasE, double energy)
Definition JobResult.h:101