Anterior

Ecuación diferencial de segundo orden

Resolver la ecuación diferencial de segundo orden

d 2 θ dt + g l sinθ=0

por procedimientos numéricos. Las condiciones iniciales dependen de cada etapa del movimiento:

public class Estado {
    double t;
    double x;
    double v;
    public Estado(double t, double x, double v) {
        this.t=t;
        this.x=x;
        this.v=v;
    }
    void setDatos(double t, double x, double v){
        this.t=t;
        this.x=x;
        this.v=v;
    }
}

public class Oscilador extends RungeKutta{
    double longitud;
     public Oscilador(double longitud, double h){
      super(h);
      this.longitud=longitud;
    }
    void setDatos(double longitud){
      this.longitud=longitud;
    }
    public double f(double x, double v, double t){
        return (-9.8*Math.sin(x)/longitud);
    }
}  

public class MiCanvas extends Canvas {
    double dt=0.01;
    double t=0.0;
   double anguloMax=10*Math.PI/180;
   final double radio=1.0;   //longitud del péndulo en m
   double longitud=radio;      //el péndulo cambia de longitud
   double delta=0.05;
//objeto oscilador
   Estado estado=new Estado(0.0, -anguloMax, 0.0);
   Oscilador oscilador=null;
   int tipo=0;
  void setNuevo(double delta, double angulo){
    this.delta=delta;
    this.anguloMax=angulo*Math.PI/180;
    estado=new Estado(0.0, -anguloMax, 0.0);
    oscilador=new Oscilador(radio, dt);
    Etotal=Ep=9.8*(1-Math.cos(anguloMax));
    t=0;
    tipo=0;
    longitud=radio;
    trayec.npoints=0;
    repaint();
 }

 void mover(){
     t+=dt;
     switch(tipo){
        case 0:
            oscilador.resolver(estado);
            Ep=9.8*radio*(1-Math.cos(estado.x));
            if(estado.x>=0){
                double w0=Math.sqrt(2*9.8*(1-Math.cos(anguloMax))/radio);
                double w1=w0*radio*radio/((radio-delta)*(radio-delta));
                anguloMax=Math.acos(1-(radio-delta)*w1*w1/19.6);
                Etotal=9.8*(radio-delta)*(1-Math.cos(anguloMax))+9.8*delta;
                estado.setDatos(0.0, 0.0, w1);
                oscilador.setDatos(radio-delta);
                longitud=radio-delta;
                tipo=1;
            }
            break;
        case 1:
            oscilador.resolver(estado);
            Ep=9.8*(radio-delta)*(1-Math.cos(estado.x))+9.8*delta;
            if(estado.v<=0){
                longitud=radio;
                estado.setDatos(0.0, anguloMax, 0.0);
                Etotal=9.8*radio*(1-Math.cos(anguloMax));
                oscilador.setDatos(radio);
               tipo=2;
            }
            break;
        case 2:
            oscilador.resolver(estado);
            Ep=9.8*radio*(1-Math.cos(estado.x));
            if(estado.x<=0){
                double w0=Math.sqrt(2*9.8*(1-Math.cos(anguloMax))/radio);
                double w1=w0*radio*radio/((radio-delta)*(radio-delta));
                anguloMax=Math.acos(1-(radio-delta)*w1*w1/19.6);
                Etotal=9.8*(radio-delta)*(1-Math.cos(anguloMax))+9.8*delta;
                estado.setDatos(0.0, 0.0, -w1);
                oscilador.setDatos(radio-delta);
                longitud=radio-delta;
                tipo=3;
            }
            break;
        case 3:
            oscilador.resolver(estado);
            Ep=9.8*(radio-delta)*(1-Math.cos(estado.x))+9.8*delta;
            if(estado.v>=0){
                estado.setDatos(0.0, -anguloMax, 0.0);
                oscilador.setDatos(radio);
                Etotal=9.8*radio*(1-Math.cos(anguloMax));
                longitud=radio;
                tipo=0;
                trayec.npoints=0;
                if(anguloMax>1.31){   //75º máximo
                    delta=-delta;
                }
            }
            break;
        default:
            break;
      }
 }
}
Anterior