001: import JSci.maths.*;
002: import JSci.maths.matrices.DoubleTridiagonalMatrix;
003: import JSci.io.*;
004: import java.io.*;
005:
006: /**
007: * Phonons in a Quasicrystal
008: * @author Mark Hale
009: */
010: public final class Quasicrystal {
011: private int N;
012: private double mass_m, mass_M;
013: private double eigenvalue[];
014:
015: /**
016: * Instantiate class.
017: */
018: public static void main(String arg[]) {
019: if (arg.length == 3) {
020: int n = Integer.valueOf(arg[0]).intValue();
021: double m1 = Double.valueOf(arg[1]).doubleValue();
022: double m2 = Double.valueOf(arg[2]).doubleValue();
023: new Quasicrystal(n, m1, m2);
024: } else {
025: System.out
026: .println("Need to specify command line arguments:");
027: System.out
028: .println("<length of chain> <mass of atom 1> <mass of atom 2>");
029: }
030: }
031:
032: /**
033: * Constructor.
034: * @param n order of matrix
035: * @param m1 mass
036: * @param m2 mass
037: */
038: public Quasicrystal(int n, double m1, double m2) {
039: N = n;
040: mass_M = m1;
041: mass_m = m2;
042: compute();
043: saveResults();
044: }
045:
046: /**
047: * Calculate the vibrational frequencies.
048: */
049: private void compute() {
050: DoubleTridiagonalMatrix matrix = new DoubleTridiagonalMatrix(N);
051: eigenvalue = new double[N];
052: // Generate sequence of masses m and M
053: double mass[] = fibonacci();
054: // Create matrix
055: matrix.setElement(0, 0, 2.0 / mass[0]);
056: matrix.setElement(0, 1, -1.0 / Math.sqrt(mass[0] * mass[1]));
057: for (int i = 1; i < N - 1; i++) {
058: matrix.setElement(i, i - 1, -1.0
059: / Math.sqrt(mass[i] * mass[i - 1]));
060: matrix.setElement(i, i, 2.0 / mass[i]);
061: matrix.setElement(i, i + 1, -1.0
062: / Math.sqrt(mass[i] * mass[i + 1]));
063: }
064: matrix.setElement(N - 1, N - 1, 2.0 / mass[N - 1]);
065: matrix.setElement(N - 1, N - 2, -1.0
066: / Math.sqrt(mass[N - 1] * mass[N - 2]));
067: // Solve eigenproblem
068: try {
069: eigenvalue = LinearMath.eigenvalueSolveSymmetric(matrix);
070: } catch (MaximumIterationsExceededException e) {
071: System.out.println("Too many iterations.");
072: }
073: }
074:
075: /**
076: * Creates a Fibonacci sequence.
077: * @return an array containing the sequence
078: */
079: private double[] fibonacci() {
080: double array[];
081: java.util.Vector seq = new java.util.Vector(N);
082: Double adult = new Double(mass_M);
083: Double child = new Double(mass_m);
084: seq.addElement(child);
085: while (seq.size() < N) {
086: for (int i = 0; i < seq.size(); i++) {
087: if (seq.elementAt(i).equals(adult))
088: seq.insertElementAt(child, ++i);
089: else if (seq.elementAt(i).equals(child))
090: seq.setElementAt(adult, i);
091: }
092: }
093: array = new double[N];
094: for (int i = 0; i < array.length; i++) {
095: array[i] = ((Double) seq.elementAt(i)).doubleValue();
096: }
097: return array;
098: }
099:
100: /**
101: * Log results to disk.
102: */
103: private void saveResults() {
104: File file = new File("spectrum.txt");
105: char filebuf[] = null;
106: double data[][] = new double[1][N + 1];
107: data[0][0] = mass_m / mass_M;
108: for (int i = 1; i < data[0].length; i++) {
109: data[0][i] = Math.sqrt(eigenvalue[i - 1]);
110: }
111: // Read in existing data
112: try {
113: FileReader in = new FileReader(file);
114: filebuf = new char[(int) file.length()];
115: in.read(filebuf);
116: in.close();
117: } catch (Exception e) {
118: System.out.println("No previous data - new file.");
119: }
120: // Save all to file
121: try {
122: TextWriter out = new TextWriter(file, ',');
123: if (filebuf != null)
124: out.write(filebuf);
125: out.write(data);
126: out.close();
127: } catch (Exception e) {
128: System.out.println("Failed to save.");
129: }
130: }
131: }
|