Skip to content

Commit

Permalink
Merge pull request #19 from IntegratedQuantum/IntegratedQuantum-patch-2
Browse files Browse the repository at this point in the history
Add schrödinger to the app.
  • Loading branch information
IntegratedQuantum authored Mar 16, 2019
2 parents fb8aa55 + 3530748 commit b78aee9
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 3 deletions.
2 changes: 2 additions & 0 deletions assets/3/1D Symmetric Potential .txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[t]You want to enter your own function for the potential? Modify the sourcecode![\]
[d]3[\]
4 changes: 2 additions & 2 deletions java/quantum/integratedquantum/app/MenuScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ class MenuScreen extends Screen implements ActionListener {
{"Introduction", "Black Body Radiation", "Interference", "Wave Function", "Superposition", "Wave Particle Dualism I", "Wave Particle Dualism II", "Tunnel Effect", "Uncertainty Principle", "Particles", "Light", "Pauli Exclusion", "Spin", "Vacuum Fluctuation", "Quantum Entanglement", "Interpretations"},
{"Notice", "Differentiation", "Integration", "Imaginary Numbers", "Complex Numbers", "Differential Equations", "Partial Differential Equations"},
{"Schrödinger Equation", "Basic Calculations I", "Quantum Well", "Quantum Well II", "Basic Calculations II", "Basic Calculations III", "Operators", "Superposition", "Wave Particle Dualism II", "Tunnel Effect", "Uncertainty Principle", "Electronvolt", "Pauli Exclusion", "Spin"},
{"Numerical Approach I"},
{"Numerical Approach I", "Numerical Solution I"},
{"Settings"},
};
subName = new String[][]{
{"", "", "", "", "", "Double Slit Experiment", "Photoelectric Effect", "", "", "", "", "", "", "", "", ""},
{"", "", "", "", "", "", ""},
{"", "constant Potential", "", "Finite Potential Well", "non-radial symmetric Potential", "radial symmetric Potential", "", "", "Photoelectric Effect", "", "", "", "", ""},
{"1D Symmetric Potential"},
{"1D Symmetric Potential", "1D Symmetric Potential "},
{" "},
};
String [] name2 = {"Principles of Quantum Physics", "Mathematical Foundation", "Quantum Principle Calculations", "Numerical Solution", "Extras"};
Expand Down
62 changes: 62 additions & 0 deletions java/quantum/integratedquantum/implementation/Complex.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package quantum.integratedquantum.implementation;

public class Complex {
public double r;
public double i;
public Complex(double r, double i) {
this.r = r;
this.i = i;
}
public Complex plus(Complex z) {
return new Complex(r+z.r, i+z.i);
}
public Complex minus(Complex z) {
return new Complex(r-z.r, i-z.i);
}
public Complex times(Complex z) {
return new Complex(r*z.r-i*z.i, r*z.i+i*z.r);
}
public Complex times(double x) {
return new Complex(r*x, i*x);
}
public Complex divide(Complex z) {
double r2 = 0;
double i2 = 0;
if(z.r != 0) {
r2 = r/z.r;
i2 = i/z.r;
}
if(z.i != 0) {
r2 += i/z.i;
i2 -= r/z.i;
}
return new Complex (r2, i2);
}
public Complex ePow() {
double a = Math.exp(r);
return new Complex(a*Math.cos(i), a*Math.sin(i));
}
public Complex negate() {
return new Complex(-r, -i);
}
public static Complex sqrt(double x) {
if (x < 0)
return new Complex(0, Math.sqrt(-x));
return new Complex(Math.sqrt(x), 0);
}
public double valueSquared() {
return r*r+i*i;
}
public String toString() {
String ret = "";
if(r != 0)
ret += r;
if(ret.length() > 0 && i > 0)
ret += "+";
if(i != 0)
ret += i+"i";
if(ret.length() == 0)
ret = "0";
return ret;
}
}
5 changes: 4 additions & 1 deletion java/quantum/integratedquantum/implementation/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import quantum.integratedquantum.implementation.functions.BlackBody;
import quantum.integratedquantum.implementation.functions.Differentiation;
import quantum.integratedquantum.implementation.functions.Schrödinger;
import quantum.integratedquantum.implementation.functions.Tunnel;

