public void steepestDescentInitialize(int stepMax, double criterion) { this.stepMax = stepMax; // 1000 // The criterion must be in the units of the calculation. // However, the user is setting this, so they will be in Minimizer units. // this.criterion = criterion / toUserUnits(1); // 1e-3 currentStep = 0; clearForces(); calc.setLoggingEnabled(true); calc.setLoggingEnabled(stepMax == 0 || Logger.isActiveLevel(Logger.LEVEL_DEBUGHIGH)); String s = name + " " + calc.getDebugHeader(-1) + "Jmol Minimization Version " + Viewer.getJmolVersion() + "\n"; calc.appendLogData(s); Logger.info(s); calc.getConstraintList(); if (calc.loggingEnabled) calc.appendLogData(calc.getAtomList("S T E E P E S T D E S C E N T")); dE = 0; calc.setPreliminary(stepMax > 0); e0 = energyFull(false, false); s = TextFormat.sprintf( " Initial " + name + " E = %10.3f " + minimizer.units + " criterion = %8.6f max steps = " + stepMax, new Object[] {Float.valueOf(toUserUnits(e0)), Float.valueOf(toUserUnits(criterion))}); minimizer.report(s, false); calc.appendLogData(s); }
// Vector3d dir = new Vector3d(); public boolean steepestDescentTakeNSteps(int n) { if (stepMax == 0) return false; boolean isPreliminary = true; for (int iStep = 1; iStep <= n; iStep++) { currentStep++; calc.setSilent(true); for (int i = 0; i < minAtomCount; i++) if (bsFixed == null || !bsFixed.get(i)) setForcesUsingNumericalDerivative(minAtoms[i], ENERGY); linearSearch(); calc.setSilent(false); if (calc.loggingEnabled) calc.appendLogData(calc.getAtomList("S T E P " + currentStep)); double e1 = energyFull(false, false); dE = e1 - e0; boolean done = Util.isNear(e1, e0, criterion); if (done || currentStep % 10 == 0 || stepMax <= currentStep) { String s = TextFormat.sprintf( name + " Step %-4d E = %10.6f dE = %8.6f ", new Object[] { new float[] {(float) e1, (float) (dE), (float) criterion}, Integer.valueOf(currentStep) }); minimizer.report(s, false); calc.appendLogData(s); } e0 = e1; if (done || stepMax <= currentStep) { if (calc.loggingEnabled) calc.appendLogData(calc.getAtomList("F I N A L G E O M E T R Y")); if (done) { String s = TextFormat.formatString( "\n " + name + " STEEPEST DESCENT HAS CONVERGED: E = %8.5f " + minimizer.units + " after " + currentStep + " steps", "f", toUserUnits(e1)); calc.appendLogData(s); minimizer.report(s, true); Logger.info(s); } return false; } // System.out.println(isPreliminary + " " + getNormalizedDE() + " " + currentStep); if (isPreliminary && getNormalizedDE() >= 2) { // looking back at this after some time, I don't exactly see why I wanted // this to stay in preliminary mode unless |DE| >= 2 * crit. // It's hard to ever have |DE| NOT >= 2 * crit -- that would be very close to the criterion. // And when that IS the case, why would you want to STAY in preliminary mode? Hmm. calc.setPreliminary(isPreliminary = false); e0 = energyFull(false, false); } } return true; // continue }