Revision: 5206
Author:   hansonr
Date:     2006-06-06 15:57:31 -0700 (Tue, 06 Jun 2006)
ViewCVS:  http://svn.sourceforge.net/jmol/?rev=5206&view=rev

Log Message:
-----------
bob200603 real, calculated orbitals!!!! :)

Modified Paths:
--------------
    branches/bob200603/Jmol/src/org/jmol/viewer/Eval.java
    branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java
Modified: branches/bob200603/Jmol/src/org/jmol/viewer/Eval.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/Eval.java       2006-06-06 
19:36:48 UTC (rev 5205)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/Eval.java       2006-06-06 
22:57:31 UTC (rev 5206)
@@ -3980,6 +3980,8 @@
     int fileIndexPt = 0;
     int signPt = 0;
     int contourPt = 0;
+    int orbitalPt = 0;
+    float[] nlmZR = new float[5];
     viewer.loadShape(JmolConstants.SHAPE_ISOSURFACE);
     viewer.setShapeProperty(JmolConstants.SHAPE_ISOSURFACE, "init", null);
     boolean colorSeen = false;
@@ -4019,6 +4021,11 @@
           colorRangeStage = 1;
           break;
         } else if (str.equalsIgnoreCase("phase")) {
+          if (orbitalPt != 0) {
+            propertyName = "phase";
+            propertyValue = "_orb";
+            break;
+          }
           colorByPhase = true;
           break;
         } else if (str.equalsIgnoreCase("fileIndex")) {
@@ -4039,6 +4046,9 @@
         } else if (str.equalsIgnoreCase("gridPoints")) {
           propertyName = "gridPoints";
           break;
+        } else if (str.equalsIgnoreCase("orbital")) {
+          orbitalPt = i + nlmZR.length;
+          break;
         } else if (str.equalsIgnoreCase("contour")) {
           propertyName = "contour";
           contourPt = i + 1;
@@ -4073,13 +4083,26 @@
         }
         break;
       case Token.decimal:
-        if (colorRangeStage == 0) {
+        if (colorRangeStage == 0 && orbitalPt == 0) {
           propertyName = "cutoff";
           propertyValue = token.value;
           break;
         }
       // fall into
       case Token.integer:
+        if (orbitalPt > 0 && i <= orbitalPt) {
+          int ipt = nlmZR.length - (orbitalPt - i) - 1;
+          if (ipt < 3 && token.tok != Token.integer)
+            integerExpected();
+          // n l m Znuc ptsPerAngstrom 
+          nlmZR[ipt] = floatParameter(i);
+          if (i != orbitalPt)
+            break;
+          propertyName = "orbital";
+          propertyValue = nlmZR;
+          orbitalPt = Integer.MIN_VALUE;
+          break;
+        }
         if (i == contourPt) {
           if (token.tok != Token.integer)
             integerExpected();

Modified: branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-06-06 
19:36:48 UTC (rev 5205)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-06-06 
22:57:31 UTC (rev 5206)
@@ -101,6 +101,7 @@
   final static float defaultMappedDataMin = 0f;
   final static float defaultMappedDataMax = 1.0f;
   final static float defaultCutoff = 0.02f;
+  final static float defaultOrbitalCutoff = 0.02f;
   final static int defaultContourCount = 10;
   final static String colorScheme = "roygb";
   final static int nContourMax = 100;
@@ -113,6 +114,7 @@
   int colorPtr;
   boolean colorByPhase;
   int colorPhase;
+  boolean isOrbital;
 
   int edgeFractionBase;
   int edgeFractionRange;
@@ -154,7 +156,6 @@
   int nContours;
   int thisContour;
   boolean dotsOnly;
-  boolean loadAll;
 
   BufferedReader br;
 
@@ -181,7 +182,7 @@
       colorNeg = defaultColorNegative;
       colorPos = defaultColorPositive;
       colorByPhase = false;
-      loadAll = false;
+      isOrbital = false;
       cutoff = Float.MAX_VALUE;
       super.setProperty("meshID", null, null);
       return;
@@ -267,13 +268,32 @@
         return;
       }
       applyColorScale();
-      currentMesh.visible = true;
+      if (currentMesh != null)
+        currentMesh.visible = true;
       return;
     }
 
