





Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
A documentation of how the program works. This program was proposed and developed in order to help the solution and representation of the multivariable first-order differential equations. The program embeds a Runge-Kutta Fourth order solution Method.
Typology: Study Guides, Projects, Research
1 / 9
This page cannot be seen from the preview
Don't miss anything!
Developed by Hyungho Chris Choi
Documented by Hyungho Chris Choi
This program was proposed and developed in order to help the solution and representation of the multivariable first-order differential equations. The program embeds a Runge-Kutta Fourth order solution Method
The author of this program had inspiration from the Mathematical Modeling and Differential Equations class from the Korea Science Academy. And this program is conversely fit for students looking for a reliable solution software.
Special Thanks to prof. Y.D.Kim for the intellectual aid.
Please read and follow the instructions on https://pypi.org/project/hashbrown/ for proper installation and use.
Overview
The overall system workflow
This documentation will be based around an example of a forced oscillator, to easily describe the workflow.
0. Simplification
Before you look for the solution, the differential equation must be simplified to a simple multivariable first-order differential equation which has the form
x 1 โฒ^ = ๐๐ 1 (๐ก๐ก, ๐ฅ๐ฅ 1 , ๐ฅ๐ฅ 2 , โฆ , ๐ฅ๐ฅ๐๐)
x 2 โฒ^ = ๐๐ 2 (๐ก๐ก, ๐ฅ๐ฅ 1 , ๐ฅ๐ฅ 2 , โฆ , ๐ฅ๐ฅ๐๐)
โฆ
xnโฒ^ = ๐๐๐๐(๐ก๐ก, ๐ฅ๐ฅ 1 , ๐ฅ๐ฅ 2 , โฆ , ๐ฅ๐ฅ๐๐)
The number of equations is irrelevant as long as the equations are given as the form above
For example, consider the forced harmonic equation
mxโฒโฒ^ + bxโฒ^ + kx = ๐น๐น 0 sin (๐ค๐ค๐ก๐ก)
We could simplify this by appointing y = xโฒ and concluding with a series of equations given as
xโฒ^ = ๐ฆ๐ฆ
yโฒ^ = โ
sin (๐ค๐ค๐ก๐ก)
This process must be done by the user, the program can NOT (and should not) handle the simplification. You should also have the initial values ( x 1 (0), ๐ฅ๐ฅ 2 (0) โฆ xn(0) ) Figured out accordingly.
1. Assigning Function Class Variables
Now the coding begins. Before we start, all you need to import is the hashbrown library. The library imports its dependencies in a hierarchy.
**from hashbrown import ***
From the simplified solutions from section 0, we assign [Function] class variables for each equation.
class Function:
def init(self, f, var, name):
f is a python function that governs each equation. var is the number of variables that the function takes (including t) name is the name of this variable. The name parameter is very important, since it will be used in all result handling. Keep in mind, the name โtโ is reserved for hashbrown internal (variable for time).
f could be separately defined and then plugged into the [Function] class constructor.
Following with the example from section 0, the [Function] class variables could be defined as follows
from hashbrown import * b = 1 m = 1 k = 1 F0 = 1 w = 10 def xp(t,x,y): return y def yp(t,x,y): return -(b/m)y - (k/m)x + (F0/m)sin(wt) F1 = Function(xp,3,'Displacement') F2 = Function(yp,3,'Speed')
Make good use of the global variables for now. They will be encapsulated later.
Make sure you match the number of variables with all the functions. Even with functions like xp, we need all three parameters mentioned
We could also get creative (and nonlinear) with the functions: Suppose the force is no longer applied after tf. Then we could define
from hashbrown import * b = 1 m = 1 k = 1 F0 = 1 w = 10 tf = 10 def F(t): if t>=tf: return 0 return F def xp(t,x,y): return y def yp(t,x,y): return -(b/m)y - (k/m)x - (F(t)/m)sin(wt)
3.1. Export Data
There are a number of ways to export data out of the program
.writeCSV(s=1)
This method exports the dataset into the current working directory. Parameter s denotes how much data to actually save. .writeCSV() will save everything, and .writeCSV(10) will save every 10 th^ data point. writeCSV(10) is recommended since the saving of CSV and EXCEL files are a long process
.writeXLSX(s=1)
Same deal with excel. Note that saving the excel file takes much longer than that of CSV. So use this when the datasets are small. Saving to CSV and converting to EXCEL is recommended (Until you have extra knowledge about openpyxl ).
Continuing from section 2, R.writeCSV() saves as follows.
Notice that the names of each variable (defined in Function class) are already in place.
3.3. Graphic representation
There are ways to immediately represent the data graphically. This uses matplotlib.
.writePLOT(subj = None, points = 1000,s=1)
The .writePLOT method grpahs the result in the desired format.
subj governs which variables are graphed. It is a list of tuples containing variable names. The name that denotes time is โtโ. For example, setting subj = [(โtโ,โxโ),(โtโ,โyโ)] draws x-t, y-t graphs in the same graph. .writePLOT also supports 3d plotting. So subj can also contain tuples of length 3. Setting subj = [(โtโ,โxโ,โyโ)] graphs the result on a 3D space. If nothing is given for subj , it graphs everything with respect to time in 2D.
points govern how many points the whole graph is drawn. 1000 is recommended since the rendering could take extensive time. Setting it to 0 overrides the parameters and follows s , which is how many to skip (same as that of .writeCSV ).
Giving more examples from the example mentioned in (2.),
R.writePLOT()
R.writePLOT(subj = [(โDisplacementโ,โSpeedโ)]
R.writePLOT(subj = [(โtโ,โDisplacementโ,โSpeedโ)]
5. Additional Documentation
There are multiple methods and functions that were not covered in the documentation above. Although these features are not the major features, it is powerful in some mathematical and visual aspects.
The full representation of the rk4 functionโs parameters are
rk4(ts, te, step, s, name, ti)
and there are two additional features to this function.
1.Reverse calculation
If ts is greater than te, the function automatically assumes the initial value is actually given for the te and reverse calculates back to ts. So, the rk4 function is actually capable of taking โfinal conditionsโ to calculate the result
2.Midpoint calculation
The same is true with giving โmiddle conditions.โ This is what the parameter ti is for. The parameter denotes the time the initial condition applies. For example, setting ts = 0, te = 10, ti = 5 finds a solution where the given conditions are true a t = 5. Since the process takes two calculations, two computations will take place. (one forward and one reverse)
mapF returns a [Result] class object of a simple time-based function. The parameter f takes a tuple of [Function] class elements to return the result as the value of that function form ts to te and by timestep
step. Since it returns a [Result] class object, it could be represented as shown above in section 4.
The .merge(R) method returns a [Result] class object that merges two instances of results (self, R). If the time ranges are incompatible, the function simply pastes the first or last value as the result representing that time. Also if the timestep between two results are not compatible, It adopts the larger timestep as its own timestep. Although the merging for results are possible between for different timesteps, it is recommended that the one timestep is a multiple of another.
To avoid name collision, the merged values have their original names as prefixes. But any name with โ_โ will not be changed. Here is an example of a merged plot.
6. Legacy
Some functions and methods are no longer used, or a better alternative was introduced with new patches. The documentation for them are written here.
- .animateF(subj = None, scale = 1, tail = 1):
The .animateF method is an old, legacy method that animates the result. This method is kept for version consistency. It has slightly different parameters from .writeANIM :
The scale parameter determines how fast the animation is played. When .animateF was developed, it did not support ratio to realtime. Now, the scale parameter simply translates to timescale = 3scale*.
The stability and computation efficiency has significantly been improved from .animateF to .writeANIM. So, using .writeANIM is strongly recommended. In fact, .animateF is simply translated to:
.writeANIM(subj,scale3,tail)*