How to converge on a value for an iterative function
Question:
`A iterative function I wrote is unable to converge on a value, I believe the function is not updating the last calculated value at the beginning of each new loop and thus not converging and instead calculating only one value each time.
Ive tried the function below, the issue is that for any f input I put it will calculate a subsequent f0 value but it wont repeat the loop with the new value and instead just return f0.`
import numpy as np
Q = 62549.5 #gpm
L = 52800 #ft
a = (100 / 1.10) #Right side of energy balance
Vis = 1.537*10**(-5)
e = 0.0015 # in
f = 0.008
ep = 0.00001
list = np.linspace(0.005, 1, 5)
def friction(f):
convergence = True
while convergence:
D = ((f*L*(Q**2))/(32.15*a))**(1/5)
A = (3.14*(D/12)**2)/4 #ft^2
v = (Q/448.831)/A #ft/s
Re = (v*(D/12))/Vis
f0 = 0.25/(np.log10(e/(3.7*D) + 5.74/(Re**(9/10))))**2
convergence = abs((f0-f)/f0) < ep
f = f0
break
return f0
for f in list:
print(friction(f))
Answers:
Although I’m not 100% on whether the values It spit out for me are correct as I don’t know much about calculating friction as i assume this is doing, this worked when I tried it(working meaning it gave different values when input was changed but same values for repeated inputs). you could try removing the break. I’m assuming that you may be breaking out of the loop before a convergence is met. you can add an if statement and set convergence to false when its met. or if you prefer to use break, you can use it instead in the if statement. Here’s how I ran it, if I got the idea wrong I apologize.
import numpy as np
Q = 62549.5 # gpm
L = 52800 # ft
a = (100 / 1.10) # Right side of energy balance
Vis = 1.537 * 10 ** (-5)
e = 0.0015 # in
f = 0.008
ep = 0.00001
def friction(f):
convergence = True
while convergence:
D = ((f * L * (Q ** 2)) / (32.15 * a)) ** (1 / 5)
A = (3.14 * (D / 12) ** 2) / 4 # ft^2
v = (Q / 448.831) / A # ft/s
Re = (v * (D / 12)) / Vis
f0 = 0.25 / (np.log10(e / (3.7 * D) + 5.74 / (Re ** (9 / 10)))) ** 2
f = f0
# I used an if statement so that when satisfied
# it sets convergence to false and loop ends
if abs((f0 - f) / f0) < ep:
convergence = False # This could be set to break, to
# immediately break loop if preferred
return f0
if __name__ == '__main__':
inPut = 0.008 # This is how I was changed input variable
print(friction(inPut))
`A iterative function I wrote is unable to converge on a value, I believe the function is not updating the last calculated value at the beginning of each new loop and thus not converging and instead calculating only one value each time.
Ive tried the function below, the issue is that for any f input I put it will calculate a subsequent f0 value but it wont repeat the loop with the new value and instead just return f0.`
import numpy as np
Q = 62549.5 #gpm
L = 52800 #ft
a = (100 / 1.10) #Right side of energy balance
Vis = 1.537*10**(-5)
e = 0.0015 # in
f = 0.008
ep = 0.00001
list = np.linspace(0.005, 1, 5)
def friction(f):
convergence = True
while convergence:
D = ((f*L*(Q**2))/(32.15*a))**(1/5)
A = (3.14*(D/12)**2)/4 #ft^2
v = (Q/448.831)/A #ft/s
Re = (v*(D/12))/Vis
f0 = 0.25/(np.log10(e/(3.7*D) + 5.74/(Re**(9/10))))**2
convergence = abs((f0-f)/f0) < ep
f = f0
break
return f0
for f in list:
print(friction(f))
Although I’m not 100% on whether the values It spit out for me are correct as I don’t know much about calculating friction as i assume this is doing, this worked when I tried it(working meaning it gave different values when input was changed but same values for repeated inputs). you could try removing the break. I’m assuming that you may be breaking out of the loop before a convergence is met. you can add an if statement and set convergence to false when its met. or if you prefer to use break, you can use it instead in the if statement. Here’s how I ran it, if I got the idea wrong I apologize.
import numpy as np
Q = 62549.5 # gpm
L = 52800 # ft
a = (100 / 1.10) # Right side of energy balance
Vis = 1.537 * 10 ** (-5)
e = 0.0015 # in
f = 0.008
ep = 0.00001
def friction(f):
convergence = True
while convergence:
D = ((f * L * (Q ** 2)) / (32.15 * a)) ** (1 / 5)
A = (3.14 * (D / 12) ** 2) / 4 # ft^2
v = (Q / 448.831) / A # ft/s
Re = (v * (D / 12)) / Vis
f0 = 0.25 / (np.log10(e / (3.7 * D) + 5.74 / (Re ** (9 / 10)))) ** 2
f = f0
# I used an if statement so that when satisfied
# it sets convergence to false and loop ends
if abs((f0 - f) / f0) < ep:
convergence = False # This could be set to break, to
# immediately break loop if preferred
return f0
if __name__ == '__main__':
inPut = 0.008 # This is how I was changed input variable
print(friction(inPut))