STEM 隨筆︰古典力學︰模擬術【一】

才想可以快速通過

n07_simulation.ipynb

 Now that we have the symbolic equations of motion we need to transform them into Python functions that can be evaluated for use in numerical integration. Numerical integration is required to solve the ordinary differential initial value problem and allow us to see how the states change through time.

 

筆記文本,輕輕飛越『動態模擬』

Dynamical simulation

Dynamical simulation, in computational physics, is the simulation of systems of objects that are free to move, usually in three dimensions according to Newton’s laws of dynamics, or approximations thereof. Dynamical simulation is used in computer animation to assist animators to produce realistic motion, in industrial design (for example to simulate crashes as an early step in crash testing), and in video games. Body movement is calculated using time integration methods.

Physics engines

In computer science, a program called a physics engine is used to model the behaviors of objects in space. These engines allow simulation of the way bodies of many types are affected by a variety of physical stimuli. They are also used to create Dynamical simulations without having to know anything about physics. Physics engines are used throughout the video game and movie industry, but not all physics engines are alike; They are generally broken into real-time and the high precision but these are not the only options. Most real-time physics engines are inaccurate and yield only the barest approximation of the real world, whereas most high-precision engines are far too slow for use in everyday applications. To understand how these Physics engines are built, a basic understanding of physics is required. Physics engines are based on the actual behaviors of the world as described by classical mechanics. Engines do not typically account for Modern Mechanics (see Theory of relativity and quantum mechanics) because most visualization deals with large bodies moving relatively slowly, but the most complicated engines perform calculations for Modern Mechanics as well as Classical. The models used in Dynamical simulations determine how accurate these simulations are.

 

語詞叢林!只需介紹一下 PyDy 之

codegen

Introduction

The pydy.codegen package contains various tools to generate numerical code from symbolic descriptions of the equations of motion of systems. It allows you to generate code using a variety of backends depending on your needs. The generated code can also be auto-wrapped for immediate use in a Python session or script. Each component of the code generators and wrappers are accessible so that you can use just the raw code or the wrapper versions.

We currently support three backends:

lambdify
This generates NumPy-aware Python code which is defined in a Python lambda function, using the sympy.utilities.lambdify module and is the default generator.
Theano
This generates Theano trees that are compiled into low level code, using thesympy.printers.theano_code module.
Cython
This generates C code that can be called from Python, using SymPy’s C code printer utilities and Cython.

 

的用法!!何況早有範例也。

Example Use

The simplest entry point to the code generation tools is through the System class.

>>> from pydy.models import multi_mass_spring_damper
>>> sys = multi_mass_spring_damper()
>>> type(sys)
<class 'pydy.system.System'>
>>> rhs = sys.generate_ode_function()
>>> help(rhs) # rhs is a function:
Returns the derivatives of the states, i.e. numerically evaluates the right
hand side of the first order differential equation.

x' = f(x, t, p)

Parameters
==========
x : ndarray, shape(2,)
    The state vector is ordered as such:
        - x0(t)
        - v0(t)
t : float
    The current time.
p : dictionary len(3) or ndarray shape(3,)
    Either a dictionary that maps the constants symbols to their numerical
    values or an array with the constants in the following order:
        - m0
        - c0
        - k0

Returns
=======
dx : ndarray, shape(2,)
    The derivative of the state vector.


>>> import numpy as np
>>> rhs(np.array([1.0, 2.0]), 0.0, np.array([1.0, 2.0, 3.0]))
array([ 2., -7.])

 

怎知一跑跑了 n 次?只因結果會不一樣勒??

突然發現 m_0 , c_0, k_0  help 排列次序,為何每每不同耶??!!

 

故爾鼻子摸著閱讀『原始碼』︰

Source code for pydy.models

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""This module contains some sample symbolic models used for testing and
examples."""

# external libraries
import sympy as sm
import sympy.physics.mechanics as me

# local
from .system import System


[docs]def multi_mass_spring_damper(n=1, apply_gravity=False,
                             apply_external_forces=False):
    """Returns a system containing the symbolic equations of motion and
    associated variables for a simple mutli-degree of freedom point mass,
    spring, damper system with optional gravitational and external
    specified forces. For example, a two mass system under the influence of
    gravity and external forces looks like:

    ::

        ----------------
         |     |     |   | g
         \    | |    |   V
      k0 /    --- c0 |
         |     |     | x0, v0
        ---------    V
        |  m0   | -----
        ---------    |
         | |   |     |
         \ v  | |    |
      k1 / f0 --- c1 |
         |     |     | x1, v1
        ---------    V
        |  m1   | -----
        ---------
           | f1
           V

    Parameters
    ----------
    n : integer
        The number of masses in the serial chain.
    apply_gravity : boolean
        If true, gravity will be applied to each mass.
    apply_external_forces : boolean
        If true, a time varying external force will be applied to each mass.

    Returns
    -------
    system : pydy.system.System
        A system constructed from the KanesMethod object.

    """

 

卻是一無所獲!!??

只能死馬當活馬醫,扒文

codegen API

pydy.codegen.ode_function_generators.generate_ode_function(*args, **kwargs)

Generates a numerical function which can evaluate the right hand side of the first order ordinary differential equations from a system described by one of the following three symbolic forms:

[1] x’ = F(x, t, r, p)

[2] M(x, p) x’ = F(x, t, r, p)

[3] M(q, p) u’ = F(q, u, t, r, p)
q’ = G(q, u, t, r, p)

where

x : states, i.e. [q, u] t : time r : specified (exogenous) inputs p : constants q : generalized coordinates u : generalized speeds M : mass matrix (full or minimum) F : right hand side (full or minimum) G : right hand side of the kinematical differential equations

The generated function is of the form F(x, t, p) or F(x, t, r, p) depending on whether the system has specified inputs or not.

Parameters:

right_hand_side : SymPy Matrix, shape(n, 1)

A column vector containing the symbolic expressions for the right hand side of the ordinary differential equations. If the right hand side has been solved for symbolically then only F is required, see form [1]; if not then the mass matrix must also be supplied, see forms [2, 3].

coordinates : sequence of SymPy Functions

The generalized coordinates. These must be ordered in the same order as the rows in M, F, and/or G and be functions of time.

speeds : sequence of SymPy Functions

The generalized speeds. These must be ordered in the same order as the rows in M, F, and/or G and be functions of time.

constants : sequence of SymPy Symbols

All of the constants present in the equations of motion. The order does not matter.

mass_matrix : sympy.Matrix, shape(n, n), optional

This can be either the “full” mass matrix as in [2] or the “minimal” mass matrix as in [3]. The rows and columns must be ordered to match the order of the coordinates and speeds. In the case of the full mass matrix, the speeds should always be ordered before the speeds, i.e. x = [q, u].

coordinate_derivatives : sympy.Matrix, shape(m, 1), optional

If the “minimal” mass matrix, form [3], is supplied, then this column vector represents the right hand side of the kinematical differential equations.

specifieds : sequence of SymPy Functions

The specified exogenous inputs to the system. These should be functions of time and the order does not matter.

linear_sys_solver : string or function

Specify either numpy or scipy to use the linear solvers provided in each package or supply a function that solves a linear system Ax=b with the call signature x = solve(A, b). For example, if you need to use custom kwargs for the SciPy solver, pass in a lambda function that wraps the solver and sets them.

constants_arg_type : string

The generated function accepts two different types of arguments for the numerical values of the constants: either a ndarray of the constants values in the correct order or a dictionary mapping the constants symbols to the numerical values. If None, this is determined inside of the generated function and can cause a significant slow down for performance critical code. If you know apriori what arg types you need to support choose either array or dictionary. Note that array is faster than dictionary.

specifieds_arg_type : string

The generated function accepts three different types of arguments for the numerical values of the specifieds: either a ndarray of the specifieds values in the correct order, a function that generates the correctly ordered ndarray, or a dictionary mapping the specifieds symbols or tuples of thereof to floats, ndarrays, or functions. If None, this is determined inside of the generated function and can cause a significant slow down for performance critical code. If you know apriori what arg types you want to support choose either array, function, or dictionary. The speed of each, from fast to slow, are array, function, dictionary, None.

generator : string or and ODEFunctionGenerator, optional

The method used for generating the numeric right hand side. The string options are {‘lambdify’|’theano’|’cython’} with ‘lambdify’ being the default. You can also pass in a custom subclass of ODEFunctionGenerator.

Returns:

rhs : function

A function which evaluates the derivaties of the states. See the function’s docstring for more details after generation.

Notes

The generated function still supports the pre-0.3.0 extra argument style, i.e. args = {‘constants’: …, ‘specified’: …}, but only if constants_arg_type and specifieds_arg_type are both set to None. This functionality is deprecated and will be removed in 0.4.0, so it’s best to adjust your code to support the new argument types. See the docstring for the generated function for more info on the new style of arguments.

 

忽恍然大悟,後哈哈大笑呦◎