Python Forum

Full Version: Return values for use outside of function
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all,

I have written a function which contains a loop which gradually builds a displacement vector. I would like to plot this generated displacement vector against time once the loop has completed the calculation of displacement for all time steps.

# Set constants

tvector = t # tVector is an array holding the time vector
f1vector = 0
f2vector = F2
f3vector = F3
xi = 0.025
omega_n = OmegaC
omega_d = OmegaC*((1-0.025**2)**0.5)
k = modalK[0,0]
delta_t = t[1]-t[0]
u_0 = 0
v_0 = 0
n = 0

#Function to calculate displacement from a time and force vector

def calculateResponse(tvector, f2vector, f3vector):
    
	# Compute constants A1-D1 (captures dynamic characteristics of the system)
    A = math.e**(-xi*omega_n*delta_t)*((xi/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t)+np.cos(omega_d*delta_t))
    B = math.e**(-xi*omega_n*delta_t)*((1/omega_d*np.sin(omega_d*delta_t)))
    C = (1/k)*(((2*xi)/(omega_n*delta_t)) + math.e**(-xi*omega_n*delta_t)*((((1-2*(xi**2))/(omega_d*delta_t))-(xi/(math.sqrt(1-(xi**2)))))*math.sin(omega_d*delta_t)-(1+((2*xi)/(omega_n*delta_t)))*np.cos(omega_d*delta_t)))
    D = (1/k)*(1-((2*xi)/(omega_n*delta_t))+math.e**(-xi*omega_n*delta_t)*(((2*(xi**2)-1)/(omega_d*delta_t))*np.sin(omega_d*delta_t)+((2*xi)/(omega_n*delta_t))*np.cos(omega_d*delta_t)))
    A1 = -math.e**(-xi*omega_n*delta_t)*((omega_n/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t))
    B1 = math.e**(-xi*omega_n*delta_t)*(np.cos(omega_d*delta_t)-((xi)/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t))
    C1 =(1/k)*(-(1/delta_t)+math.e**(-xi*omega_n*delta_t)*((((omega_n)/(math.sqrt(1-(xi**2))))+((xi)/(delta_t*math.sqrt(1-(xi**2)))))*np.sin(omega_d*delta_t)+(1/delta_t)*np.cos(omega_d*delta_t)))
    D1 =(1/k)*((1/delta_t)-(math.e**(-xi*omega_n*delta_t)/delta_t)*((xi/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t)+np.cos(omega_d*delta_t))) 

    u_n = u_0

    v_n = v_0

    uVector = [u_n]

    vVector = [v_n]
    
    print (uVector)
    
    for n, timestep in enumerate(tvector):

    # Extract the force values at the beginning and end of this timestep

        F_n = f1vector + (0.00313418*f2vector[n]) + (0.00505446*f3vector[n])
        #print (n)
        #print (F_n)
        
        if n == (len(tvector)) - 1 :
            F_n_1 = F_n
            #print (F_n_1)
                       
        else: 
            
            F_n_1 = f1vector + (0.00382305*f2vector[n+1]) + (0.00505446*f3vector[n+1])
        
            #print (F_n_1)
            
            
        u_n_1 = A*u_n+B*v_n+C*F_n+D*F_n_1

        v_n_1 = A1*u_n+B1*v_n+C1*F_n+D1*F_n_1

        uVector.append(u_n_1)
    
        vVector.append(v_n_1)

    # Update the initial conditions (for use on next iteration of for loop)

        u_n = u_n_1
           
        v_n = v_n_1
        
    #print (uVector)
    
    return (uVector)

systemResponse = calculateResponse(tvector, f2vector, f3vector)
When I run this code I get this error.

Error:
[0] --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-136-62a772ba4a52> in <module> 81 82 ---> 83 print (uVector) NameError: name 'uVector' is not defined
I made a quick check that uVector was being created properly within the for loop by printing once the loop was finished by adding the following to the code:

# Set constants

tvector = t # tVector is an array holding the time vector
f1vector = 0
f2vector = F2
f3vector = F3
xi = 0.025
omega_n = OmegaC
omega_d = OmegaC*((1-0.025**2)**0.5)
k = modalK[0,0]
delta_t = t[1]-t[0]
u_0 = 0
v_0 = 0
n = 0

#Function to calculate displacement from a time and force vector

def calculateResponse(tvector, f2vector, f3vector):
    
	# Compute constants A1-D1 (captures dynamic characteristics of the system)
    A = math.e**(-xi*omega_n*delta_t)*((xi/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t)+np.cos(omega_d*delta_t))
    B = math.e**(-xi*omega_n*delta_t)*((1/omega_d*np.sin(omega_d*delta_t)))
    C = (1/k)*(((2*xi)/(omega_n*delta_t)) + math.e**(-xi*omega_n*delta_t)*((((1-2*(xi**2))/(omega_d*delta_t))-(xi/(math.sqrt(1-(xi**2)))))*math.sin(omega_d*delta_t)-(1+((2*xi)/(omega_n*delta_t)))*np.cos(omega_d*delta_t)))
    D = (1/k)*(1-((2*xi)/(omega_n*delta_t))+math.e**(-xi*omega_n*delta_t)*(((2*(xi**2)-1)/(omega_d*delta_t))*np.sin(omega_d*delta_t)+((2*xi)/(omega_n*delta_t))*np.cos(omega_d*delta_t)))
    A1 = -math.e**(-xi*omega_n*delta_t)*((omega_n/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t))
    B1 = math.e**(-xi*omega_n*delta_t)*(np.cos(omega_d*delta_t)-((xi)/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t))
    C1 =(1/k)*(-(1/delta_t)+math.e**(-xi*omega_n*delta_t)*((((omega_n)/(math.sqrt(1-(xi**2))))+((xi)/(delta_t*math.sqrt(1-(xi**2)))))*np.sin(omega_d*delta_t)+(1/delta_t)*np.cos(omega_d*delta_t)))
    D1 =(1/k)*((1/delta_t)-(math.e**(-xi*omega_n*delta_t)/delta_t)*((xi/(math.sqrt(1-(xi**2))))*np.sin(omega_d*delta_t)+np.cos(omega_d*delta_t))) 

    u_n = u_0

    v_n = v_0

    uVector = [u_n]

    vVector = [v_n]
    
    print (uVector)
    
    for n, timestep in enumerate(tvector):

    # Extract the force values at the beginning and end of this timestep

        F_n = f1vector + (0.00313418*f2vector[n]) + (0.00505446*f3vector[n])
        #print (n)
        #print (F_n)
        
        if n == (len(tvector)) - 1 :
            F_n_1 = F_n
            #print (F_n_1)
                       
        else: 
            
            F_n_1 = f1vector + (0.00382305*f2vector[n+1]) + (0.00505446*f3vector[n+1])
        
            #print (F_n_1)
            
            
        u_n_1 = A*u_n+B*v_n+C*F_n+D*F_n_1

        v_n_1 = A1*u_n+B1*v_n+C1*F_n+D1*F_n_1

        uVector.append(u_n_1)
    
        vVector.append(v_n_1)

    # Update the initial conditions (for use on next iteration of for loop)

        u_n = u_n_1
           
        v_n = v_n_1
        
    print (uVector)
    
    return (uVector)

systemResponse = calculateResponse(tvector, f2vector, f3vector)
And the output is as expected.
Output:
[0, 0.00011831004537829503, 0.0006849483306082231, 0.0023220314106007817, 0.005293307226704513, 0.010539345065170538, 0.018893679127418687, 0.030886890310690307, 0.047005486264238366, 0.06706645152843715, 0.0909185769226359, 0.1185924427430188, 0.15030821956229495, 0.18587497429363395, 0.22484493048446996, 0.26722094089203824, 0.31227402234149865, 0.35957272182711403, 0.40921037179173364, 0.46043750913559034, 0.5122199213799024, 0.5643595068373557, 0.6155033562254681, 0.6650471478122503, 0.7125315968886307, 0.7569376799567396, 0.7977384869753286, 0.8339281228741673, 0.8649852705391295, 0.8905438210062928, 0.9108158652429355, 0.925847816796332, 0.9349845664972962, 0.9384343659004083, 0.936699235920457, 0.9297777268206677, 0.9173148662887954,....
I need uVector to be available outside the function in order to plot it.

Please any help would be massively appreciated!!
your function returns uVector (no need of the brackets, by the way) and you assign the value returned by the function to systemResponse. You must use that name, not uVector (which is local to function scope only, i.e. it doesn't exists outside the function).
By the way, instead of systemResponse you can use uVector, without any problem, if that name is more meaningful, e.g.
uVector = calculateResponse(tvector, f2vector, f3vector)