From f97280116a8e1c8920fd592d375e035bfac9fde9 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 30 Sep 2010 22:28:15 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@4915 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/min.cpp | 26 +++---------------------- src/min.h | 2 +- src/min_fire.cpp | 44 ++++++++++++++++++++++++++++++++++++++----- src/min_quickmin.cpp | 45 ++++++++++++++++++++++++++++++++++++++++---- src/minimize.cpp | 2 +- src/update.cpp | 1 + src/update.h | 1 + 7 files changed, 87 insertions(+), 34 deletions(-) diff --git a/src/min.cpp b/src/min.cpp index 32928f1876..2619cb979c 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -347,12 +347,9 @@ void Min::setup_minimal(int flag) /* ---------------------------------------------------------------------- perform minimization, calling iterate() for N steps - complete = 1 if caller wants to force N iterations (in every replica) - minimize command and PRD call with complete = 0 - NEB calls with complete = 1 ------------------------------------------------------------------------- */ -void Min::run(int n, int complete) +void Min::run(int n) { // minimizer iterations @@ -360,24 +357,7 @@ void Min::run(int n, int complete) stop_condition = iterate(n); stopstr = stopstrings(stop_condition); - // if early exit from iterate loop and complete flag set - // perform remaining dummy iterations - - if (stop_condition && complete) { - int ntimestep; - while (niter - iter_start < n) { - ntimestep = ++update->ntimestep; - niter++; - ecurrent = energy_force(0); - if (output->next == ntimestep) { - timer->stamp(); - output->write(ntimestep); - timer->stamp(TIME_OUTPUT); - } - } - } - - // if early exit from iterate loop and complete flag not set + // if early exit from iterate loop: // set update->nsteps to niter for Finish stats to print // set output->next values to this timestep // call energy_force() to insure vflag is set when forces computed @@ -385,7 +365,7 @@ void Min::run(int n, int complete) // add ntimestep to all computes that store invocation times // since are hardwiring call to thermo/dumps and computes may not be ready - if (stop_condition && !complete) { + if (stop_condition) { update->nsteps = niter; if (update->restrict_output == 0) { diff --git a/src/min.h b/src/min.h index 2ed698c2a8..c92535cc93 100644 --- a/src/min.h +++ b/src/min.h @@ -33,7 +33,7 @@ class Min : protected Pointers { void init(); void setup(); void setup_minimal(int); - void run(int,int); + void run(int); void cleanup(); int request(class Pair *, int, double); double memory_usage() {return 0.0;} diff --git a/src/min_fire.cpp b/src/min_fire.cpp index 5b54be5ec0..67e1dd188b 100644 --- a/src/min_fire.cpp +++ b/src/min_fire.cpp @@ -13,6 +13,7 @@ #include "math.h" #include "min_fire.h" +#include "universe.h" #include "atom.h" #include "force.h" #include "update.h" @@ -22,6 +23,10 @@ using namespace LAMMPS_NS; +// EPS_ENERGY = minimum normalization for energy tolerance + +#define EPS_ENERGY 1.0e-8 + // same as in other min classes enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; @@ -76,7 +81,7 @@ void MinFire::reset_vectors() int MinFire::iterate(int maxiter) { - int ntimestep; + int ntimestep,flag,flagall; double vmax,vdotf,vdotfall,vdotv,vdotvall,fdotf,fdotfall; double scale1,scale2; double dtvone,dtv,dtfm; @@ -173,11 +178,40 @@ int MinFire::iterate(int maxiter) eprevious = ecurrent; ecurrent = energy_force(0); neval++; - - // force tolerance criterion - //fdotf = fnorm_sqr(); - //if (fdotf < update->ftol*update->ftol) return FTOL; + // energy tolerance criterion + // sync across replicas if running multi-replica minimization + + if (update->etol > 0.0) { + if (update->multireplica == 0) { + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + return ETOL; + } else { + printf("EEE %g %g\n",ecurrent,eprevious); + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return ETOL; + } + } + + // force tolerance criterion + // sync across replicas if running multi-replica minimization + + if (update->ftol > 0.0) { + fdotf = fnorm_sqr(); + if (update->multireplica == 0) { + if (fdotf < update->ftol*update->ftol) return FTOL; + } else { + if (fdotf < update->ftol*update->ftol) flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return FTOL; + } + } // output for thermo, dump, restart files diff --git a/src/min_quickmin.cpp b/src/min_quickmin.cpp index ae13f77a3c..060dabe5eb 100644 --- a/src/min_quickmin.cpp +++ b/src/min_quickmin.cpp @@ -11,8 +11,10 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "mpi.h" #include "math.h" #include "min_quickmin.h" +#include "universe.h" #include "atom.h" #include "force.h" #include "update.h" @@ -22,6 +24,10 @@ using namespace LAMMPS_NS; +// EPS_ENERGY = minimum normalization for energy tolerance + +#define EPS_ENERGY 1.0e-8 + // same as in other min classes enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD}; @@ -65,11 +71,13 @@ void MinQuickMin::reset_vectors() if (nvec) fvec = atom->f[0]; } +/* ---------------------------------------------------------------------- + minimization via QuickMin damped dynamics /* ---------------------------------------------------------------------- */ int MinQuickMin::iterate(int maxiter) { - int ntimestep; + int ntimestep,flag,flagall; double vmax,vdotf,vdotfall,fdotf,fdotfall,scale; double dtvone,dtv,dtfm; @@ -141,10 +149,39 @@ int MinQuickMin::iterate(int maxiter) ecurrent = energy_force(0); neval++; - // force tolerance criterion + // energy tolerance criterion + // sync across replicas if running multi-replica minimization - //fdotf = fnorm_sqr(); - //if (fdotf < update->ftol*update->ftol) return FTOL; + if (update->etol > 0.0) { + if (update->multireplica == 0) { + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + return ETOL; + } else { + printf("EEE %g %g\n",ecurrent,eprevious); + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return ETOL; + } + } + + // force tolerance criterion + // sync across replicas if running multi-replica minimization + + if (update->ftol > 0.0) { + fdotf = fnorm_sqr(); + if (update->multireplica == 0) { + if (fdotf < update->ftol*update->ftol) return FTOL; + } else { + if (fdotf < update->ftol*update->ftol) flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return FTOL; + } + } // output for thermo, dump, restart files diff --git a/src/minimize.cpp b/src/minimize.cpp index ccc1b31a03..94d748f9dd 100644 --- a/src/minimize.cpp +++ b/src/minimize.cpp @@ -51,7 +51,7 @@ void Minimize::command(int narg, char **arg) update->minimize->setup(); timer->barrier_start(TIME_LOOP); - update->minimize->run(update->nsteps,0); + update->minimize->run(update->nsteps); timer->barrier_stop(TIME_LOOP); update->minimize->cleanup(); diff --git a/src/update.cpp b/src/update.cpp index f1a9fd2cdb..82b9cf8864 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -43,6 +43,7 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp) firststep = laststep = 0; beginstep = endstep = 0; setupflag = 0; + multireplica = 0; restrict_output = 0; diff --git a/src/update.h b/src/update.h index b964ec69ef..43b7eb0ea8 100644 --- a/src/update.h +++ b/src/update.h @@ -31,6 +31,7 @@ class Update : protected Pointers { int max_eval; // max force evaluations for minimizer int restrict_output; // 1 if output should not write dump/restart int setupflag; // set when setup() is computing forces + int multireplica; // 1 if min across replicas, else 0 int eflag_global,eflag_atom; // timestep global/peratom eng is tallied on int vflag_global,vflag_atom; // ditto for virial