+    if ("orbital" == propertyName) {
+      isOrbital = true;
+      float[] nlmZR = (float[]) value;
+      psi_n = (int) nlmZR[0];
+      psi_l = (int) nlmZR[1];
+      psi_m = (int) nlmZR[2];
+      psi_Znuc = nlmZR[3];
+      psi_ptsPerAngstrom = nlmZR[4];
+      if (psi_ptsPerAngstrom <= 0 || psi_Znuc <= 0 || Math.abs(psi_m) > psi_l
+          || psi_l >= psi_n) {
+        System.out.println("invalid n, l, m, Znuc, or ptsPerAngstrom : "
+            + psi_n + " " + psi_l + " " + psi_m + " " + psi_Znuc + " "
+            + psi_ptsPerAngstrom);
+        return;
+      }
+      propertyName = "bufferedReader";
+    }
     if ("bufferedReader" == propertyName) {
+      if (!isOrbital)
+        br = (BufferedReader) value;
       System.out.println("loading voxel data...");
-      br = (BufferedReader) value;
       checkFlags();
       createIsosurface();
       initializeMesh(force2SidedTriangles);
@@ -405,7 +425,7 @@
       currentMesh.hasGridPoints = true;
     }
     if (cutoff == Float.MAX_VALUE)
-      cutoff = defaultCutoff;
+      cutoff = (isOrbital ? defaultOrbitalCutoff : defaultCutoff);
     currentMesh.jvxlSurfaceData = "";
     currentMesh.jvxlEdgeData = "";
     currentMesh.jvxlColorData = "";
@@ -473,11 +493,15 @@
 
   int readVolumetricHeader() {
     try {
-      readTitleLines();
-      readAtomCountAndOrigin();
-      for (int i = 0; i < 3; ++i) {
-        readVoxelVector(i);
-        System.out.println("cube axes vector:" + volumetricVectors[i]);
+      if (isOrbital) {
+        setupOrbital();
+      } else {
+        readTitleLines();
+        readAtomCountAndOrigin();
+        for (int i = 0; i < 3; ++i) {
+          readVoxelVector(i);
+          System.out.println("cube axes vector:" + volumetricVectors[i]);
+        }
       }
       setupMatrix(volumetricMatrix, volumetricVectors);
       readAtoms();
@@ -662,7 +686,9 @@
            *  
            */
 
-          if (isMapData || thePlane == null)
+          if (isOrbital)
+            voxelValue = getPsi2(x, y, z);
+          else if (isMapData || thePlane == null)
             voxelValue = getNextVoxelValue();
           else
             voxelValue = calcVoxelPlaneDistance(x, y, z);
@@ -1073,7 +1099,7 @@
   }
 
   final static String[] colorPhases = { "x", "y", "z", "xy", "yz", "xz",
-      "x2-y2", "z2" };
+      "x2-y2", "z2", "_orb" };
 
   float getPhase(Point3f pt) {
     switch (colorPhase) {
@@ -1092,7 +1118,9 @@
     case 6:
       return (pt.x * pt.x - pt.y * pt.y > 0 ? 1 : -1);
     case 7:
-      return (pt.z * pt.z - pt.x * pt.x - pt.y * pt.y > 0 ? 1 : -1);
+      return (pt.z * pt.z * 2f - pt.x * pt.x - pt.y * pt.y > 0 ? 1 : -1);
+    case 8:
+      return (hydrogenAtomPsiAt(pt, psi_n, psi_l, psi_m) > 0 ? 1 : -1);
     }
     return 1;
   }
@@ -1428,7 +1456,7 @@
       compressedData += jvxlCompressString(mesh.jvxlEdgeData
           + mesh.jvxlColorData);
       int nColor = (mesh.jvxlColorData.length() - 1);
-      if (isJvxlColorPrecision  && nColor != -1)
+      if (isJvxlColorPrecision && nColor != -1)
         nColor = -nColor;
       data += mesh.jvxlSurfaceData.length() + " "
           + (mesh.jvxlEdgeData.length() - 1) + " " + nColor;
@@ -1444,8 +1472,8 @@
       data += " CONTOUR PLANE " + mesh.jvxlPlane;
     if (!isJvxl)
       data += " approximate compressionRatio="
-          + (int) (((float)mesh.nBytes + mesh.jvxlFileHeader.length()) / 
-              (data.length() + compressedData.length())) + ":1";
+          + (int) (((float) mesh.nBytes + mesh.jvxlFileHeader.length()) / (data
+              .length() + compressedData.length())) + ":1";
     data += "\n" + compressedData;
     if (msg != null)
       data += "#-------end of jvxl file data-------\n";
@@ -1602,7 +1630,8 @@
             continue;
           }
           ++surfaceCount;