public class Function {
private static int[] heights = {700, 500, 300};
private static int[] heights = {700, 500, 300, 1000};
public static Component getFunction(int x, int y, Component parent, int n) {
switch(n) {
case 0:
Expand All @@ -14,6 +15,8 @@ public static Component getFunction(int x, int y, Component parent, int n) {
return new Differentiation(x, y);
case 2:
return new Tunnel(y);
case 3:
return new Schrödinger(y);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package quantum.integratedquantum.implementation.functions;

import android.graphics.Color;
import android.graphics.Paint;

import quantum.integratedquantum.ActionListener;
import quantum.integratedquantum.implementation.Button;
import quantum.integratedquantum.implementation.CheckBox;
import quantum.integratedquantum.implementation.Complex;
import quantum.integratedquantum.implementation.Component;
import quantum.integratedquantum.implementation.Graphics;
import quantum.integratedquantum.implementation.Label;

public class Schrödinger extends Component implements ActionListener {
private int y;
private int l;
private int minX;
private int maxX;
private int averageX;
private float minY;
private float maxY;
private float ΔY;
private float averageY;
private boolean sym;
private static int width = 460;
private static int height = 540;
private Paint p;
private float[] PsiSquared;
private float[] Psi;
private Complex[] A;
private Complex[] B;
private Complex[] k;
private float scaleX = (float)(width/2000.0);
private float scaleY = 1;
private double m = 9.10938188e-31;//kg //.0016678204759907602; //¿?
private double ħ = 1.0545716346179718e-34;//Js
private static double scale = 10e-12;
private CheckBox ch1, ch2, ch3;
private int energylevel = 1;
//double m = 510998.946131; //eV/c²
//static double ħ = 6.58211951440e-16; //eVs
static double e = 1.602176620898e-19; //C
private double E;
private static Complex one = new Complex(1, 0);


// Rounds a float to 3 digits.
private static float round(float in) {
in *= 1000;
in = (int)in;
in /= 1000;
return in;
}

// Calculates Ψ from the constants A, B and k.
private void schröd(int x) {
Complex exp = k[x].times(x*scale);
Psi[x] = (float)(A[x].times(exp.ePow()).plus(B[x].times(exp.negate().ePow()))).r;
}

// Calculates the constants A and B based on the previous constant.
private void A(int x) {
A[x] = A[x-1].times(k[x-1].minus(k[x]).times(x*scale).ePow()).times(one.plus(k[x-1].divide(k[x]))).plus(B[x-1].times(k[x-1].plus(k[x]).negate().times(x*scale).ePow()).times(one.minus(k[x-1].divide(k[x])))).divide(new Complex(2, 0));
}
private void B(int x) {
B[x] = (A[x-1].times(k[x-1].times(x*scale).ePow()).plus(B[x-1].times(k[x-1].negate().times(x*scale).ePow())).minus(A[x].times(k[x].times(x*scale).ePow()))).times(k[x].times(x*scale).ePow());
}

// Calculates k for the specific energy at a given point.
private void k(int x) {
k[x] = Complex.sqrt(-2*m*(E-V(x))).divide(new Complex (ħ, 0));
}

// Calculates the potential energy based on a given formula.
private static double V(double x) {
// x is in nm.
x *= scale;
return x*x/e/10000000000000000000.0;
//return Math.log(x)*x/1000000000000000000000000000000000000000000000000000000000000000000000000.0;
//return Math.log(x+1)/100000000000000000000000000000000000000000000000000000000000000000000.0;
/*x *= scale;
double V = 0.00000000000000000000000000000004;
for(int i = 0; i < 22; i++) {
V -= e*e/value(x-i*1000/21*scale+500*scale)/22;
}
if(V == Double.NaN || V == -1/0.0 || V < 0)
V = 0;
return V*6.2415091e18;*/
}

// Normalizes Ψ and initializes a few parameters that are needed to display the function.
private void norm() {
int i = 0;
for(; i < l; i++) {
if(Psi[i] != Psi[i])
Psi[i] = 0;
}
i--;
int x;
for(;; i--) {
if(Math.signum(Psi[i]-Psi[i-1]) == Math.signum(Psi[i-2]-Psi[i-1]) || (Psi[i] == Psi[i-1])) {
x = i-1;
break;
}
}
PsiSquared = new float[Psi.length];
float base = Psi[x]/Psi[x-1];
for(i = x+1; i < l; i++) {
Psi[i] = base*Psi[i-1];
}
float sum = 0;
for(i = 0; i < l; i++) {
sum += Psi[i]*Psi[i];
}
System.out.println(sum);
sum = 1/(float)Math.sqrt(sum);
float max = 0;
float min = 0;
for(i = 0; i < l; i++) {
Psi[i] = Psi[i]*sum;
if(Psi[i] <= min)
min = Psi[i];
if(Psi[i] >= max)
max = Psi[i];
PsiSquared[i] = Psi[i]*Psi[i];
}
minY = round(min);
maxY = round(max);
if(!sym) {
if(minY <= -maxY)
maxY = -minY;
else
minY = -maxY;
}
averageY = round(((minY+maxY)/2));
minX = -l;
maxX = l;
averageX = 0;
scaleY = round((height/(maxY-minY)));
ΔY = round(((maxY)*scaleY));
scaleX = (float)(width/(2.0*l));
}

// Finds the nth energy level in the given potential function.
private void rebuild(int n, int l) {
this.l = l;
Psi = new float[l];
A = new Complex[l];
B = new Complex[l];
k = new Complex[l];
sym = (n&1) == 1;
if(sym) {
A[0] = new Complex(1, 0);
B[0] = new Complex(1, 0);
}
else {
A[0] = new Complex(0, 1);
B[0] = new Complex(0, -1);
}
E = 1.0e-200;
double factor = 1000;
boolean changed = false;
l /= 20;
scale *= 20;
while(true) {
E *= factor;
k(0);
schröd(0);
for (int i = 1; i < l; i++) {
k(i);
A(i);
B(i);
schröd(i);
}
int nulls = sym ? 0:1;
for(int j = 1; j < l; j++) {
if(Psi[j]*Psi[j-1] < 0) {
nulls += 2;
}
}
if(!changed && factor < 1.1) {
l = this.l;
scale /= 20;
changed = true;
}
if(factor == 1)
break;
if(nulls-n > 0) {
E /= factor;
factor = 1+(factor-1)*0.11;
}
}
norm();
}

// Initializes the needed objects, and calculates the first function.
public Schrödinger(int y) {
this.y = y;
p = new Paint();
p.setColor(Color.YELLOW);
p.setTextSize(20);
p.setAntiAlias(true);
p.setTextAlign(Paint.Align.CENTER);
rebuild(1, 500);
ch1 = new CheckBox(40, y+height+40, 30, true); // Ψ
ch2 = new CheckBox(40, y+height+100, 30, false); //|Ψ|²
ch3 = new CheckBox(40, y+height+160, 30, false); // Hide labeling
add(ch1);
add(ch2);
add(ch3);
add(new Label(100, y+height+45, 30, "Show Ψ", Paint.Align.LEFT));
add(new Label(100, y+height+105, 30, "Show |Ψ|²", Paint.Align.LEFT));
add(new Label(100, y+height+165, 30, "Hide labeling", Paint.Align.LEFT));
add(new Label(40, y+height+230, 20, "Choose an energy level:", Paint.Align.LEFT));
add(new Button(310, y+height+190, 40, 30, "+", this));
add(new Button(310, y+height+220, 40, 30, "–", this));
add(new Button(30, y+height+280, 310, 60, "Reload wave function", this));
//add(ch3);
}

@Override
public void paint(Graphics g) {
g.fillRect(40+width/2, y, 1, height, Color.BLUE);
g.fillRect(40, y+(int)ΔY, width-40, 1, Color.BLUE);
if(ch1.value) {
for(int i = 0; i < l-1; i++) {
g.drawLine(width/2+scaleX*i+40, y-scaleY*Psi[i]+ΔY, width/2+scaleX*(i+1)+40, y-scaleY*Psi[i+1]+ΔY, p);
if(sym)
g.drawLine(width/2-scaleX*i+40, y-scaleY*Psi[i]+ΔY, width/2-scaleX*(i+1)+40, y-scaleY*Psi[i+1]+ΔY, p);
else
g.drawLine(width/2-scaleX*i+40, y+scaleY*Psi[i]+ΔY, width/2-scaleX*(i+1)+40, y+scaleY*Psi[i+1]+ΔY, p);
}
}
p.setColor(Color.rgb(255, 127, 0));
if(ch2.value) {
for(int i = 0; i < l-1; i++) {
g.drawLine(width/2+scaleX*i+40, y-scaleY*PsiSquared[i]+ΔY, width/2+scaleX*(i+1)+40, y-scaleY*PsiSquared[i+1]+ΔY, p);
g.drawLine(width/2-scaleX*i+40, y-scaleY*PsiSquared[i]+ΔY, width/2-scaleX*(i+1)+40, y-scaleY*PsiSquared[i+1]+ΔY, p);
}
}
p.setColor(Color.WHITE);
p.setTextSize(20);
p.setTextAlign(Paint.Align.RIGHT);
g.drawString(String.valueOf(energylevel), 300, y+height+230, p);
p.setTextAlign(Paint.Align.CENTER);
p.setTextSize(20);
p.setColor(Color.YELLOW);
if(!ch3.value) {
g.drawString(String.valueOf(minY), 40+width/2, y+height, p);
g.drawString(String.valueOf(minX), 40, y+(int)ΔY+16, p);
g.drawString(String.valueOf(maxY), 40+width/2, y, p);
g.drawString(String.valueOf(maxX), 40+width, y+(int)ΔY+16, p);
g.drawString(String.valueOf(averageY), 40+width/2, y+height/2, p);
g.drawString(String.valueOf(averageX), 40+width/2, y+(int)ΔY+16, p);
}
super.paint(g);
}

// WIP
@Override
public void actionPerformed(int n) {
switch(n) {
case 0:
energylevel++;
if(energylevel == 81)
energylevel = 80;
break;
case 1:
energylevel--;
if(energylevel == 0)
energylevel = 1;
break;
case 2:
rebuild(energylevel, l);
break;
}
}
}

0 comments on commit b78aee9

Please sign in to comment.