Commit JT 092419
- added inf norm option
This commit is contained in:
BIN
doc/src/Eqs/norm_inf.jpg
Normal file
BIN
doc/src/Eqs/norm_inf.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
15
doc/src/Eqs/norm_inf.tex
Normal file
15
doc/src/Eqs/norm_inf.tex
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
\documentclass[preview]{standalone}
|
||||||
|
\usepackage{varwidth}
|
||||||
|
\usepackage[utf8x]{inputenc}
|
||||||
|
\usepackage{amsmath, amssymb, graphics, setspace}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\begin{varwidth}{50in}
|
||||||
|
\begin{equation}
|
||||||
|
|| \vec{F} ||_{inf}
|
||||||
|
= {\rm max}\left(|F_1^1|, |F_1^2|, |F_1^3| \cdots,
|
||||||
|
|F_N^1|, |F_N^2|, |F_N^3|\right)
|
||||||
|
\nonumber
|
||||||
|
\end{equation}
|
||||||
|
\end{varwidth}
|
||||||
|
\end{document}
|
||||||
@ -20,7 +20,8 @@ keyword = {dmax} or {line} or {norm} or {alpha_damp} or {discrete_factor}
|
|||||||
backtrack,quadratic,forcezero,spin_cubic,spin_none = style of linesearch to use
|
backtrack,quadratic,forcezero,spin_cubic,spin_none = style of linesearch to use
|
||||||
{norm} value = {two} or {max}
|
{norm} value = {two} or {max}
|
||||||
two = Euclidean two-norm (length of 3N vector)
|
two = Euclidean two-norm (length of 3N vector)
|
||||||
max = max value of across all 3-vectors
|
inf = max force component across all 3-vectors
|
||||||
|
max = max force norm across all 3-vectors
|
||||||
{alpha_damp} value = damping
|
{alpha_damp} value = damping
|
||||||
damping = fictitious Gilbert damping for spin minimization (adim)
|
damping = fictitious Gilbert damping for spin minimization (adim)
|
||||||
{discrete_factor} value = factor
|
{discrete_factor} value = factor
|
||||||
@ -86,6 +87,11 @@ all atoms
|
|||||||
|
|
||||||
:c,image(Eqs/norm_max.jpg)
|
:c,image(Eqs/norm_max.jpg)
|
||||||
|
|
||||||
|
The {inf} norm takes the maximum component across the forces of
|
||||||
|
all atoms in the system:
|
||||||
|
|
||||||
|
:c,image(Eqs/norm_inf.jpg)
|
||||||
|
|
||||||
For the min styles {spin}, {spin/cg} and {spin/lbfgs}, the force
|
For the min styles {spin}, {spin/cg} and {spin/lbfgs}, the force
|
||||||
norm is replaced by the spin-torque norm.
|
norm is replaced by the spin-torque norm.
|
||||||
|
|
||||||
|
|||||||
@ -165,8 +165,10 @@ int MinSpin::iterate(int maxiter)
|
|||||||
|
|
||||||
fmdotfm = fmsq = 0.0;
|
fmdotfm = fmsq = 0.0;
|
||||||
if (update->ftol > 0.0) {
|
if (update->ftol > 0.0) {
|
||||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
if (normstyle == MAX) fmsq = max_torque(); // max torque norm
|
||||||
else fmsq = total_torque(); // Euclidean 2-norm
|
else if (normstyle == INF) fmsq = inf_torque(); // inf torque norm
|
||||||
|
else if (normstyle == TWO) fmsq = total_torque(); // Euclidean torque 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
fmdotfm = fmsq*fmsq;
|
fmdotfm = fmsq*fmsq;
|
||||||
if (update->multireplica == 0) {
|
if (update->multireplica == 0) {
|
||||||
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
||||||
|
|||||||
@ -270,8 +270,10 @@ int MinSpinCG::iterate(int maxiter)
|
|||||||
|
|
||||||
fmdotfm = fmsq = 0.0;
|
fmdotfm = fmsq = 0.0;
|
||||||
if (update->ftol > 0.0) {
|
if (update->ftol > 0.0) {
|
||||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
if (normstyle == MAX) fmsq = max_torque(); // max torque norm
|
||||||
else fmsq = total_torque(); // Euclidean 2-norm
|
else if (normstyle == INF) fmsq = inf_torque(); // inf torque norm
|
||||||
|
else if (normstyle == TWO) fmsq = total_torque(); // Euclidean torque 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
fmdotfm = fmsq*fmsq;
|
fmdotfm = fmsq*fmsq;
|
||||||
if (update->multireplica == 0) {
|
if (update->multireplica == 0) {
|
||||||
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
||||||
|
|||||||
@ -285,8 +285,10 @@ int MinSpinLBFGS::iterate(int maxiter)
|
|||||||
|
|
||||||
fmdotfm = fmsq = 0.0;
|
fmdotfm = fmsq = 0.0;
|
||||||
if (update->ftol > 0.0) {
|
if (update->ftol > 0.0) {
|
||||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
if (normstyle == MAX) fmsq = max_torque(); // max torque norm
|
||||||
else fmsq = total_torque(); // Euclidean 2-norm
|
else if (normstyle == INF) fmsq = inf_torque(); // inf torque norm
|
||||||
|
else if (normstyle == TWO) fmsq = total_torque(); // Euclidean torque 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
fmdotfm = fmsq*fmsq;
|
fmdotfm = fmsq*fmsq;
|
||||||
if (update->multireplica == 0) {
|
if (update->multireplica == 0) {
|
||||||
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
||||||
|
|||||||
34
src/min.cpp
34
src/min.cpp
@ -670,6 +670,7 @@ void Min::modify_params(int narg, char **arg)
|
|||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
|
||||||
if (strcmp(arg[iarg+1],"two") == 0) normstyle = TWO;
|
if (strcmp(arg[iarg+1],"two") == 0) normstyle = TWO;
|
||||||
else if (strcmp(arg[iarg+1],"max") == 0) normstyle = MAX;
|
else if (strcmp(arg[iarg+1],"max") == 0) normstyle = MAX;
|
||||||
|
else if (strcmp(arg[iarg+1],"inf") == 0) normstyle = INF;
|
||||||
else error->all(FLERR,"Illegal min_modify command");
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else {
|
} else {
|
||||||
@ -899,6 +900,39 @@ double Min::total_torque()
|
|||||||
return sqrt(ftotsqall) * hbar;
|
return sqrt(ftotsqall) * hbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute and return max_i ||mag. torque components|| (in eV)
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Min::inf_torque()
|
||||||
|
{
|
||||||
|
double fmsq,fmaxsqone,fmaxsqall;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
double hbar = force->hplanck/MY_2PI;
|
||||||
|
double tx,ty,tz;
|
||||||
|
double **sp = atom->sp;
|
||||||
|
double **fm = atom->fm;
|
||||||
|
|
||||||
|
fmsq = fmaxsqone = fmaxsqall = 0.0;
|
||||||
|
for (int i = 0; i < nlocal; i++) {
|
||||||
|
tx = fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1];
|
||||||
|
ty = fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2];
|
||||||
|
tz = fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0];
|
||||||
|
fmaxsqone = MAX(fmaxsqone,tx*tx);
|
||||||
|
fmaxsqone = MAX(fmaxsqone,ty*ty);
|
||||||
|
fmaxsqone = MAX(fmaxsqone,tz*tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finding max fm on this replica
|
||||||
|
|
||||||
|
fmaxsqall = fmaxsqone;
|
||||||
|
MPI_Allreduce(&fmaxsqone,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,world);
|
||||||
|
|
||||||
|
// multiply it by hbar so that units are in eV
|
||||||
|
|
||||||
|
return sqrt(fmaxsqall) * hbar;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute and return max_i ||mag. torque_i|| (in eV)
|
compute and return max_i ||mag. torque_i|| (in eV)
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -43,11 +43,12 @@ class Min : protected Pointers {
|
|||||||
double fnorm_inf();
|
double fnorm_inf();
|
||||||
double fnorm_max();
|
double fnorm_max();
|
||||||
|
|
||||||
enum{TWO,MAX};
|
enum{TWO,MAX,INF};
|
||||||
|
|
||||||
// methods for spin minimizers
|
// methods for spin minimizers
|
||||||
double max_torque();
|
|
||||||
double total_torque();
|
double total_torque();
|
||||||
|
double inf_torque();
|
||||||
|
double max_torque();
|
||||||
|
|
||||||
virtual void init_style() {}
|
virtual void init_style() {}
|
||||||
virtual void setup_style() = 0;
|
virtual void setup_style() = 0;
|
||||||
@ -67,8 +68,7 @@ class Min : protected Pointers {
|
|||||||
int linestyle; // 0 = backtrack, 1 = quadratic, 2 = forcezero
|
int linestyle; // 0 = backtrack, 1 = quadratic, 2 = forcezero
|
||||||
// 3 = spin_cubic, 4 = spin_none
|
// 3 = spin_cubic, 4 = spin_none
|
||||||
|
|
||||||
int normstyle; // TWO or MAX flag for force norm evaluation
|
int normstyle; // TWO, MAX or INF flag for force norm evaluation
|
||||||
// int normstyle; // 0 = Euclidean norm, 1 = inf. norm
|
|
||||||
|
|
||||||
int nelist_global,nelist_atom; // # of PE,virial computes to check
|
int nelist_global,nelist_atom; // # of PE,virial computes to check
|
||||||
int nvlist_global,nvlist_atom;
|
int nvlist_global,nvlist_atom;
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include "min_cg.h"
|
#include "min_cg.h"
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "error.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@ -110,12 +111,15 @@ int MinCG::iterate(int maxiter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmax = 0.0;
|
fmax = 0.0;
|
||||||
if (normstyle == MAX) { // max force norm
|
if (normstyle == MAX) { // max force norm
|
||||||
fmax = fnorm_max();
|
fmax = fnorm_max();
|
||||||
if (fmax < update->ftol*update->ftol) return FTOL;
|
if (fmax < update->ftol*update->ftol) return FTOL;
|
||||||
} else { // Euclidean force 2-norm
|
} else if (normstyle == INF) { // infinite force norm
|
||||||
|
fmax = fnorm_inf();
|
||||||
|
if (fmax < update->ftol*update->ftol) return FTOL;
|
||||||
|
} else if (normstyle == TWO) { // Euclidean force 2-norm
|
||||||
if (dotall[0] < update->ftol*update->ftol) return FTOL;
|
if (dotall[0] < update->ftol*update->ftol) return FTOL;
|
||||||
}
|
} else error->all(FLERR,"Illegal min_modify command");
|
||||||
|
|
||||||
// update new search direction h from new f = -Grad(x) and old g
|
// update new search direction h from new f = -Grad(x) and old g
|
||||||
// this is Polak-Ribieri formulation
|
// this is Polak-Ribieri formulation
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "universe.h"
|
#include "universe.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "error.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
@ -250,8 +251,10 @@ int MinFire::iterate(int maxiter)
|
|||||||
// sync across replicas if running multi-replica minimization
|
// sync across replicas if running multi-replica minimization
|
||||||
|
|
||||||
if (update->ftol > 0.0) {
|
if (update->ftol > 0.0) {
|
||||||
if (normstyle == MAX) fdotf = fnorm_inf(); // max force norm
|
if (normstyle == MAX) fdotf = fnorm_max(); // max force norm
|
||||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
else if (normstyle == INF) fdotf = fnorm_inf(); // inf force norm
|
||||||
|
else if (normstyle == TWO) fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
if (update->multireplica == 0) {
|
if (update->multireplica == 0) {
|
||||||
if (fdotf < update->ftol*update->ftol) return FTOL;
|
if (fdotf < update->ftol*update->ftol) return FTOL;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "universe.h"
|
#include "universe.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "error.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
@ -215,8 +216,10 @@ int MinQuickMin::iterate(int maxiter)
|
|||||||
// sync across replicas if running multi-replica minimization
|
// sync across replicas if running multi-replica minimization
|
||||||
|
|
||||||
if (update->ftol > 0.0) {
|
if (update->ftol > 0.0) {
|
||||||
if (normstyle == MAX) fdotfloc = fnorm_max(); // max force norm
|
if (normstyle == MAX) fdotfloc = fnorm_max(); // max force norm
|
||||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
else if (normstyle == INF) fdotfloc = fnorm_inf(); // inf force norm
|
||||||
|
else if (normstyle == TWO) fdotfloc = fnorm_sqr(); // Euclidean force 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
if (update->multireplica == 0) {
|
if (update->multireplica == 0) {
|
||||||
if (fdotf < update->ftol*update->ftol) return FTOL;
|
if (fdotf < update->ftol*update->ftol) return FTOL;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "min_sd.h"
|
#include "min_sd.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "error.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@ -77,8 +78,10 @@ int MinSD::iterate(int maxiter)
|
|||||||
|
|
||||||
// force tolerance criterion
|
// force tolerance criterion
|
||||||
|
|
||||||
if (normstyle == MAX) fdotf = fnorm_max(); // max force norm
|
if (normstyle == MAX) fdotf = fnorm_max(); // max force norm
|
||||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
else if (normstyle == INF) fdotf = fnorm_inf(); // infinite force norm
|
||||||
|
else if (normstyle == TWO) fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
||||||
|
else error->all(FLERR,"Illegal min_modify command");
|
||||||
if (fdotf < update->ftol*update->ftol) return FTOL;
|
if (fdotf < update->ftol*update->ftol) return FTOL;
|
||||||
|
|
||||||
// set new search direction h to f = -Grad(x)
|
// set new search direction h to f = -Grad(x)
|
||||||
|
|||||||
Reference in New Issue
Block a user