Skip to content

Incorporate time integration to account for speed variations #1021

Closed
@jguarato

Description

@jguarato

This issue was created in order to document and detail the task of implementing the numerical integrator that was assigned to me. This task may resolve other issues: #429, #884, #1001.


Currently, it is not possible to solve the transient model with the rotor speed varying over time in ROSS, nor to incorporate other information into the model that depends on time. One solution would be to use a numerical integrator to solve the following equation of motion for a rotor:

$$ M\ \ddot{q}+[C+ G\ \Omega(t)]\ \dot{q} + [K + K_{st}\ \dot{\Omega}(t)]\ {q} = F $$

The function solve_ivp() available in SciPy integrate library can be applied in this case. This function numerically integrates a set of first-order vector ordinary differential equations (ODEs):

$$ \frac{d\mathbf{y}}{dt} = \mathrm{f}(t,\ \mathbf{y}) $$

given the initial conditions $\mathbf{y}(0)=y_0$, and it also offers 6 different integration methods. Then, it would be possible to choose a more appropriate method for each type of problem, allowing to solve, for example, non-stiff problems using explicit methods (“RK23”, “RK45”, “DOP385”), and also stiff problems using implicit methods (“Radau”, “BDF”).

A higher-order ODE can be reduced to a first-order differential equation by introducing intermediate derivatives into the $\mathbf{y}$ vector. So, this implies that:

$$ \mathbf{y} = [q, \dot{q}] $$

and accordingly $\mathrm{f}(t,\ \mathbf{y})$ must return:

$$ \frac{d\mathbf{y}}{dt} = [\dot{q}, \ddot{q}] $$

where the second-order derivative could be calculated from the equation of motion by inverting the $M$ matrix as:

$$ \ddot{q} = M^{-1} [F - [C+ G\ \Omega(t)]\ \dot{q} - [K + K_{st}\ \dot{\Omega}(t)]\ {q} ] $$

The values of rotational speed $\Omega(t)$ and acceleration $\dot{\Omega}(t)$ varying over time can be stored in arrays. Such arrays must be compatible with the array of times in which the computed solution will be stored.

Consequently, the integration can be done by calling:

scipy.integrate.solve_ivp(fun, t_span, y0, method, t_eval, args)

and passing the callable function that will be integrated fun(t, y), the interval of integration t_span=[t0, tf] and the initial state y0. It is optional, but it could be important to pass the integration method, the vector of times in which the computed solution will be stored t_eval, and a tuple of additional arguments that could be passed to fun(t, y, *args).

At first, I defined the function fun(t, y, *args) to be integrated as follows:

def _equation_of_motion(self, t, y, t0, dt, speed, accel, inv_M, C, G, K, Kst, F):
	
  size = int(len(y) / 2)
  disp_resp = y[:size]
  velc_resp = y[size:]

  i = round((t - t0) / dt)
  C_aux = C + G * speed[i]
  K_aux = K + Kst * accel[i]
  F_total = F[:, i]

  accl_resp = inv_M @ (F_total - (C_aux @ velc_resp) - (K_aux @ disp_resp))

  dydt = np.zeros(2 * size)
  dydt[:size] = velc_resp
  dydt[size:] = accl_resp

  return dydt

Here, I would like to highlight two points:

  • Accessing the rotational speed speed[i] at a specific time t can be done by a conversion based on the initial time t0 and time step dt to obtain the respective array index.
  • Passing the model matrices as arguments makes the function generic, so it could be used to solve the model in both modal and physical spaces. However, this may change later if needed.

When choosing to solve in the modal space, there is a possibility to reduce model based on the selected number of modes. A reduced model implies a considerable reduction in computational cost. Another option, suggested by Prof. Aldemir, to obtain the reduced model would be to pass the frequency range of interest.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions