diff --git a/docs/src/lectures/lecture1.md b/docs/src/lectures/lecture1.md index 0b361e8..5f6d176 100644 --- a/docs/src/lectures/lecture1.md +++ b/docs/src/lectures/lecture1.md @@ -11,7 +11,7 @@ The following list is a reference of the tools used for building advanced models ### Julia -This course will use Julia as the fundamental tool to solve numerical problems. ModelingToolkit.jl is a package written in pure Julia and leverages the fundamental technologies of symbolic math from Symbolics.jl, numerical solvers from DifferentialEquations.jl, and automatic differentiation from ForwardDiff.jl. To demonstrate an introduction to these technologeies, lets focus on one of the most fundamental engineering problems: the *mass-spring-damper*. For now, let's leave the mass out of the system to avoid the 2nd derivative term and assume a non-linear spring (``k \cdot x^{1.5}``) +This course will use Julia as the fundamental tool to solve numerical problems. ModelingToolkit.jl is a package written in pure Julia and leverages the fundamental technologies of symbolic math from Symbolics.jl, numerical solvers from DifferentialEquations.jl, and automatic differentiation from ForwardDiff.jl. To demonstrate an introduction to these technologies, let's focus on one of the most fundamental engineering problems: the *mass-spring-damper*. For now, let's leave the mass out of the system to avoid the 2nd derivative term and assume a non-linear spring (``k \cdot x^{1.5}``) ![](../img/spring_damper.svg) @@ -178,10 +178,10 @@ sol = solve(prob); sol.retcode ``` -Now we get a `DtLessThanMin` code, meaning the solver failed to converge. The reason for this is an index problem, our algebraic constraint equation does not use the 2nd derivative term ``\ddot{x}``. To solve index problems, the algrebraic constraints must be differentiated until they contain the highest order terms. This can be done as an exercise, however, this provides a perfect segue to the tool that can make all this easier and automatic: ModelingToolkit.jl +Now we get a `DtLessThanMin` code, meaning the solver failed to converge. The reason for this is an index problem, our algebraic constraint equation does not use the 2nd derivative term ``\ddot{x}``. To solve index problems, the algebraic constraints must be differentiated until they contain the highest order terms. This can be done as an exercise, however, this provides a perfect segue to the tool that can make all this easier and automatic: ModelingToolkit.jl ### ModelingToolkit.jl -ModelingToolkit.jl uses symbolic math from Symbolics.jl to provide automatic index reduction and problem simplification to provide the optimal form for a numerical solver. To define the same problem attempted previously in ModelingToolkit.jl, we first specify an independent variable ``t`` and it's differential operator +ModelingToolkit.jl uses symbolic math from Symbolics.jl to provide automatic index reduction and problem simplification to provide the optimal form for a numerical solver. To define the same problem attempted previously in ModelingToolkit.jl, we first specify an independent variable ``t`` and its differential operator ```@example l1 using ModelingToolkit @@ -235,7 +235,7 @@ observed(odesys) Notice how the 2nd derivative term `ẍ(t)` has been automatically determined from the symbolic derivative of `ẋ(t)`. -We can now assembly a problem and solve it. The initial conditions do not need to be supplied here because the `sys` contains the variable defaults from `vars`. The solution object `sol` can now be indexed symbolically from any symbol of the system regardless if it's a solved variable, observable, or even a parameter. This way, if for example doing a batch of simulations, each respective solution object can easily retrieve all respective information about the simulation. +We can now assemble a problem and solve it. The initial conditions do not need to be supplied here because the `sys` contains the variable defaults from `vars`. The solution object `sol` can now be indexed symbolically from any symbol of the system regardless if it's a solved variable, observable, or even a parameter. This way, if for example doing a batch of simulations, each respective solution object can easily retrieve all respective information about the simulation. ```@example l1 u0 = [] # <-- used to override defaults of ODESystem variables @@ -305,7 +305,7 @@ nothing # hide ### Components -To define a component, we use the `@mtkmodel` macro and define it's parameters, variables, connection ports, and equations. The mass component can be defined as +To define a component, we use the `@mtkmodel` macro and define its parameters, variables, connection ports, and equations. The mass component can be defined as ```@example l1 @mtkmodel Mass begin @@ -475,7 +475,7 @@ nothing # hide ![spring](../img/spring.svg) -One thing to consider now in the `Spring` component is the meaning of the spring stretch/compression variable `x`. What does it mean if this variable is positive or negative? It's important to note when reviewing the model output that a positive `x` means the spring is compressed and vise versa for a negative `x`. +One thing to consider now in the `Spring` component is the meaning of the spring stretch/compression variable `x`. What does it mean if this variable is positive or negative? It's important to note when reviewing the model output that a positive `x` means the spring is compressed and vice versa for a negative `x`. Now, if we want to create a full *mass-spring-damper* system with our new `Damper` and `Spring` components, we need to create some boundary conditions, such as a stationary reference and an input force. Creating a stationary reference in acausal modeling is a bit tricky. We know that the velocity should be set to zero, as it's stationary. But what should the force be? Thinking about Newton's principles, every force on a non-moving object is met with an equal but opposite force. Therefore we add a variable `f` to represent this force, which will be part of the solved system solution. @@ -504,7 +504,7 @@ Note the sign convention `port.f ~ -f`. This is maybe not expected. To underst ![reference](../img/reference.svg) -Finally, considering an input force, we can imagine this to be an invisible hand that pushes with a constant force. This invisible hand will move with the port with velocity `v`. We don't know this velocity, it's a variable that will part of the solved system solution. +Finally, considering an input force, we can imagine this to be an invisible hand that pushes with a constant force. This invisible hand will move with the port with velocity `v`. We don't know this velocity, it's a variable that will be part of the solved system solution. ```@example l1 @mtkmodel ConstantForce begin diff --git a/docs/src/lectures/lecture2.md b/docs/src/lectures/lecture2.md index c72c90e..0778ab8 100644 --- a/docs/src/lectures/lecture2.md +++ b/docs/src/lectures/lecture2.md @@ -138,13 +138,13 @@ The variables of this system are ``x``, ``p``, ``\rho``, and ``\dot{m}``. By in !!! note "mass flow guess" - We know that mass flow rate thru a pipe is equal to + We know that mass flow rate through a pipe is equal to ```math \dot{m} = \rho \bar{u} A ``` - where ``\bar{u}`` is the average flow velocity thru cross section ``A``. We can assume that ``\bar{u} \approx \dot{x}``. Therefore we have + where ``\bar{u}`` is the average flow velocity through cross section ``A``. We can assume that ``\bar{u} \approx \dot{x}``. Therefore we have ```math \dot{m} = \rho \cdot \dot{x} \cdot A @@ -443,7 +443,7 @@ u_2 = \frac{\dot{m}}{\rho_2 A} !!! note "Conservation of Momentum" - the term ``\rho V \dot{u}`` introduces what is referd to as fluid inertia. This is what resolves the pressure wave propagation through a pipe. A classic wave propagation example in pipes is the "water hammer" effect. The full derivation for the flow velocity derivative is when deriving in 2 dimensions is + the term ``\rho V \dot{u}`` introduces what is referred to as fluid inertia. This is what resolves the pressure wave propagation through a pipe. A classic wave propagation example in pipes is the "water hammer" effect. The full derivation for the flow velocity derivative is when deriving in 2 dimensions is ```math \frac{D \text{V}}{Dt} = \frac{\partial \text{V}}{\partial t} + \frac{\partial \text{V}}{\partial x} u + \frac{\partial \text{V}}{\partial z} w ``` diff --git a/docs/src/lectures/lecture3.md b/docs/src/lectures/lecture3.md index f0a58e7..153c0a8 100644 --- a/docs/src/lectures/lecture3.md +++ b/docs/src/lectures/lecture3.md @@ -346,7 +346,7 @@ An equivalent statement to this problem is the following: This is equivalent because "the order conditions for order ``o-1`` are satisfied exactly" is equivalent to stating that the method satisfies that the Taylor series expansion exactly calculates the ``o``th derivative term in the Taylor series expansion, and as the divergence of the order conditions shrinks then so does ``C`` which is a linear combination of the divergences of the order conditions. In this formulation, the optimal Runge-Kutta tableau is thus the solution to a (generally high dimensional) nonlinear constrained optimization problem! -However, similar to how the order conditions can quickly become intractible concisely state or compute by hand, and thus many of the methods used in practice used a mixture of hand-optimization mixed with a numerical optimization process. The most famous method is the Dormand-Prince method, which is the tableau behind popular software such as `dopri5`, `ode45`, `DP5`, and other implementations. It is thus given by the tabeleau: +However, similar to how the order conditions can quickly become intractable to concisely state or compute by hand, many of the methods used in practice used a mixture of hand-optimization mixed with a numerical optimization process. The most famous method is the Dormand-Prince method, which is the tableau behind popular software such as `dopri5`, `ode45`, `DP5`, and other implementations. It is thus given by the tableau: ![](../img/dp5.png) @@ -535,7 +535,7 @@ The scheme 2 uses our developed machinery to be as fast as possible, while achie !!! note - Because the Dormand-Prince method has a 4th order dense output, it's commonly misstated the `ode45`/`dopri5` method is 4th order, since empirical studies which do not carefully control the stepping to match the saving will see 4th order convergence! + Because the Dormand-Prince method has a 4th order dense output, it's commonly misstated that the `ode45`/`dopri5` method is 4th order, since empirical studies which do not carefully control the stepping to match the saving will see 4th order convergence! !!! note diff --git a/docs/src/lectures/lecture4.md b/docs/src/lectures/lecture4.md index 65089e7..fa49560 100644 --- a/docs/src/lectures/lecture4.md +++ b/docs/src/lectures/lecture4.md @@ -149,18 +149,18 @@ time step. ![](../img/numerical_stiffness_effect.png) In this illustrative plot, the grey is "the true solution". The representative solution -has a fast process and a slow process, the slow precess is an r-shaped curve. The fast -process is a quasi-steady state process, i.e. it very quickly brings any purturbation from -the r-shaped curve back to the main curve (and example of this is the ``y_2`` term in the +has a fast process and a slow process, the slow process is an r-shaped curve. The fast +process is a quasi-steady state process, i.e. it very quickly brings any perturbation from +the r-shaped curve back to the main curve (an example of this is the ``y_2`` term in the Robertson equation below). The black line up top is a **numerical solution** with an -explicit method on such an equation. It's show how for a "reasonable" sized ``h`` that the +explicit method on such an equation. It's shown how for a "reasonable" sized ``h`` that the large derivatives of the fast process back to the stable manifold cause explicit methods to overshoot the manifold, thus requiring the ``h`` to be small enough to "not overshoot too much", with this overshooting resulting in a jagged behavior. This overshooting is exactly the behavior that causes a step size limitation, thus forcing ``h`` to be sufficiently small when there is such time-scale separation, and thus simulations -of the long-scale phonomena require time steps on the scale of the short-scale phonomena. +of the long-scale phenomena require time steps on the scale of the short-scale phenomena. If those two time-scales are orders of magnitude different, then accurately handling this type of equations thus requires orders of magnitude more time steps, leading to the inefficiency of explicit methods. @@ -383,7 +383,7 @@ iterations is because the time scale separation increased, and therefore the `dt for stability decreased, and therefore it started requiring too many steps (default 1e5) in order to solve the equation. -**Notably, this shows that stiffness is a parameter-dependent phonomena** +**Notably, this shows that stiffness is a parameter-dependent phenomenon** If you change the parameter values, you can change whether an equation is stiff or non-stiff.