forked from lijiext/lammps
parallelisation of lbfgs, change indentation, more comments
This commit is contained in:
parent
707c5b1303
commit
e3ed8d8562
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue