Loading...
Searching...
No Matches
DimerRotationDispatch.h
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*/
12#pragma once
13
14#include "BaseStructures.h"
15#include "Davidson.h"
16#include "EonLogger.h"
17#include "LORRotation.h"
18#include "Lanczos.h"
19#include "Matter.h"
20#include "Parameters.h"
21
22#include <memory>
23#include <optional>
24#include <string_view>
25#include <type_traits>
26
27namespace eonc {
28
32 double eigenvalue{0.0};
33 long forceCalls{0};
34 long rotations{0};
37 bool converged{true};
38};
39
40[[nodiscard]] inline constexpr bool
44
45namespace detail {
46
47template <typename Solver>
49 const std::shared_ptr<Matter> &matter, const Parameters &params,
50 const std::shared_ptr<Potential> &pot, const AtomMatrix &initialDirection) {
51 Solver solver(matter, params, pot);
52 solver.compute(matter, initialDirection);
54 out.eigenvector = solver.getEigenvector();
55 out.eigenvalue = solver.getEigenvalue();
56 out.forceCalls = solver.totalForceCalls;
57 out.rotations = solver.statsRotations;
58 if constexpr (std::is_same_v<Solver, LORRotation>) {
59 out.converged = solver.convergedOnResidual;
60 } else {
61 out.converged = true;
62 }
63 return out;
64}
65
66} // namespace detail
67
70[[nodiscard]] inline std::optional<DimerRotationResult> runAlternativeRotation(
71 DimerRotationBackend backend, const std::shared_ptr<Matter> &matter,
72 const Parameters &params, const std::shared_ptr<Potential> &pot,
73 const AtomMatrix &initialDirection, quill::Logger *log = nullptr) {
74 if (!usesAlternativeRotation(backend)) {
75 return std::nullopt;
76 }
77
78 const std::string_view backendName = magic_enum::enum_name(backend);
79
80 if (log) {
81 QUILL_LOG_INFO(log,
82 "[DimerRot] rotation_backend={} (skipping classical "
83 "constrained rotation loop)",
84 backendName);
85 }
86
88 switch (backend) {
90 result = detail::runRotationSolver<LORRotation>(matter, params, pot,
91 initialDirection);
92 break;
94 result = detail::runRotationSolver<Lanczos>(matter, params, pot,
95 initialDirection);
96 break;
98 result = detail::runRotationSolver<Davidson>(matter, params, pot,
99 initialDirection);
100 break;
102 return std::nullopt;
103 }
104
105 if (log) {
106 QUILL_LOG_INFO(log,
107 "[DimerRot] alternative rotation done backend={} "
108 "eigenvalue={:.6f} force_calls={}",
109 backendName, result.eigenvalue, result.forceCalls);
110 }
111 return result;
112}
113
114} // namespace eonc
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
DimerRotationResult runRotationSolver(const std::shared_ptr< Matter > &matter, const Parameters &params, const std::shared_ptr< Potential > &pot, const AtomMatrix &initialDirection)
RAII resource manager for the ARTn C library with global synchronization.
DimerRotationBackend
constexpr bool usesAlternativeRotation(DimerRotationBackend backend) noexcept
std::optional< DimerRotationResult > runAlternativeRotation(DimerRotationBackend backend, const std::shared_ptr< Matter > &matter, const Parameters &params, const std::shared_ptr< Potential > &pot, const AtomMatrix &initialDirection, quill::Logger *log=nullptr)
Run Lanczos, Davidson, or LOR.
Result of a non-classical dimer rotation backend (mode estimate only).
bool converged
LOR: true only when residual stop fired; Lanczos/Davidson: true (internal convergence criteria,...