# --------------------------------------------------------------------------
# Name  : Sandeep Tripathi
# Branch: Mechanical Engineering
# 1 Dimensional Heat Flow by Conduction in Composite Wall
# --------------------------------------------------------------------------

# Define various modules required
import numpy as np
import pylab

# Input fron the user number of nodes
n = int(raw_input("Enter the number of nodes in the composite wall: "))
noelem = n - 1

# Initialize the Global Stiffness Matrix anf Force Vector to zero
K = np.zeros([n, n])
F = np.zeros([n, 1])
L = np.zeros([noelem])
kther = np.zeros([noelem])

# Accept the input from user for length and thermal conductivity of wall
for input1 in range(noelem):
    L[input1] = float(raw_input("Enter the length of the wall (cm): "))
    kther[input1] = float(raw_input("Enter the thermal conductivity of the wall (W/cm C): "))

# Global Stiffness Matrix anf Force Vector are computed
for element in range(n - 1):
    K[element, element] += (kther[element] / L[element])
    K[element + 1, element + 1] += (kther[element] / L[element])
    K[element, element + 1] += (- kther[element] / L[element])
    K[element + 1, element] += (- kther[element] / L[element])
    F[element, 0] += 0
    F[element + 1, 0] += 0

# Accepting the Boundry Conditions from the user
nodalsol = np.zeros([n, 1])
nodalsol[0] = float(raw_input("Enter the temperature at the beginning of the wall (deg C): "))
nodalsol[noelem] = float(raw_input("Enter the temperature at the end of the wall (deg C): "))

# Defining the criteria for stopping the Solution
numiter = 10
soleqn = range(1, noelem)

# Solving equations for computing Temperature at various nodes
# Gauss Siedel Algorithm is used
for iteration in range(numiter):
    for row in soleqn:
        const = F[row]
        for col in range(n):
            if row != col:
                const = const - (K[row, col] * nodalsol[col])
        nodalsol[row] = const/K[row, row]

# Computing the total length of the wall
xlen = [0]
totalen = 0
for length in range(noelem):
    totalen += L[length]
    xlen.append(totalen)

# Computing the nodal solutions
ylen = []
for values in range(n):
    ylen.append(nodalsol[values, 0])

# Calculating Heat Flow through each material
heatflow = []
for element in range(noelem):
    q = (kther[element] * ((ylen[element] - ylen[element + 1])/ (xlen[element + 1] - xlen[element])))
    heatflow.append(q)
print "\n"
for element in range(noelem):
    print('Heat flow through wall ' + str(element + 1) + ' is ' + str(heatflow[element]))

# Computing the range of a float when start, stop and step are given
def nrange(start, stop, step):
    """ Compute range for floating numbers """
    answer = []
    while start < stop:
        answer.append(start)
        start += step
    return answer

# Calculating nodal solution at intermediate distance using interpolation (Shape) functions     
xlength = []
ylength = []
for el in range(noelem):
    step = (xlen[el + 1] - xlen[el])/ 10
    for x in nrange(xlen[el], xlen[el + 1], step):
        xlength.append(x)
        tempy = (((xlen[el + 1] - x)/ (xlen[el + 1] - xlen[el])) * ylen[el]) + (((x - xlen[el])/ (xlen[el + 1] - xlen[el])) * ylen[el + 1])
        ylength.append(tempy)

# Plotting the given results
pylab.plot(xlength, ylength,)
pylab.title('Heat Conduction in 1 Dimensional Composite Wall', fontsize = 15)
pylab.xlabel('Length of Composite Wall (cm)')
pylab.ylabel('Temperature of Wall (deg C)')
pylab.grid(True)
pylab.show()
