---
title: "Falling Particle ODE"
author: "Wolfgang Christian / Alfonso R. Reyes"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Falling Particle ODE}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

## The FallingParticleODE class using the Euler ODE solver
Because this is free fall of a particle in one-dimension, for vertical motion, we use Newton's second law:

$$
m \frac{d^2y} {dt^2} = F
$$
and we know that the gravitational force is:
$$
F = -mg
$$
Therefore:
$$
m \frac{d^2y} {dt^2} = -g
$$
That expressing as first-order differential equations:
$$
\frac {dy}{dt} = v \\
\frac {dv}{dt} = -g
$$

($y$), we define the numerical state equations as:

    state[1]  x
    state[2]  v
    state[3]  t

From the equations of motion for a falling particle, the derivatives are:
$$
\dot s_1 = s_2 \\
\dot s_2 = -g  \\
\dot s_3 = 1
$$
which is equivalent of writing this as the rate in the code:
$$
r_1 = r_2 \\
r_2 = -g  \\
r_3 = 1
$$

## Build the FallingParticleODE class
We don't indicate the ODE solver at this time. That is done in the application in the next section.

```{r, message=FALSE, results='hold'}
library(rODE)

# This code can also be found in the `examples` folder under this name:
# FallingParticleODE.R
#

setClass("FallingParticleODE", slots = c(
    g = "numeric"
    ),
    prototype = prototype(
        g = 9.8
    ),
    contains = c("ODE")
    )

setMethod("initialize", "FallingParticleODE", function(.Object, ...) {
    .Object@state <- vector("numeric", 3)
    return(.Object)
})

setMethod("getState", "FallingParticleODE", function(object, ...) {
    # Gets the state variables.
    return(object@state)
})

setMethod("getRate", "FallingParticleODE", function(object, state, ...) {
    # Gets the rate of change using the argument's state variables.
    object@rate[1] <- state[2]
    object@rate[2] <- - object@g
    object@rate[3] <- 1
    
    object@rate
})

# constructor
FallingParticleODE <- function(y, v) {
    .FallingParticleODE <- new("FallingParticleODE")
    .FallingParticleODE@state[1] <- y
    .FallingParticleODE@state[2] <- v
    .FallingParticleODE@state[3] <- 0
    .FallingParticleODE
}

```

## Run the application FallingParticleODEApp

```{r}
# This code can also be found in the `examples` folder under this name:
# 
# FallingParticleODEApp.R
#
#
FallingParticleODEApp <- function(verbose = FALSE) {
    library(ggplot2)
    
    # load the R class that sets up the solver for this application
    
    initial_y <- 10   # initial y position
    initial_v <- 0    # initial x position
    dt        <- 0.01 # delta time for step
    
    
    ball <- FallingParticleODE(initial_y, initial_v)
    
    solver <- Euler(ball)
    solver <- setStepSize(solver, dt)
    
    rowVector <- vector("list")
    i <- 1
    # stop loop when the ball hits the ground
    while (ball@state[1] >= 0) {
        rowVector[[i]] <- list(state1 = ball@state[1], 
                               state2 = ball@state[2], 
                               state3 = ball@state[3])
        solver <- step(solver)
        ball <- solver@ode
        if (verbose) {
            cat(sprintf("%12f %12f ",  ball@state[1], ball@rate[1] ))
            cat(sprintf("%12f %12f ",  ball@state[2], ball@rate[2] ))
            cat(sprintf("%12f %12f\n", ball@state[3], ball@rate[3] ))
        }
        i <- i + 1
    }
    
    DT <- data.table::rbindlist(rowVector)
    print(ggplot(DT, aes(x = state3, y = state1)) + geom_line(col = "blue"))
    print(ggplot(DT, aes(x = state3, y = state2)) + geom_line(col = "red"))
}


FallingParticleODEApp()
```


