# 1D Linear Convection Python

1. Apr 15, 2010

### Jonny6001

Hi, I have a pseudocode I would like to try and implement and understand the programming of it in python. The physics and maths of the case is no problem, but the implementation of the code in Python is something I'm not familiar with.

The problem is a simple 1D linear convection using finite differences.

I have Python 2.6, Numpy and matplotlib.

I have attached the pseudocode as an image file. I can more or less input this in a form that Python understands but I'm not quite sure how to start off the loops with a value of 'i' and maybe I need to add and increment to 'i' once it has done the loop once?
I mean for a start, I should be able to run the first for loop which says for values of i between 0.5 and 1, the value of 'ui' will be 2, everywhere else ui=1.
Then plot the results in matplotlib.

I have tried this and I get a blank ploot with x axis around the 20 and y axis around 1, so the axes are not far off but the increment of the loop is something I'm not getting. By the way, this is my own interest, not a homework or assignment, so there isn't anyone I can ask the most basic quiestions to.

Thanks a lot for your time, I'm sure if I can be shown how to make a start then it will slowly click in to place.

#### Attached Files:

• ###### Untitled.jpg
File size:
18.7 KB
Views:
184
2. Apr 15, 2010

### Staff: Mentor

Can you please enter your code in your post, not as an image? I can either look at your code or type a response, but not both.

3. Apr 16, 2010

### Jonny6001

nx=20, nt=50
dt=0.01, c=1
dx=2/(nx-1)

for i in (1,nx):
if 0.5<=x(i)<=1:
u(i)=2
else:
u(i)=1
end
end

for it in (1,nt):
un=u
for i in (2,nx-1):
u(i)=un(i)-c*dt/dx(un(i)-un(i-1))
end
end

Sorry about that, it didn't cross my mind.

Thank you

4. Apr 16, 2010

### Staff: Mentor

5. Apr 16, 2010

### Jonny6001

Hi, thanks for taking the time to reply. I am pretty sure that in python, you can do 0.5<=x(i)<=1, I have seen a few documents and it doesn't complain about the syntax.

The issue I think is the loop doesn't seem to be running 'i' between the values in the brackets.

The code below, I see it as being; increment 'i' between 1 and 'nx', if i<10, put y=10, if y==10 put y=20, if y>10 put y=50

So if I was to plot (i,y) I was expecting to see a graph with 'i' along the x axis ranging from 1-20, and the corresponding values of 'y' so 'y' would be 10, then when i==10, y goes up to 20 then its 50 for the remaining values of 'i'.

For some reason the plot axis goes to the region of the final value as it it wasn't running and recording the whole loop.

I won't paste the code in this post as its so short, you can see the code and the graph output in the attached image.

I recall ages ago when I did more things like this, there was a commond at the end of the loop such as i++ or something to add 1 to the value of i, perhaps Python requires something similar?

I'm sorry if my questions are a little boring but I really want to get heavily in to Scientific Programming and Mathematical Modelling.
By the way, the pseudocode I wrote earlier is a way of approximating a partial differential equation describing linear convection, using finite difference method.

Thanks so much for taking the time to bother with this.

#### Attached Files:

• ###### Untitled1.jpg
File size:
25.5 KB
Views:
114
6. Apr 16, 2010

### Staff: Mentor

Nor does C, which is even worse. IOW, it's not a syntax error in C, so you don't hear from the compiler about it, but it is a semantic error.

Here's an example that shows how it works in C and might work in python, using a slightly simpler example.

result = 0.5 <= x <= 1

Suppose x has been set to .75. The expression 0.5 <= x is true, so the value of the expression (0.5 <= x) is 1. 1 <= 1 is true, so the overall expression has a value of 1, which is what is stored in result. That is the expected behavior.

Now suppose x has been set to 1.5. The expression 0.5 <= x is true again, so the value of the expression (0.5 <= x) is 1. 1 <= 1 is true, so the overall expression has a value of 1, which is what is stored in result. This is not what was expected.

One more. Suppose x has been set to 0.0. The expression 0.5 <= x is false this time, so the value of the expression (0.5 <= x) is 0. 0 <= 1 is true, so the overall expression has a value of 1, which is what is stored in result. This is not what was expected.

In other words, no matter what value x is, the expression 0.5 <= x <= 1 always comes out true - at least in C, and I would be very surprised if python behaves any differently.

I'll take a look at your other comments in a little while.

7. Apr 16, 2010

### Staff: Mentor

For matlab's plot function, the two arguments have to be arrays, and in your code they don't seem to be arrays.

Here's a python tutorial that I found. Take a look at section 4.2, which talks about for loops. You don't need to increment your loop counter.

