When using Autolev to solve dynamics problems, you can use it to produce C code that will run the numerical analysis in order to solve the ODE's. The typical process is to compile the resulting C code in whatever compiler you have handy and then run the compiled version. By using Ch you can not only skip the compile step, but you can also get output in the form of plots as you run the code instead of having to postprocess some output files with Excel or some other plotting utility.
Running a C program created by Autolev in Ch is the same as running any other program. You simply start Ch and type the file name, given that you're in the same directory. Therefore the majority of this web page will describe the steps necessary to use the plotting capabilities of Ch to get immediate output instead of going throught the post processing procedures. It is assumed that, if you're looking to use the code shown on this page, you have a basic working knowledge of both C and Ch. Any questions on specific code that was used can be directed to me via email.
The example code that's used here is some that I wrote while taking Multibody Dynamics, MAE 223. Therefore a lot of the specific variable names that I used can be changed depending on what you would like them to be. Also, several of the variable need to be placed in certain spots in the C file. I will try to point out where and show some of the Autolev created code to help with this, but it would probably be helpful to have your c file open to compare with pieces of code I'll show.
Here is a list of the necessary steps to create output plots directly in the Autolev C file.
Here are several suggestions that can make life easier before you begin modifying your code. These are not necessay, but I found them useful.
First is to make a separate file that has your additional code so that it can be pasted into the program instead of typed in as you go. This is handy in case you discover a small error in your Autolev program and need to create a new C file. If the changes you've made aren't saved some where, you will have to rewrite them because Autolev will overwrite the old program if you didn't move it. This also makes it easier to modify subsequent programs.
Second is to put all of your addtional code together in blocks labeled with comments before and after. If you have errors when running program or if you need to make small changes to your code, this makes it much easier to wade through the large Autolev program and isolate your code from the Autolev created portion.
Third, save plots to external files. When running the program it would be fairly common to run it several times with different initial conditions or time frames. If the plots are saved externally, then it becomes very easy to move all of the output to a separate folder and rerun the program thereby saving both sets of data.
To add plotting and numerical arrays to your program you only need to add the chplot and array header files
#include <ctype.h> #include <math.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* Header Files Added */ #include <array.h> #include <chplot.h> /* Header Files Added */
For creating the array used in plotting, you have to define the array size.
This can be done directly in the declartion statement for the array, but if you want to
run the program over a different time span or change the time step, the array
sizes will have to change. By using a macro to define the array size, you'll
only have to change the size in one place. Add a #define
statements to set the number of points in the arrays.
#define _NAN 9.99999999999999E+305 /* Constant Definitions Added */ #define POINTS 51 // Number of data points /* Constant Definitions Added */
There are two types of variables needed to do the plotting, objects of the
plot class and computational arrays. The exact number of each one will depend
on how many plots you'd like to create. Obviously you'll need one plot object
for each plot. Don't forget that you can put more than one data set on a
plot and even create subplots if you like. As for the arrays, you need one
for time and one additional one for each data set. In this code, there are
four plots being created, one each for θ, ω, α, and torque.
Notice that for each plot there are actually four sets of data. Each variable
is a [4] × [something] array. This makes it extremely simple to plot all
four set on one graph as I'll show in the plotting seciton.
Also note the count
variable. This will become necessary when entering
data into your arrays in the output section as a way of indexing
through the elements of the arrays. You can see here how the number of data points
for each one was set with the maro POINTS
.
double Pi,DEGtoRAD,RADtoDEG,z[189],... /* variables added */ class CPlot plot1; class CPlot plot2; class CPlot plot3; class CPlot plot4; int count = 0; double time[POINTS]; double angles[4][POINTS]; double angvel[4][POINTS]; double alpha[4][POINTS]; double torques[4][POINTS]; /* variables added */
In order to create the plots with Ch, the output files that Autolev writes to need
to be closed. It is important to do this in the correct place of you will mess up
the program. Whereas all the previous code was added before any function definitions,
this code is added to the main
function.
The last thing the program does is write several
messages to the screen to telling you about the various files. Then there's the
return 0;
statement. Close the files after the program writes these
messages to the screen. This is done with the fclose
statement as show
below. Autolev uses the array Fptr[]
to point to all the output files.
The number of files you have will depend on the number of output
statements in your Autolev code.
You can also look for the comment /* Open input and output files */
. The
for
loop just after this will show how many files are being opened.
Just add the necessary number of close statements.
/* Inform user of input and output filename(s) */ puts( "\n Input is in the file punt.in" ); puts( "\n Output is in the file(s) punt.i (i=1, ..., 9)" ); puts( "\n The output quantities and associated "files are listed in file punt.dir\n" ); /* Added to Close file and plot results */ fclose(Fptr[1]); fclose(Fptr[2]); etc... /* Added to Close file and plot results */ return 0; }
Where the etc...
just means to add the number you need. Note that I didn't
close the Fptr[0]
file. This is the input file and I found closing it to
be unecessary, but at this point the program doesn't need the file any more so closing
it shouldn't hurt.
After you close the output files you can create the plots. I set up the program to save the plots as files and to output them directly to the screen for immediate feedback. Below are the commands used for one plot. They can be repeated as many times as necessary.
/* Inform user of input and output filename(s) */ puts( "\n Input is in the file punt.in" ); puts( "\n Output is in the file(s) punt.i (i=1, ..., 9)" ); puts( "\n The output quantities and associated files "are listed in file punt.dir\n" ); /* Added to Close file and plot results */ fclose(Fptr[1]); fclose(Fptr[2]); etc... plotxy(time, angles, "Angles", "t", "angle"); plotxy(time, angles, "Angles", "t (s)", "Angle (deg)", &plot1); plot1.legend("tang ", 0); plot1.legend("lang1", 1); plot1.legend("fang ", 2); plot1.legend("lang2", 3); plot1.legendLocation(0.2,240); plot1.outputType(PLOT_OUTPUTTYPE_FILE, "png color", "plot_1.png"); plot1.plotting(); /* Added to Close file and plot results */ return 0; }
The first plotxy
will give you the quick sceen output without using
the CPlot object. The rest of the commands are for creating the plot
with the CPlot object and then saving to the file. The nice part about using
the plotting object is it allows you to do more with the layout. In this program, the
plots are saved as .png
files. I've found that the plots look nicer if saved as
.eps
files, but you will need a program that reads them.
To get the data into the arrays you need to go to the output
function in program. This is where the program writes to its output files.
At the end of the fuction, there is at least one writef
statement.
After this, assign the output to the arrays that
you defined. This is where the count
variable gets used.
Having initialized count to 0 previously,
count
will be the index for the array element that the data is saved to.
Autolev uses the T
variable for time.
The rest of the variables are the ones that
you defined in Autolev. Don't forget at the end of the assignment statements
to increment the count
variable to continue throught the arrays.
/* Write output to screen and to output file(s) */ writef(stdout, " %- 14.6E", T,... writef(Fptr[1]," %- 14.6E", T,... /* Added arrays for plotting */ time[count] = T; angles[0][count] = (TANG*RADtoDEG); angles[1][count] = (LANG1*RADtoDEG); angles[2][count] = (FANG*RADtoDEG); angles[3][count] = (LANG2*RADtoDEG); angvel[0][count] = U1; angvel[1][count] = U2; angvel[2][count] = U3; angvel[3][count] = U4; alpha[0][count] = U1p; alpha[1][count] = U2p; alpha[2][count] = U3p; alpha[3][count] = U4p; torques[0][count] = TA; torques[1][count] = TH; torques[2][count] = TK1; torques[3][count] = TK2; count++; /* Added arrays for plotting */
Here I've data being saved to all the arrays that I set up in the variables section. With this you should be able to get plots for all your significant data from within your Autolev created C program.
If your just trying out your program for the first time and are not sure if you need to make corrections, you might want to look at the output plots without having to define new variables inside the program. Here is a quick way to use the plotting capabilities of Ch without making as many changes. You can modify the output files that the program writes so that Ch will read them and use a separate Ch program to plot the data from the files. The main disadvantage to this method is that Ch won't plot more than one curve this way. If your output file has multiple columns of data Ch will use the first for the X values, the second for the Y, and ignore the rest. Still, it can be useful for simpler models.
First in main
,
locate section commented /* Write heading(s) to output file(s) */
.
The fprintf
statements must be modifies so that Ch will see these
headings as comments. This can be done by placing a pound sign "#
"
where the beginning of each line will be in the resulting output file.
Then these files can be plotted with another program such as the one below.
Notice the inputs to the plots are the modified data files. Here, I had run the
program twice with different initial conditions and renamed the output file
after each run. That allowed me to plot two curves simultaneously, but each file
has only two columns.
The modified code from the Autolev C program.
/* Write heading(s) to output file(s) */ fprintf(stdout, " FILE: p-13-10.1\n\n *** %s\n\n", string); fprintf(stdout, " T Q2\n" " (UNITS) (DEG)\n\n" ); fprintf(Fptr[1], "# FILE: p-13-10.1\n#\n# *** %s#\n#\n", string); fprintf(Fptr[1], "# T Q2\n" "# (UNITS) (DEG)\n#\n" ); /* # at each line of heading */
The program used to plot the files.
/* p-13-10-plotab.ch */ /* Plotting the output of p-13-10.ch for Dynamics */ /* Initial values: q1(0) = 45 & q2(0) = 1, 0.5 */ #include <stdio.h> #include <chplot.h> int main() { class CPlot plot; char *title = "q2 vs. t w/ q1(0) = 45"; char *xlabel = "time (s)"; char *ylabel = "q2 (deg)"; plot.dataFile("p-13-10.1(a)"); /* input file */ plot.dataFile("p-13-10.1(b)"); /* input file */ plot.legend("q2(0) = 1.0", 0); plot.legend("q2(0) = 0.5", 1); plot.legendLocation(9,1.5); plot.title(title); plot.label(PLOT_AXIS_X, xlabel); plot.label(PLOT_AXIS_Y, ylabel); plot.plotting(); plot.outputType(PLOT_OUTPUTTYPE_FILE, "png color", "plot.png"); plot.plotting(); return 0; }
If you'd like to down load the code fragments that I included on the page, but can not get them directly from the page, here is a text file with all the code included.
Get the Code fragments in this text file
On this page, there's an example problem that with the code from Autolev, the original Autolev C program, the modified C program, and all the associated output. It is a fairly simple problem that you should be able to work through easily
Hopefully this information has been helpful. If you have any
questions or comments they can be directed to Matt Campbell
whose email can be found on the
MAE Grauduate Student Directory
Autolev™ is the property of OnLine Dynamics, Inc.