예제 #1
0
 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);
 }
예제 #2
0
  // 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
  }