Commit JT 092419

- added inf norm option
This commit is contained in:
julient31
2019-09-24 13:58:56 -06:00
parent a0f0c23578
commit d9306a5865
12 changed files with 94 additions and 20 deletions

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
View 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}

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)
------------------------------------------------------------------------- */

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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)