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/EonLogger.h"
14#include "eon/EpiCenters.h"
15#include "eon/HelperFunctions.h"
16#include "eon/Matter.h"
17#include "eon/PotRegistry.h"
18
19#include <format>
20#include <fstream>
21#include <stdexcept>
22
23using namespace eonc::helpers;
24
25std::vector<std::string> FiniteDifferenceJob::run(void) {
26 auto reactant = std::make_unique<Matter>(pot, params);
27 if (!eonc::io::io_ok(reactant->con2matter("pos.con"))) {
28 EONC_LOG_CRITICAL("Failed to load pos.con");
29 throw std::runtime_error("failed to load pos.con");
30 }
31 AtomMatrix posA = reactant->getPositions();
32
33 double dRs[] = {1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 5e-3, 0.01, 0.05, 0.1, -1};
34
35 AtomMatrix forceA = reactant->getForces();
36
38 reactant.get(), params.structure_comparison_options.neighbor_cutoff);
39 AtomMatrix displacement;
40 displacement.resize(reactant->numberOfAtoms(), 3);
41 displacement.setZero();
42 printf("displacing atoms:");
43 for (int i = 0; i < reactant->numberOfAtoms(); i++) {
44 if (reactant->distance(epicenter, i) <= 3.3) {
45 printf(" %i", i);
46 for (int j = 0; j < 3; j++) {
47 if (!reactant->getFixed(i)) {
48 displacement(i, j) = randomDouble(1.0);
49 }
50 }
51 }
52 }
53 printf("\n");
54 displacement.normalize();
55
56 std::ofstream results("results.dat");
57 results << "0 termination_reason\n";
58 results << "GOOD termination_reason_text\n";
59 results << "finite_difference job_type\n";
60 results << std::format("{} total_force_calls\n",
61 PotRegistry::get().total_force_calls());
62
63 std::ofstream table("curvature.dat");
64 table << std::format("{:>14s} {:>14s}\n", "dR", "curvature");
65 printf("%14s %14s\n", "dR", "curvature");
66 AtomMatrix posB;
67 AtomMatrix forceB;
68 double curvature = 0.0;
69 for (int dRi = 0; dRs[dRi] != -1; dRi++) {
70 posB = posA + displacement * dRs[dRi];
71 reactant->setPositions(posB);
72 forceB = reactant->getForces();
73 curvature = matDot(forceB - forceA, displacement) / dRs[dRi];
74 table << std::format("{:14.8f} {:14.8f}\n", dRs[dRi], curvature);
75 results << std::format("{:.12e} dR_{}\n", dRs[dRi], dRi);
76 results << std::format("{:.12e} curvature_{}\n", curvature, dRi);
77 printf("%14.8f %14.8f\n", dRs[dRi], curvature);
78 table.flush();
79 }
80
81 std::vector<std::string> returnFiles;
82 returnFiles.push_back("results.dat");
83 returnFiles.push_back("curvature.dat");
84 return returnFiles;
85}
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_CRITICAL(...)
Definition EonLogger.h:268
std::vector< std::string > run(void)
Virtual run; used solely for dynamic dispatch.
std::shared_ptr< Potential > pot
Definition Job.h:55
Parameters params
Definition Job.h:54
static PotRegistry & get() noexcept
Process-lifetime singleton.
long minCoordinatedEpiCenter(const Matter *matter, double neighborCutoff)
double randomDouble()
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38