Also, I looked at the section on logical conditions and didn't see anything to contradict what I said in my previous reply about what 0.5 <= x(i) <= 2 would evaluate as. I still believe this always evaluates to 1 (or true).
http://docs.python.org/tutorial/

8. Apr 16, 2010

### shoehorn

Python is a very different language to C! Although Python (the standard version, at least) is written in C, the style, intent, and scope of the language is extremely unlike what you might be used to in C.

For what it's worth, the change in mindset that I needed to undergo when I first learned Python was quite painful; I had a solid C/C++ background and many Pythonic ways of doing things just seemed wrong. With the benefit of hindsight though, it's clear that Python gives rise to a much more natural style of expression than C/C++.

You can have several arithmetic tests as conditions to an if statement in Python. For instance, consider the following situation where I define a Python list which contains the integers from one to ten, inclusive.

Code (Text):

# Define a list containing the integers from 1 to 10.
li = range(1, 11)

# Print out whether the numbers in the list are between 6 and 9, inclusive.
for x in li:
if 6 <= x <= 9:
print x
else:
print 'FAIL!'

The output from this is as one would expect:

Code (Text):

FAIL!
FAIL!
FAIL!
FAIL!
FAIL!
6
7
8
9
FAIL!

Last edited: Apr 16, 2010
9. Apr 17, 2010

### Staff: Mentor

Thanks, that's good to know.

10. Apr 17, 2010

### Jonny6001

Ok, I have tried to take a step back to better understand, it's not enough to be good at the mathematics I'm trying to express in a program, I understand that now.

I have attached something I wrote to see how the loops work and how the plot function in matplotlib works.
It appears that the for loop runs ok and increments up to value of 'nx', and as you can see I have an array of 'i' and corresponding 'y' values. I thought that if I plotted (i,y) this should plot the whole range, but it seems it sort of plots the last value of (i,y) in the array?

Does anyone know how I should plot the values, so between 5<=i<=10, the value of 'y' should be 2, everywhere else it's 1.

Thanks a lot.

#### Attached Files:

• ###### Untitled3.jpg
File size:
23.6 KB
Views:
102
11. Apr 17, 2010

### shoehorn

Instead of attaching your code as a jpeg, it's much better to use the [ code ] [ /code ] tags (although without the spaces inside the brackets!). For instance, the code you've given in your last attachment is as follows.

Code (Text):

import matplotlib.pyplot as plt

nx = range(1, 21)

for i in nx:
if 5 <= i <= 10:

y = 2
print i, y

else:

y = 1
print i, y

plt.plot(i, y)
plt.show()

The intent behind what you're doing is almost correct, but the implementation is slightly wrong. In each step of the for loop you run an if..else test. The condition for the test is that $5 \le i \le 10$; if this is TRUE, you define $y=2$ and print the values of $i$ and $y$ to standard output. You then go on to the next stage in the loop and run the test again. The important thing to note is that when you go to the next step in the loop you are (i) not storing the values of $i$ and $y$ you had in the previous step, and (ii) you are rewriting the old values with new ones.

What you really want to do is to store the appropriate values somewhere so that they can be plotted later on. Here's a simple example of how this can be achieved.

Code (Text):

import matplotlib.pyplot as plt

nx = range(1, 21)

# Define lists to hold the values of i and y
iList = []
yList = []

# Now run through the loop.
for i in nx:

# Add the current value of i to the iList
iList.append(i)

if 5 <= i <= 10:

# Append 2 to the yList
yList.append(2)

else:

# Append 1 to the yList
yList.append(1)

# Now print out the contents of the lists as ordered pairs.
for elem in range(len(iList)):
print '(%g, %g)' % (iList[elem], yList[elem])

# Now plot the data contained in the lists. Note that you can pass other options
# to the plot command to give you, for example, a plot of just the data points
# with no interpolating line between them. The relevant command for this would
# be something of the form:
# plt.plot(iList, yList, 'bo')
plt.plot(iList, yList)
plt.show()

This results in the pairs of numbers being printed to standard output and will give you the following plot.

[PLAIN]http://img686.imageshack.us/img686/8480/plotx.png [Broken]

It's possible to do this more elegantly, but it's good to concentrate on getting code working before you attempt to make it beautiful.

Last edited by a moderator: May 4, 2017
12. Apr 17, 2010

### Jonny6001

Brilliant, thanks a lot for the reply, I clearly see how this is achieved now.

I will try and get the methodology working in a more practical way, to try and plot the values of the initial case.
Have you any experience in finite difference methods in Python, such as Burgers Equation, Convection equation or what I eventually want to build up to, Navier Stokes.