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
|
||||
{norm} value = {two} or {max}
|
||||
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
|
||||
damping = fictitious Gilbert damping for spin minimization (adim)
|
||||
{discrete_factor} value = factor
|
||||
@ -86,6 +87,11 @@ all atoms
|
||||
|
||||
: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
|
||||
norm is replaced by the spin-torque norm.
|
||||
|
||||
|
||||
@ -165,8 +165,10 @@ int MinSpin::iterate(int maxiter)
|
||||
|
||||
fmdotfm = fmsq = 0.0;
|
||||
if (update->ftol > 0.0) {
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
||||
else fmsq = total_torque(); // Euclidean 2-norm
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max torque 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;
|
||||
if (update->multireplica == 0) {
|
||||
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
||||
|
||||
@ -270,8 +270,10 @@ int MinSpinCG::iterate(int maxiter)
|
||||
|
||||
fmdotfm = fmsq = 0.0;
|
||||
if (update->ftol > 0.0) {
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
||||
else fmsq = total_torque(); // Euclidean 2-norm
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max torque 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;
|
||||
if (update->multireplica == 0) {
|
||||
if (fmdotfm < update->ftol*update->ftol) return FTOL;
|
||||
|
||||
@ -285,8 +285,10 @@ int MinSpinLBFGS::iterate(int maxiter)
|
||||
|
||||
fmdotfm = fmsq = 0.0;
|
||||
if (update->ftol > 0.0) {
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max norm
|
||||
else fmsq = total_torque(); // Euclidean 2-norm
|
||||
if (normstyle == MAX) fmsq = max_torque(); // max torque 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;
|
||||
if (update->multireplica == 0) {
|
||||
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 (strcmp(arg[iarg+1],"two") == 0) normstyle = TWO;
|
||||
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");
|
||||
iarg += 2;
|
||||
} else {
|
||||
@ -899,6 +900,39 @@ double Min::total_torque()
|
||||
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)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -43,11 +43,12 @@ class Min : protected Pointers {
|
||||
double fnorm_inf();
|
||||
double fnorm_max();
|
||||
|
||||
enum{TWO,MAX};
|
||||
enum{TWO,MAX,INF};
|
||||
|
||||
// methods for spin minimizers
|
||||
double max_torque();
|
||||
double total_torque();
|
||||
double inf_torque();
|
||||
double max_torque();
|
||||
|
||||
virtual void init_style() {}
|
||||
virtual void setup_style() = 0;
|
||||
@ -67,8 +68,7 @@ class Min : protected Pointers {
|
||||
int linestyle; // 0 = backtrack, 1 = quadratic, 2 = forcezero
|
||||
// 3 = spin_cubic, 4 = spin_none
|
||||
|
||||
int normstyle; // TWO or MAX flag for force norm evaluation
|
||||
// int normstyle; // 0 = Euclidean norm, 1 = inf. norm
|
||||
int normstyle; // TWO, MAX or INF flag for force norm evaluation
|
||||
|
||||
int nelist_global,nelist_atom; // # of PE,virial computes to check
|
||||
int nvlist_global,nvlist_atom;
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "min_cg.h"
|
||||
#include <mpi.h>
|
||||
#include <cmath>
|
||||
#include "error.h"
|
||||
#include "update.h"
|
||||
#include "output.h"
|
||||
#include "timer.h"
|
||||
@ -110,12 +111,15 @@ int MinCG::iterate(int maxiter)
|
||||
}
|
||||
|
||||
fmax = 0.0;
|
||||
if (normstyle == MAX) { // max force norm
|
||||
if (normstyle == MAX) { // max force norm
|
||||
fmax = fnorm_max();
|
||||
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;
|
||||
}
|
||||
} else error->all(FLERR,"Illegal min_modify command");
|
||||
|
||||
// update new search direction h from new f = -Grad(x) and old g
|
||||
// this is Polak-Ribieri formulation
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <cmath>
|
||||
#include "universe.h"
|
||||
#include "atom.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
#include "update.h"
|
||||
#include "output.h"
|
||||
@ -250,8 +251,10 @@ int MinFire::iterate(int maxiter)
|
||||
// sync across replicas if running multi-replica minimization
|
||||
|
||||
if (update->ftol > 0.0) {
|
||||
if (normstyle == MAX) fdotf = fnorm_inf(); // max force norm
|
||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
||||
if (normstyle == MAX) fdotf = fnorm_max(); // max force 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 (fdotf < update->ftol*update->ftol) return FTOL;
|
||||
} else {
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <cmath>
|
||||
#include "universe.h"
|
||||
#include "atom.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
#include "update.h"
|
||||
#include "output.h"
|
||||
@ -215,8 +216,10 @@ int MinQuickMin::iterate(int maxiter)
|
||||
// sync across replicas if running multi-replica minimization
|
||||
|
||||
if (update->ftol > 0.0) {
|
||||
if (normstyle == MAX) fdotfloc = fnorm_max(); // max force norm
|
||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
||||
if (normstyle == MAX) fdotfloc = fnorm_max(); // max force 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 (fdotf < update->ftol*update->ftol) return FTOL;
|
||||
} else {
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include "min_sd.h"
|
||||
#include <cmath>
|
||||
#include "error.h"
|
||||
#include "update.h"
|
||||
#include "output.h"
|
||||
#include "timer.h"
|
||||
@ -77,8 +78,10 @@ int MinSD::iterate(int maxiter)
|
||||
|
||||
// force tolerance criterion
|
||||
|
||||
if (normstyle == MAX) fdotf = fnorm_max(); // max force norm
|
||||
else fdotf = fnorm_sqr(); // Euclidean force 2-norm
|
||||
if (normstyle == MAX) fdotf = fnorm_max(); // max force 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;
|
||||
|
||||
// set new search direction h to f = -Grad(x)
|
||||
|
||||
Reference in New Issue
Block a user