-
Notifications
You must be signed in to change notification settings - Fork 0
/
transversePotential.cc
117 lines (94 loc) · 3.28 KB
/
transversePotential.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <dlib/optimization.h>
#include <cassert>
#include "stop_strategy.h"
#include "potential.h"
#include "transversePotential.h"
#include "lina.h"
#include "iop.h"
#include "globals.h"
using namespace std;
void TransversePotential::setVector (double &eval, column_vector &v)
{
_eval = eval;
_vector = v / sqrt(dot(v, v));
}
void TransversePotential::setVector (double &eval, vector<double> &v)
{
_eval = eval;
column_vector vector(v.size());
for (int i = 0; i < v.size() ; i++)
{
vector(i) = v[i];
}
_vector = vector / sqrt(dot(vector, vector));
}
column_vector TransversePotential::getTransverseGradient (const column_vector &v)
{
assert(_vector.size() == v.size());
const column_vector g = getTrueGradient(v);
assert(_vector.size() == g.size());
return g - dot(g, _vector) * _vector;
}
column_vector TransversePotential::getTransverseGradient (structure &S)
{
assert(_vector.size());
column_vector g = getTrueGradient(S);
assert(_vector.size() == g.size());
return g - dot(g, _vector) * _vector;
}
void TransversePotential::calcTransverseDirection (structure &S)
{
vector< vector<double> > hessian = _potential->calcHessian(S);
vector<pair<double, vector<double> > > eval_evec = diagv(hessian);
pair<double,vector<double> > lowest_eval_evec = _potential->getLowestEvec(eval_evec);
setVector(lowest_eval_evec.first, lowest_eval_evec.second);
}
structure TransversePotential::optimize (structure &S)
{
column_vector x = S.getFlattenedCoordinates();
auto f = [this] (column_vector v) -> const double {return this->getEnergy(v);};
auto df = [this] (column_vector v) -> column_vector {return this->getTransverseGradient(v);};
try
{
switch (_potential->getAlgoSwitch())
{
case 1:
{
dlib::find_min( dlib::bfgs_search_strategy(),
dlib::stop_strategy(_potential->getStopCrit(), _potential->getNsteps()),
f, df, x, -(S.nAtoms()) * 1000);
break;
}
case 2:
{
dlib::find_min( dlib::cg_search_strategy(),
dlib::stop_strategy(_potential->getStopCrit(), _potential->getNsteps()),
f, df, x, -(S.nAtoms()) * 1000);
break;
}
default:
{
cerr << "Bad input of algorithm name" << endl;
structure newS(S.getNumber(), S.getCoordinates());
return newS;
}
}
}
catch (std::exception &e)
{
structure newS(S.getNumber(), S.getCoordinates());
return newS;
}
vector<coord3d> newCoordinates = structure::unflattenCoordinates(x);
structure newS(S.getNumber(), newCoordinates, true);
double finalEnergy = this->getEnergy(x);
newS.setEnergy(finalEnergy);
newS.setConverged();
cout << "gT: " << dlib::length(this->getTransverseGradient(x)) << endl;
cout << "g: " << dlib::length(this->getTrueGradient(x)) << endl;
vector< vector<double> > hessian = _potential->calcHessian(newS);
vector<double> eval = diag(hessian);
//for (auto& i : eval)
// cout << "H: " << i << endl;
return newS;
}