String getDebugFooter(int iType, double energy) {
   String s = "";
   switch (iType) {
     case CALC_DISTANCE:
       s = "BOND STRETCHING";
       break;
     case CALC_ANGLE:
       s = "ANGLE BENDING";
       break;
     case CALC_TORSION:
       s = "TORSIONAL";
       break;
     case CALC_OOP:
       s = "OUT-OF-PLANE BENDING";
       break;
     case CALC_VDW:
       s = "VAN DER WAALS";
       break;
     case CALC_ES:
       s = "ELECTROSTATIC ENERGY";
       break;
   }
   return TextFormat.sprintf(
       "\n     TOTAL %s ENERGY = %8.3f %s\n",
       new String[] {s, getUnit()}, new float[] {(float) energy});
 }
예제 #2
0
  /*
    //
    //          f(x + 2delta) - 2f(x + delta) + f(x)
    // f''(x) = ------------------------------------
    //                        (delta)^2
    //
    void getNumericalSecondDerivative(MinAtom atom, int terms, Vector3d dir) {
      double delta = 1.0e-5;
      double e0 = getEnergy(terms, false);
      double dx = getDx2(atom, terms, 0, e0, delta);
      double dy = getDx2(atom, terms, 1, e0, delta);
      double dz = getDx2(atom, terms, 2, e0, delta);
      dir.set(dx, dy, dz);
    }

    private double getDx2(MinAtom atom, int terms, int i,
                                       double e0, double delta) {
      // calculate f(1)
      atom.coord[i] += delta;
      double e1 = getEnergy(terms, false);
      // calculate f(2)
      atom.coord[i] += delta;
      double e2 = getEnergy(terms, false);
      atom.coord[i] -= 2 * delta;
      return (e2 - 2 * e1 + e0) / (delta * delta);
    }

  */
  public double energyFull(boolean gradients, boolean isSilent) {
    double energy;

    if (gradients) clearForces();

    energy =
        energyBond(gradients)
            + energyAngle(gradients)
            + energyTorsion(gradients)
            + energyStretchBend(gradients)
            + energyOOP(gradients)
            + energyVDW(gradients)
            + energyES(gradients);

    if (!isSilent && calc.loggingEnabled)
      calc.appendLogData(
          TextFormat.sprintf(
              "\nTOTAL %s ENERGY = %8.3f %s/mol\n",
              new Object[] {name, Float.valueOf(toUserUnits(energy)), minimizer.units}));
    return energy;
  }
 String getAtomList(String title) {
   String trailer =
       "----------------------------------------"
           + "-------------------------------------------------------\n";
   StringBuffer sb = new StringBuffer();
   sb.append(
       "\n"
           + title
           + "\n\n"
           + " ATOM    X        Y        Z    TYPE     GRADX    GRADY    GRADZ  "
           + "---------BONDED ATOMS--------\n"
           + trailer);
   for (int i = 0; i < atomCount; i++) {
     MinAtom atom = atoms[i];
     int[] others = atom.getBondedAtomIndexes();
     int[] iVal = new int[others.length + 1];
     iVal[0] = atom.atom.getAtomNumber();
     String s = "   ";
     for (int j = 0; j < others.length; j++) {
       s += " %3d";
       iVal[j + 1] = atoms[others[j]].atom.getAtomNumber();
     }
     sb.append(
         TextFormat.sprintf(
             "%3d %8.3f %8.3f %8.3f  %-5s %8.3f %8.3f %8.3f" + s + "\n",
             new String[] {atom.type},
             new float[] {
               (float) atom.coord[0],
               (float) atom.coord[1],
               (float) atom.coord[2],
               (float) atom.force[0],
               (float) atom.force[1],
               (float) atom.force[2],
             },
             iVal));
   }
   sb.append(trailer + "\n\n");
   return sb.toString();
 }
예제 #4
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);
 }
예제 #5
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
  }
 String getDebugLine(int iType, Calculation c) {
   switch (iType) {
     case CALC_DISTANCE:
       return TextFormat.sprintf(
           "%3d %3d  %-5s %-5s  %4.2f%8.3f   %8.3f     %8.3f   %8.3f   %8.3f",
           new String[] {atoms[c.ia].type, atoms[c.ib].type},
           new float[] {
             (float) c.dData[2] /*rab*/,
             (float) c.rab,
             (float) c.dData[0],
             (float) c.dData[1],
             (float) c.delta,
             (float) c.energy
           },
           new int[] {atoms[c.ia].atom.getAtomNumber(), atoms[c.ib].atom.getAtomNumber()});
     case CALC_ANGLE:
       return TextFormat.sprintf(
           "%3d %3d %3d  %-5s %-5s %-5s  %8.3f  %8.3f     %8.3f   %8.3f",
           new String[] {atoms[c.ia].type, atoms[c.ib].type, atoms[c.ic].type},
           new float[] {
             (float) (c.theta * RAD_TO_DEG),
             (float) c.dData[4] /*THETA0*/,
             (float) c.dData[0] /*Kijk*/,
             (float) c.energy
           },
           new int[] {
             atoms[c.ia].atom.getAtomNumber(),
             atoms[c.ib].atom.getAtomNumber(),
             atoms[c.ic].atom.getAtomNumber()
           });
     case CALC_TORSION:
       return TextFormat.sprintf(
           "%3d %3d %3d %3d  %-5s %-5s %-5s %-5s  %8.3f     %8.3f     %8.3f",
           new String[] {atoms[c.ia].type, atoms[c.ib].type, atoms[c.ic].type, atoms[c.id].type},
           new float[] {
             (float) c.dData[0] /*V*/, (float) (c.theta * RAD_TO_DEG), (float) c.energy
           },
           new int[] {
             atoms[c.ia].atom.getAtomNumber(),
             atoms[c.ib].atom.getAtomNumber(),
             atoms[c.ic].atom.getAtomNumber(),
             atoms[c.id].atom.getAtomNumber()
           });
     case CALC_OOP:
       return TextFormat.sprintf(
           "" + "%3d %3d %3d %3d  %-5s %-5s %-5s %-5s  %8.3f   %8.3f     %8.3f",
           new String[] {atoms[c.ia].type, atoms[c.ib].type, atoms[c.ic].type, atoms[c.id].type},
           new float[] {
             (float) (c.theta * RAD_TO_DEG), (float) c.dData[0] /*koop*/, (float) c.energy
           },
           new int[] {
             atoms[c.ia].atom.getAtomNumber(),
             atoms[c.ib].atom.getAtomNumber(),
             atoms[c.ic].atom.getAtomNumber(),
             atoms[c.id].atom.getAtomNumber()
           });
     case CALC_VDW:
       return TextFormat.sprintf(
           "%3d %3d  %-5s %-5s %6.3f  %8.3f  %8.3f",
           new String[] {atoms[c.iData[0]].type, atoms[c.iData[1]].type},
           new float[] {(float) c.rab, (float) c.dData[0] /*kab*/, (float) c.energy},
           new int[] {atoms[c.ia].atom.getAtomNumber(), atoms[c.ib].atom.getAtomNumber()});
     case CALC_ES:
       return TextFormat.sprintf(
           "%3d %3d  %-5s %-5s %6.3f  %8.3f  %8.3f",
           new String[] {atoms[c.iData[0]].type, atoms[c.iData[1]].type},
           new float[] {(float) c.rab, (float) c.dData[0] /*qq*/, (float) c.energy},
           new int[] {atoms[c.ia].atom.getAtomNumber(), atoms[c.ib].atom.getAtomNumber()});
   }
   return "";
 }