相空間(位置+運動量)上のベクトル。
曲面上の運動のシミュレーション用なので、2次元。 4次のルンゲクッタ法を使った数値計算関数付き。
Esempio n. 1
0
        static void Show(double t, PhaseVector q)
        {
            double y = Math.Sin(q.q2);
            double x = Math.Cos(q.q1) * y;

            y = Math.Sin(q.q1) * y;
            double z = -Math.Cos(q.q2);

            Console.Write("{0},{1},{2},{3}\n",
                          t, x, y, z);
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            const double dt               = 0.01;
            const double t_end            = 10;
            const int    DISPLAY_INTERVAL = 5;

            const double q1 = 0;
            const double q2 = Math.PI / 2;
            const double p1 = 0.1;
            const double p2 = 0;

            PhaseVector.Simulate(
                0, t_end, dt, DISPLAY_INTERVAL,
                new PhaseVector(q1, q2, p1, p2),
                F, Show
                );
        }
Esempio n. 3
0
        static PhaseVector F(PhaseVector q)
        {
            const double M = 0.1;
            const double G = 10;

            double s2 = Math.Sin(q.q2);
            double c2 = Math.Cos(q.q2);

            return(new PhaseVector(
                       q.p1 / (M * s2),
                       q.p2 / M,
                       0,
                       (q.p1 * q.p1 * c2)
                       / (M * s2 * s2 * s2)
                       - M * G * s2
                       ));
        }
Esempio n. 4
0
    /// <summary>
    /// 微分方程式
    /// (d/dt)q = f(q)
    /// の解を数値計算で求める。
    /// </summary>
    /// <param name="t0">時刻の初期値</param>
    /// <param name="t1">時刻の最終値</param>
    /// <param name="dt">時刻の刻み幅</param>
    /// <param name="display_interval">結果出力の間隔</param>
    /// <param name="initial">q の初期値</param>
    /// <param name="f">f</param>
    /// <param name="cb">結果出力用のコールバック関数</param>
    /// <remarks>
    /// 4次のルンゲクッタ法で計算。
    /// </remarks>
    public static void Simulate(
      double t0, double t1, double dt, int display_interval,
      PhaseVector initial,
      PhaseFunc f, Callback cb)
    {
      PhaseVector q = initial;

      int n = 1;
      for (double t = t0; t < t1; t += dt, ++n)
      {
        PhaseVector k1 = dt * f(q);
        PhaseVector k2 = dt * f(q + k1 / 2);
        PhaseVector k3 = dt * f(q + k2 / 2);
        PhaseVector k4 = dt * f(q + k3);
        q = q + (k1 + 2 * (k2 + k3) + k4) / 6;

        if (n > display_interval)
        {
          cb(t, q);
          n = 1;
        }
      }
    }
Esempio n. 5
0
        /// <summary>
        /// 微分方程式
        /// (d/dt)q = f(q)
        /// の解を数値計算で求める。
        /// </summary>
        /// <param name="t0">時刻の初期値</param>
        /// <param name="t1">時刻の最終値</param>
        /// <param name="dt">時刻の刻み幅</param>
        /// <param name="display_interval">結果出力の間隔</param>
        /// <param name="initial">q の初期値</param>
        /// <param name="f">f</param>
        /// <param name="cb">結果出力用のコールバック関数</param>
        /// <remarks>
        /// 4次のルンゲクッタ法で計算。
        /// </remarks>
        public static void Simulate(
            double t0, double t1, double dt, int display_interval,
            PhaseVector initial,
            PhaseFunc f, Callback cb)
        {
            PhaseVector q = initial;

            int n = 1;

            for (double t = t0; t < t1; t += dt, ++n)
            {
                PhaseVector k1 = dt * f(q);
                PhaseVector k2 = dt * f(q + k1 / 2);
                PhaseVector k3 = dt * f(q + k2 / 2);
                PhaseVector k4 = dt * f(q + k3);
                q = q + (k1 + 2 * (k2 + k3) + k4) / 6;

                if (n > display_interval)
                {
                    cb(t, q);
                    n = 1;
                }
            }
        }
Esempio n. 6
0
    static void Show(double t, PhaseVector q)
    {
      double y = Math.Sin(q.q2);
      double x = Math.Cos(q.q1) * y;
      y = Math.Sin(q.q1) * y;
      double z = -Math.Cos(q.q2);

      Console.Write("{0},{1},{2},{3}\n",
        t, x, y, z);
    }
Esempio n. 7
0
    static PhaseVector F(PhaseVector q)
    {
      const double M = 0.1;
      const double G = 10;

      double s2 = Math.Sin(q.q2);
      double c2 = Math.Cos(q.q2);

      return new PhaseVector(
        q.p1 / (M * s2),
        q.p2 / M,
        0,
        (q.p1 * q.p1 * c2)
          / (M * s2 * s2 * s2)
         - M * G * s2
       );
    }