-          processOneVoxel(insideMask, cutoff, voxelPointIndexes, x, y, z, 
contouring);
+          processOneVoxel(insideMask, cutoff, voxelPointIndexes, x, y, z,
+              contouring);
         }
       }
     }
@@ -2758,4 +2787,141 @@
     vector.y /= planarVectorLengths[1];
   }
 
+  /////// orbitals ///////
+
+  //just for small factorials
+  static float factorial(int n) {
+    if (n == 0)
+      return 1;
+    return n * factorial(n - 1);
+  }
+
+  static float[] fact = new float[20];
+  static double[] rfactor = new double[10];
+  static double[] pfactor = new double[10];
+  int lastFactorial = -1;
+
+  void calcFactors(int n, int el, int m) {
+    int abm = Math.abs(m);
+    if (lastFactorial < n + el) {
+      for (int i = lastFactorial + 1; i <= n + el; i++)
+        fact[i] = factorial(i);
+      lastFactorial = n + el;
+    }
+    double Nnl = Math.pow(2 * psi_Znuc / n / A0, 1.5)
+        * Math.sqrt(fact[n - el - 1] / 2 / n / Math.pow(fact[n + el], 3));
+    double Lnl = fact[n + el] * fact[n + el];
+    double Plm = Math.pow(2, -el) * fact[el] * fact[el + abm]
+        * Math.sqrt((2 * el + 1) * fact[el - abm] / 2 / fact[el + abm]);
+
+    for (int p = 0; p <= n - el - 1; p++)
+      rfactor[p] = Nnl * Lnl / fact[p] / fact[n - el - p - 1]
+          / fact[2 * el + p + 1];
+    for (int p = abm; p <= el; p++)
+      pfactor[p] = Math.pow(-1, el - p) * Plm / fact[p] / fact[el + abm - p]
+          / fact[el - p] / fact[p - abm];
+  }
+
+  Point3f psiOrigin = new Point3f(0, 0, 0);
+  final static double A0 = 0.52918f; //x10^-10 meters
+  final static double ROOT2 = 1.414214;
+
+  float getPsi2(int x, int y, int z) {
+    Point3f ptPsi = voxelPtToXYZ(x, y, z);
+    float value = (float) hydrogenAtomPsiAt(ptPsi, psi_n, psi_l, psi_m);
+    return value * value;
+  }
+
+  double hydrogenAtomPsiAt(Point3f pt, int n, int el, int m) {
+    // ref: http://www.stolaf.edu/people/hansonr/imt/concept/schroed.pdf
+    int abm = Math.abs(m);
+    float x = pt.x - psiOrigin.x;
+    float y = pt.y - psiOrigin.y;
+    float z = pt.z - psiOrigin.z;
+    double x2y2 = x * x + y * y;
+    double r2 = x2y2 + z * z;
+    double r = Math.sqrt(r2);
+    double rho = 2d * psi_Znuc * r / n / A0;
+    double ph, th, cth, sth;
+    double theta_lm = 0;
+    double phi_m = 0;
+    double sum = 0;
+    for (int p = 0; p <= n - el - 1; p++)
+      sum += Math.pow(-rho, p) * rfactor[p];
+    double rnl = Math.exp(-rho / 2) * Math.pow(rho, el) * sum;
+    ph = Math.atan2(y, x);
+    th = Math.atan2(Math.sqrt(x2y2), z);
+    cth = Math.cos(th);
+    sth = Math.sin(th);
+    sum = 0;
+    for (int p = abm; p <= el; p++)
+      sum += Math.pow(1 + cth, p - abm) * Math.pow(1 - cth, el - p)
+          * pfactor[p];
+    theta_lm = Math.abs(Math.pow(sth, abm)) * sum;
+    if (m == 0)
+      phi_m = 1;
+    else if (m > 0)
+      phi_m = Math.cos(m * ph) * ROOT2;
+    else
+      phi_m = Math.sin(-m * ph) * ROOT2;
+    if (Math.abs(phi_m) < 0.0000000001)
+      phi_m = 0;
+    return rnl * theta_lm * phi_m;
+  }
+
+  int psi_n = 2;
+  int psi_l = 1;
+  int psi_m = 1;
+  float psi_ptsPerAngstrom = 5f;
+  float psi_radiusAngstroms;
+  float psi_Znuc = 1; // hydrogen
+
+  float autoScaleOrbital() {
+    float w = (psi_n * (psi_n + 3) - 5f) / psi_Znuc;
+    if (w < 1)
+      w = 1;
+    if (psi_n < 3)
+      w += 1;
+    return w;
+  }
+
+  int psi_gridMax = 61;
+
+  void setupOrbital() {
+    psi_radiusAngstroms = autoScaleOrbital();
+    int nGrid = (int) (psi_radiusAngstroms * psi_ptsPerAngstrom) * 2 + 1;
+    if (nGrid > psi_gridMax) {
+      nGrid = psi_gridMax;
+      psi_ptsPerAngstrom = ((nGrid - 1) / 2) / psi_radiusAngstroms;
+    }
+    jvxlFileHeader = "orbital psi squared\nn=" + psi_n + ", l=" + psi_l
+        + ", m=" + psi_m + " Znuc=" + psi_Znuc + " res=" + psi_ptsPerAngstrom
+        + " rad=" + psi_radiusAngstroms + "\n";
+    voxelCounts[0] = voxelCounts[1] = voxelCounts[2] = nGrid;
+    float dx = 1f / psi_ptsPerAngstrom;
+    volumetricVectors[0].set(dx, 0, 0);
+    volumetricVectors[1].set(0, dx, 0);
+    volumetricVectors[2].set(0, 0, dx);
+
+    volumetricVectorLengths[0] = volumetricVectorLengths[1] = 
volumetricVectorLengths[2] = dx;
+    unitVolumetricVectors[0].set(1, 0, 0);
+    unitVolumetricVectors[1].set(0, 1, 0);
+    unitVolumetricVectors[2].set(0, 0, 1);
+
+    float origin = dx * (1 - nGrid) / 2;
+
+    volumetricOrigin.set(origin, origin, origin);
+
+    jvxlFileHeader += "-1 " + (origin / ANGSTROMS_PER_BOHR) + " "
+        + (origin / ANGSTROMS_PER_BOHR) + " " + (origin / ANGSTROMS_PER_BOHR)
+        + "\n";
+    for (int i = 0; i < 3; i++)
+      jvxlFileHeader += nGrid + " "
+          + (volumetricVectors[i].x / ANGSTROMS_PER_BOHR) + " "
+          + (volumetricVectors[i].y / ANGSTROMS_PER_BOHR) + " "
+          + (volumetricVectors[i].z / ANGSTROMS_PER_BOHR) + "\n";
+    atomCount = 0;
+    negativeAtomCount = false;
+    calcFactors(psi_n, psi_l, psi_m);
+  }
 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Jmol-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to