Procedimiento numérico
Código del procedimiento numérico que calcula las bandas de energía de un sólido lineal.
.
public abstract class Raices {
static final double E1=1.0e-15; //cota de errores
static final double E2=0.0001;
static final int MAXITERACCION=100;
static final int MAXNIVELES=10;
double a; //anchura
double b; //separación
static final double H=5.0 //profundidad del pozo;
//resultados
double Ceros[]=new double[MAXNIVELES]; // ceros de la funcóón
int nCeros=0; // número de ceros de la función
double DE=0.05; //paso de exploración en la búsqueda de ceros
abstract double f(double E);
public Raices(double a, double b) {
this.a=a;
this.b=b;
}
//procedimiento del punto medio
double punto_medio(double inf, double sup, Boolean bError){
double med, inter, ini;
int j=0; //cuenta el úúmero de iteraciones
ini=f(inf);
do{
med=(inf+sup)/2;
inter=f(med);
if(Math.abs(inter)<E1) return med;
if(Math.abs((sup-inf)/med)<E2) return med;
if(inter*ini<0)
sup=med;
else{
inf=med;
ini=inter;
}
j++;
}while(!(j==MAXITERACCION));
bError=new Boolean(true);
return med;
}
//calcula en un intervalo entre dos discontinuidades
void calcular(double E_inf, double E_sup){
if((E_inf>E_sup)||(Math.abs(E_sup-E_inf)<=DE)) return;
double inf, sup;
double ini, fin;
double raiz;
Boolean Error=new Boolean(false);
inf=E_inf+DE;
ini=f(inf);
sup=inf+DE;
while(sup<E_sup-DE){
fin=f(sup);
if(ini*fin>0){
ini=fin;
inf=sup;
sup=inf+DE;
continue;
}
raiz=punto_medio(inf, sup, Error);
if (!Error.booleanValue()){
Ceros[nCeros]=raiz;
nCeros++;
}
Error=new Boolean(false);
ini=fin;
inf=sup;
sup=inf+DE;
}
}
}
public class SolidoKp extends Raices {
double cte;
int nBanda;
double banda[]=new double[7];
public SolidoKp(double a, double b) {
super(a, b);
nBanda=0;
cte=0;
}
double f(double E){
double q=Math.sqrt(E);
double k=Math.sqrt(H-E);
double sinh=(Math.exp(k*b)-Math.exp(-k*b))/2;
double cosh=(Math.exp(k*b)+Math.exp(-k*b))/2;
return(Math.cos(q*a)*cosh+(k*k-q*q)/(2*q*k)*Math.sin(q*a)*sinh+cte);
}
void hallarBandas(){
cte=-1.0;
nCeros=0;
calcular(0.0, H);
cte=1.0;
calcular(0.0, H);
for(int i=0; i<nCeros; i++){
banda[i]=Ceros[i];
}
nBanda=nCeros;
if(nBanda%2==1){
banda[nBanda]=H;
nBanda++;
}
ordenar();
cte=0;
}
//ordena según el valor de la energía
void ordenar(){
double d;
for(int izq=1; izq<nBanda; ++izq){
for(int der=nBanda-1; der>=izq; --der){
if(banda[der-1]>banda[der]){
d=banda[der-1];
banda[der-1]=banda[der];
banda[der]=d;
}
}
}
}
}
|
