Python Forum
Inflow watertank before outward flow starts
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Inflow watertank before outward flow starts
#1
This is an exercise i'm working with, and I'm wondering if anyone have the chance to help me with this.

Problem description:

Water towers are among the simplest yet ingenious methods to distribute water having been in use in some form since ancient times. More than simply calculating capacity or flow rate however, we can model how a tank can be filled and emptied. We will model a scaled down version of this problem. In our model, our water tank will have a single water flow inward, and a single flow outward and be perfectly cylindrical.

where:

fin – the flow-rate in (cubic meters per second)
fout – the flow rate out ( cubic meters per second )
r – the radius of the tower (meters)
H – The height of the tower (meters)
h – The height of the current water-level (meters)

You are tasked to write a function called ‘trackFlow’ which when given some initial conditions iteratively simulates the contents of the tower. By ‘iteratively’ we mean you will update the volume of water in the tank repeatedly over numerous time-intervals.


More specifically, the tank will be filled up until some time (topen) at which point the outward flow is activated (instantly).

Your function will accept the following arguments (in the following order):

fin – The flow-rate in ( cubic meters per second )
fout – The flow rate out ( cubic meters per second )
r – The radius of the tower (meters)
H – The height of the tower (meters)
h – The height of the initial water-level (meters)
tmax – The maximum time allowed to simulate the system(seconds)
topen – The time when the outwards flow opens (seconds)
Your calculations should continue until either t > tmax, h > H or h < 0 whichever comes first.

Assume

The time-step = 0.1 sec
The density of water = 1000 Kg/m3
The inward flow is open at t = 0.0 sec
Your function should return the following

A list of volume values (in cubic meters )
A list of water-height values (in meters)
A list of time-stamps at which the values were calculated (in seconds)
Note: Do not print the lists in a formatted manner, simply return them at the end of calculations

All values during the computation must be rounded to 10 decimal places to avoid approximation problem. See details at

https://docs.python.org/2/tutorial/floatingpoint.html


In addition, all output values are to be rounded to 2 decimal places when they are appended to the output result-arrays.

See the round() function for more information.


Your submission will be tested against a sample solution with numerous test-cases in addition to those presented below.

Sample testing data:


testFlow(1, 1, 1, 10, 0, 3, 1) #Steady-state after 1s

Volumes = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

Heights = [0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32]

Times = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0]

testFlow(1, 5, 1, 10, 0, 5, 2) #Decreases until tank is empty

Volumes = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 1.6, 1.2, 0.8, 0.4]

Heights = [0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.35, 0.38, 0.41, 0.45, 0.48, 0.51, 0.54, 0.57, 0.6, 0.64, 0.51, 0.38, 0.25, 0.13]

Times = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4]

testFlow(1, 0.5, 1, 10, 0, 3, 1) #Increases after out-flow is open to maximum time

Volumes = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2.0]

Heights = 0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.33, 0.35, 0.37, 0.38, 0.4, 0.41, 0.43, 0.45, 0.46, 0.48, 0.49, 0.51, 0.53, 0.54, 0.56, 0.57, 0.59, 0.6, 0.62, 0.64]

Times = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0]




My code is:
import math
"""f_in = int()
f_out = int()
r = int()
H = int()
h = int()
t_max = int()
t_open = int()"""

def trackFlow(f_in, f_out, r, H, h, t_max, t_open): #Function with input values
t = 0
pi = math.pi
Volume = [] #Making list for volumes
Heights = [] #Making list for heights
Times = [] #Making list for times
t = 0
v_old = pi*r**2*h #Defining the start volume of water.
v_total = pi*r**2*H #Defining the total volume in the tank
Heights.append(h)
Volume.append(v_old)
Times.append(0)

while t < t_open: #Make a loop for filling up the tank
v_new = v_old + (f_in*(0.1)) #An equation for the volume of water after time, t.
t+=0.1 #Get the loop for checking for t0, t1+0.1, t2+0.1
v_old = v_new #v_new becomes v_old when the loop checks for next t.
h_new = h + ((f_in*(t))/(pi*r**2)) #The height after time, t, before tank is filled
Heights.append(round(h_new,2)) #Adding heights before tank is filled
Times.append(round(t,2)) #Adding time-stamps
Volume.append(round(v_new,2)) #Adding the volume in the list Volume

if t > t_open: #Make an if statement to break the loop if the
break #water volume gets bigger than tank volume.
elif h > H:
break
elif h < 0:
break
else:
continue


while t_open < t < t_max: #Making a loop for when the outward flow has started.
v_new = v_old + ((f_in - f_out)*(t_max-t)) #Equation for water volume after time t, f_out has been taken into consideration.
t = t_open #t counts from t_open
t+=0.1 #And checking for each value in the interval 0.1
h_new = h + (((f_in - f_out)*(t_max-t))/(pi*r**2)) #Equation for water height after time t, f_out has been taken into consideration.
Volume.append(round(v_new,2)) #Adding heights after the outward flow has started
Heights.append(round(h_new,2)) #Adding heights after the outward flow has started
Times.append(round(t,2)) #Adding time-stamps, still supposed to still add 0.1

if t > t_max: #Make an if statement to break the loop if the
break
elif h > H:
break
elif h < 0:
break
else:
continue


"""Volume = (round(Volume,2))
Heights = (round(Heights,2))
Times = (round(Times,2))"""



print(Volume) #Print list with volumes
print(Heights) #Print list with heights
print(Times) #Print list with time-stamps

I think my problem is I don't get the second loop to work and I need some help.
I appreciate all assistance and guidance You may support me with.
Reply
#2
Please put your code in Python code tags and errors in error tags if they show up. You can find help here.
If there are no errors you can show the results you get vs. the desired result.
Reply
#3
"""
fin – The flow-rate in ( cubic meters per second )
fout – The flow rate out ( cubic meters  per second )
r – The radius of the tower (meters)
H – The height of the tower (meters)
h – The height of the initial water-level (meters)
tmax – The maximum time allowed to simulate the system(seconds)
topen – The time when the outwards flow opens (seconds)

V_total = pi*r^2*H
V_new = Vold + (fin-fout)*changein t
h_new = hold + ((fin-fout)*change in t)/(pi*r^2))
"""
import math

def trackFlow(f_in, f_out, r, H, h, t_max, t_open):      #Function with input values
    t = 0
    pi = math.pi
    Volume = []                                          #Making list for volumes
    Heights = []                                         #Making list for heights
    Times = []                                           #Making list for times
    t = 0
    v_old = pi*r**2*h                                    #Defining the start volume of water.
    v_total = pi*r**2*H                                  #Defining the total volume in the tank
    Heights.append(h)
    Volume.append(v_old)
    Times.append(0)
    
    while t < t_open:                                    #Make a loop for filling up the tank
        v_new = v_old + (f_in*(0.1))                     #An equation for the volume of water after time, t.
        t+=0.1                                           #Get the loop for checking for t0, t1+0.1, t2+0.1
        v_old = v_new                                    #v_new becomes v_old when the loop checks for next t.
        h_new = h + ((f_in*(t))/(pi*r**2))               #The height after time, t, before tank is filled
        Heights.append(round(h_new,2))                   #Adding heights before tank is filled
        Times.append(round(t,2))                         #Adding time-stamps
        Volume.append(round(v_new,2))                    #Adding the volume in the list Volume
     
        if t > t_open:                                   #Make an if statement to break the loop if the 
            break                                        #water volume gets bigger than tank volume.
        elif h > H:
            break
        elif h < 0:
            break   
        else:
            continue
        
    
        while t_open < t < t_max:                                 #Making a loop for when the outward flow has started.
            v_new = v_old + ((f_in - f_out)*(t_max-t))            #Equation for water volume after time t, f_out has been taken into consideration.
            t = t_open                                            #t counts from t_open
            t+=0.1                                                #And checking for each value in the interval 0.1
            h_new = h + (((f_in - f_out)*(t_max-t))/(pi*r**2))    #Equation for water height after time t, f_out has been taken into consideration.
            Volume.append(round(v_new,2))                         #Adding heights after the outward flow has started
            Heights.append(round(h_new,2))                        #Adding heights after the outward flow has started
            Times.append(round(t,2))                              #Adding time-stamps, still supposed to still add 0.1        
        
            if t > t_max:                                         #Make an if statement to break the loop if the 
                break                                             
            elif h > H:
                break
            elif h < 0:
                break   
            else:
                continue
    
          
    
    print(Volume)                                 #Print list with volumes
    print(Heights)                                #Print list with heights
    print(Times)                                  #Print list with time-stamps
When inserting the first test values trackFlow(1, 1, 1, 10, 0, 3, 1), I'm supposed to get;
Volumes = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

Heights = [0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32]

Times = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0]

But I get;
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1]
[0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.35]
[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1]
Reply
#4
I rewrited the code to;
import math
def trackFlow(f_in, f_out, r, H, h, t_max, t_open):      #Function with input values
    t = 0
    pi = math.pi
    Volume = []                                          #Making list for volumes
    Heights = []                                         #Making list for heights
    Times = []                                           #Making list for times
    v_old = round(pi*r**2*h,10)                          #Defining the start volume of water.
    v_total = round(pi*r**2*H,10)                        #Defining the total volume in the tank
    Heights.append(h)
    Volume.append(v_old)
    Times.append(0)
    
    while t < t_max:                                    #Make a loop for filling up the tank
        t += 0.1
                
        if t > t_open or h > H or h < 0:                 #Make an if statement to break the loop if the 
            break                                       #water volume gets bigger than tank volume.
           
        

        if t < t_open:
            v_new = round(v_old + (f_in*(0.1)),10)           #An equation for the volume of water after time, t.
            v_old = v_new                                    #v_new becomes v_old when the loop checks for next t.
            h_new = round(h + ((f_in*(t))/(pi*r**2)),10)     #The height after time, t, before tank is filled
            Heights.append(round(h_new,2))                   #Adding heights before tank is filled
            Times.append(round(t,2))                         #Adding time-stamps
            Volume.append(round(v_new,2))                    #Adding the volume in the list Volume
            
            

        else:
            t = t_open                                                      #t counts from t_open
            v_new = round(v_old + ((f_in - f_out)*(t_max-t)),10)            #Equation for water volume after time t, f_out has been taken into consideration.
            h_new = round(h + (((f_in - f_out)*(t_max-t))/(pi*r**2)),10)    #Equation for water height after time t, f_out has been taken into consideration.
            Volume.append(round(v_new,2))                                   #Adding heights after the outward flow has started
            Heights.append(round(h_new,2))                                  #Adding heights after the outward flow has started
            Times.append(round(t,2))                                        #Adding time-stamps, still supposed to still add 0.1        
        
            if t > t_max:                                                   #Make an if statement to break the loop if the 
                break                                             
            elif h > H:
                break
            elif h < 0:
                break   
            
    
    
    
    print(Volume)                                 #Print list with volumes
    print(Heights)                                #Print list with heights
    print(Times)                                  #Print list with time-stamps
When I run the script trackFlow(1, 1, 1, 10, 0, 3, 1), I get:

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
[0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32]
[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

I'm supposed to get:
Volumes = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

Heights = [0, 0.03, 0.06, 0.1, 0.13, 0.16, 0.19, 0.22, 0.25, 0.29, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32]

Times = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0]

So I guess there's something wrong with my conditions of breaking the loop, because it breaks to early.
Reply
#5
This happens because your functions reaches the break on line 40:
if t > t_open:
    break
At that point:
t > t_open
1.0999999999999999 > 1

If it is of help, I investigated this with debugger built into PyCharm IDE, very handy!
Otherwise you can simply place some print statements to see values of meaningful variables as the program executes. That way it is way easier to find where the problem is, rather than guessing :)
Reply
#6
So the function doesn't count the "else" statement. Should I have a nested if statement at line 29 or something?
Reply
#7
Sorry it was a mistake, I looked at the code and line numbers too quickly.
The code reaches "break" in line 18, but the reason (condition) is same as one pointed out in my previous post.

        if t > t_open or h > H or h < 0:                 #Make an if statement to break the loop if the 
            break                                       #water volume gets bigger than tank volume.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Checking if string starts the same but end differently using re module ranbarr 1 1,778 May-20-2021, 06:23 PM
Last Post: Gribouillis
  nested while loop flow help Ponamis 4 3,116 Nov-02-2018, 11:22 PM
Last Post: Ponamis

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020