parallelisation of lbfgs, change indentation, more comments

This commit is contained in:
alxvov 2019-07-02 18:02:22 +00:00
parent 707c5b1303
commit e3ed8d8562
1 changed files with 79 additions and 61 deletions

View File

@ -12,7 +12,7 @@
------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------
Contributing authors: Aleksei Ivanov (UI)
Contributing authors: Aleksei Ivanov (University of Iceland)
Julien Tranchida (SNL)
Please cite the related publication:
@ -176,6 +176,7 @@ int MinSpinOSO_LBFGS_LS::iterate(int maxiter)
double fmdotfm;
int flag, flagall;
double **sp = atom->sp;
double der_e_cur_global = 0.0;
if (nlocal_max < nlocal) {
nlocal_max = nlocal;
@ -213,6 +214,8 @@ int MinSpinOSO_LBFGS_LS::iterate(int maxiter)
for (int i = 0; i < 3 * nlocal; i++) {
der_e_cur += g_cur[i] * p_s[i];
}
MPI_Allreduce(&der_e_cur, &der_e_cur_global, 1, MPI_DOUBLE, MPI_SUM, world);
der_e_cur = der_e_cur_global;
}
if (use_line_search){
@ -353,7 +356,10 @@ void MinSpinOSO_LBFGS_LS::calc_gradient(double dts)
}
/* ----------------------------------------------------------------------
search direction
search direction:
Limited-memory BFGS.
See Jorge Nocedal and Stephen J. Wright 'Numerical
Optimization' Second Edition, 2006 (p. 177)
---------------------------------------------------------------------- */
void MinSpinOSO_LBFGS_LS::calc_search_direction(int iter)
@ -629,9 +635,9 @@ void MinSpinOSO_LBFGS_LS::make_step(double c, double *energy_and_der)
double rot_mat[9]; // exponential of matrix made of search direction
double s_new[3];
double **sp = atom->sp;
double der_e_cur_global = 0.0;;
for (int i = 0; i < nlocal; i++) {
// scale the search direction
for (int j = 0; j < 3; j++) p_scaled[j] = c * p_s[3 * i + j];
@ -653,10 +659,17 @@ void MinSpinOSO_LBFGS_LS::make_step(double c, double *energy_and_der)
for (int i = 0; i < 3 * nlocal; i++) {
der_e_cur += g_cur[i] * p_s[i];
}
MPI_Allreduce(&der_e_cur, &der_e_cur_global, 1, MPI_DOUBLE, MPI_SUM, world);
der_e_cur = der_e_cur_global;
energy_and_der[0] = ecurrent;
energy_and_der[1] = der_e_cur;
}
/* ----------------------------------------------------------------------
Calculate step length which satisfies approximate Wolfe conditions
using the cubic interpolation
------------------------------------------------------------------------- */
int MinSpinOSO_LBFGS_LS::calc_and_make_step(double a, double b, int index)
{
@ -671,6 +684,7 @@ int MinSpinOSO_LBFGS_LS::calc_and_make_step(double a, double b, int index)
index++;
if (awc(der_e_pr, eprevious, e_and_d[1], e_and_d[0]) || index == 3){
MPI_Bcast(&b,1,MPI_DOUBLE,0,world);
for (int i = 0; i < 3 * nlocal; i++) {
p_s[i] = b * p_s[i];
@ -689,6 +703,9 @@ int MinSpinOSO_LBFGS_LS::calc_and_make_step(double a, double b, int index)
c2 = 3.0*(f1-f0)/(r*r)-(df1+2.0*df0)/(r);
c3 = df0;
// f(x) = c1 x^3 + c2 x^2 + c3 x^1 + c4
// has minimum at alpha below. We do not check boundaries.
alpha = (-c2 + sqrt(c2*c2 - 3.0*c1*c3))/(3.0*c1);
if (alpha < 0.0) alpha = r/2.0;
@ -699,18 +716,19 @@ int MinSpinOSO_LBFGS_LS::calc_and_make_step(double a, double b, int index)
}
return 0;
}
/* ----------------------------------------------------------------------
Approximate Wolfe conditions:
William W. Hager and Hongchao Zhang
SIAM J. optim., 16(1), 170-192. (23 pages)
------------------------------------------------------------------------- */
int MinSpinOSO_LBFGS_LS::awc(double der_phi_0, double phi_0, double der_phi_j, double phi_j){
double eps = 1.0e-6;
double delta = 0.1;
double sigma = 0.9;
if ((phi_j <= phi_0 + eps * fabs(phi_0)) &&
((2.0*delta - 1.0) * der_phi_0 >= der_phi_j >= sigma * der_phi_0))
if ((phi_j <= phi_0 + eps * fabs(phi_0)) && ((2.0*delta - 1.0) * der_phi_0 >= der_phi_j >= sigma * der_phi_0))
return 1;
else
return 0;