簡體   English   中英

使用帶有經典Runge-kutta積分器的StepHandlers存儲多個常微分方程輸出

[英]Store multiple ordinary differential equations outputs using StepHandlers with classical runge-kutta integrator

我對Java很陌生,在理解如何存儲常微分方程的多個解的數據時遇到一些問題。 我正在使用經典的Runge-Kutta積分器對軌跡進行積分,並且需要逐步存儲所有軌跡歷史。 我在其他問題中看到可以使用StepHandler如下存儲數據:

StepHandler stepHandler = new StepHandler() {
    public void init(double t0, double[] y0, double t) {}
    public void handleStep(StepInterpolator interpolator, boolean isLast) {
        double   t = interpolator.getCurrentTime();
        double[] y = interpolator.getInterpolatedState();
        output.add(new double[] {t, y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]});
    }
};

因此,在每個步驟中,我都會在輸出變量中添加一個包含所需數據的列表。 但是,僅當我必須存儲單個集成的數據時,此方法才有效。

我的問題是我必須運行多個ode集成,對於每個人我都需要以上述方式存儲數據。 我正在考慮創建ArrayList的ArrayList並分別存儲每個集成的集成歷史記錄,如下所示:

ArrayList<ArrayList<double[]>> integrationsOutputs = new ArrayList<ArrayList<double[]>>();
private void propagate() {
    // initialise arraylist to store results locally
    ArrayList<double[]> outputLocal = new ArrayList<double[]>();
    double[] y = new double[8];
    // defining the integrator
    FirstOrderIntegrator integrator = new ClassicalRungeKuttaIntegrator(0.5);
    // setting the differential equations
    FirstOrderDifferentialEquations ode = new models.EquationsOfMotion();
    // adding event handler
    integrator.addStepHandler(stepHandler);
    // integrate
    integrator.integrate(ode, t0, y0, tf, y);
    integrationsOutputs.add(outputLocal);   
}

問題是,我不能讓StepHandler“看到” outputLocal ArrayList的我為了存儲一個整合的結果產生。 是否有可能修改StepHandler通過它outputLocal變量,這樣我可以實際存儲我想要的數據?

先謝謝您的幫助。

更新

使用LutzL的一些建議,我設法使它起作用。 我無法直接應用LutzL的解決方案,因為我無法使用setTape()方法。 我必須將StepHandler接口實現到我自己的步驟處理程序中,並將方法添加到其中,如下所示:

public class MyStepHandler implements StepHandler {
    ArrayList<double[]> _tape;
    public void setTape(ArrayList<double[]> tape) { _tape = tape; }
    @Override
    public void handleStep(StepInterpolator interpolator, boolean isLast) {
        double   t = interpolator.getCurrentTime();
        double[] y = interpolator.getInterpolatedState();
        _tape.add(new double[] {t, y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]});

    }
    @Override
    public void init(double t0, double[] y0, double t) {}
}

從您的代碼段中尚不清楚如何構造整個初始點的循環。 通常,邏輯看起來像這樣

  • 初始化集成器和stepHandler,
  • 循環遍歷初始點(t0,y0)
    • 分配一個新的磁帶localTape
    • 將此磁帶傳遞給stepHandler,`stepHandler.setTape(localTape)
    • 整合ODE
    • 將localTape附加到全局磁帶集合

由於磁帶是通過引用傳遞的,因此在集成后,步驟處理程序中更新的磁帶仍然是相同的localTape,因此不必將其傳遞回去。 因此,您只需要將stepHandler擴展為

StepHandler stepHandler = new StepHandler() {
    List<double[]> _tape;
    public void setTape(List<double[]> tape) { _tape = tape; }
    public void init(double t0, double[] y0, double t) {}
    public void handleStep(StepInterpolator interpolator, boolean isLast) {
        double   t = interpolator.getCurrentTime();
        double[] y = interpolator.getInterpolatedState();
        _tape.add(new double[] {t, y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]});
}

};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM