Решение системы массы, пружины, демпфера и кулоновского трения - PullRequest
0 голосов
/ 25 июня 2019

Рассмотрим систему ниже:

            <img src="https://i.stack.imgur.com/CSKyf.png" width="500">
        Fig.1 - Mass, spring, damper and Coulomb frction (image courtesy of <a href="https://commons.wikimedia.org/wiki/File:Mass-Spring-Damper.svg" rel="nofollow noreferrer">Wikimedia</a>).

с динамическим уравнением:

                        <img src="https://i.stack.imgur.com/MpA8Y.png" width="300">

, где Ff - трение Амонтона-Колумба, определяемое как:

          <img src="https://i.stack.imgur.com/TNroj.png" width="500">

и, следовательно, условие no-slip определяется как

                   <img src="https://i.stack.imgur.com/Ty8iB.png" width="300">

Следуя этому примеру , я имею в виду неопределенный код, который не знаю, как выполнить:

from scipy.integrate import odeint
import numpy as np

m = 1.0
k = 2.0
c = 0.1
mus = 0.3
muk = 0.2
g = 9.8
vf = 0.01

def eq(X, t, Xi):
  Ff = k * (Xi[0] - X[0]) + c * (Xi[1] - X[1]) # - m * dydt

  if np.abs(X[1]) < vf and np.abs(Ff) < mus * m * g :
    Ff = k * (Xi[0] - X[0]) + c * (Xi[1] - X[1]) # - m * dydt
  else:
    Ff = -np.sign(X[1]) * muk * m * g
    pass

  dxdt = X[1]
  dydt = (k * (Xi[0] - X[0]) + c * (Xi[1] - X[1]) - Ff) / m
  return [dxdt, dydt]

t = np.linspace(0, 10, 1000)
Xi0 = np.piecewise(t, [t < 1, t >= 1], [0, 1])
X0 = [0, 0]
sol = odeint(eq, X0, t)

, где Xi0 - шаговая функция.Моя главная проблема заключается в том, что когда я хочу определить Ff, это зависит от dydt, который будет определен позже в этой области!

Буду признателен, если вы поможете мне узнать, какой самый канонический способ численного решения этой системы.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

другой подход - просто использовать цикл for и последовательно вычислять шаги:

Y = np.piecewise(t, [t < t2, t >= t2], [0, 1])
dY = np.insert(np.diff(Y) / np.diff(t), 0 , v0, axis = 0)
X = np.zeros((steps,))
dX = np.zeros((steps,))
dX[0] = v0
ddX = np.zeros((steps,))
Ff = np.zeros((steps,))
# FS = np.zeros((steps,))
dt = t1 / (steps - 1)

for ii in range(1, steps):
  X[ii] = X[ii - 1] + dt * dX[ii - 1]
  dX[ii] = dX[ii - 1] + dt * ddX[ii - 1]
  Ff[ii] = k * (Y[ii] - X[ii]) #+ c * (dY[ii] - dX[ii])
  if not (np.abs(dX[ii]) < vf and np.abs(Ff[ii]) < mus * m * g) :
    Ff[ii] = np.sign(dX[ii]) * muk * m * g
  ddX[ii] = (k * (Y[ii] - X[ii]) - Ff[ii]) / m 

результат показан зеленым на графике ниже:

              <img src="https://i.stack.imgur.com/8qsiE.png" width="500">

Я также изменил vf на 0.001. Результаты отличаются от odeint по некоторым причинам!

0 голосов
/ 25 июня 2019

Я положу здесь упрощенное / временное решение, пока кто-нибудь не придет с лучшим:

from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt

m = 0.2
k = 2.0
c = 0.1
mus = 0.3
muk = 0.2
g = 9.8
vf = 0.01
v0 = 0.0
t1 = 10
sign = lambda x: np.tanh(100*x)

def Xi(t):
  if t < 1 :
    return 0
  else:
    return 1

vXi = np.vectorize(Xi)

def eq(X, t, Xi):
  Ff = k * (Xi(t) - X[0])

  if np.abs(X[1]) < vf and np.abs(Ff) < mus * m * g :
    Ff = k * (Xi(t) - X[0])
  else:
    Ff = sign(X[1]) * muk * m * g

  d2x = (k * (Xi(t) - X[0]) - Ff) / m
  return [X[1], d2x]

t = np.linspace(0, t1, 1000)
X0 = [v0, 0]
sol = odeint(func = eq, y0 = X0, t = t, args = (Xi, ), mxstep = 50000, atol = 1e-5)

plt.plot(t, sol[:, 0], 'r-', label = 'Output (x(t))')
plt.plot(t, vXi(t), 'b-', label = 'Input (xi(t))')
plt.ylabel('values')
plt.xlabel('time')
plt.legend(loc='best')
plt.show()

, и в результате получится:

              <img src="https://i.stack.imgur.com/hOWeJ.png" width="500">

Я использовал Это , , это и , это сообщения для написания кода.Я проигнорировал демпфирование и инерцию, чтобы упростить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...