Challenge

Week 6 - Multivariate Newton Rhapson Solver

Aim :

To solve the given set of coupled non linear equations using multivariate newton raphson method.

Given data:

Initial guess values:

y1=1

y2=0

y3=0

Methods incorporating newton raphson solver:

1. Implicit scheme

2.Jacobian method.

Newton Raphson method:

The Newton-Raphson method (also known as Newton's method) is a way to quickly find a good approximation for the root of a real-valued function f(x) = 0f(x)=0. It uses the idea that a continuous and differentiable function can be approximated by a straight line tangent to it.

Suppose you need to find the root of a continuous, differentiable function f(x)f(x), and you know the root you are looking for is near the point x = x_0x=x0​. Then Newton's method tells us that a better approximation for the root is

`x_1 = x_0 - \frac{f(x_0)}{f'(x_0)}`

This process may be repeated as many times as necessary to get the desired accuracy. In general, for any xx-value x_nxn​, the next value is given by

`x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}`

For a multivariate equation the equation is devised as

`x_(New) = x_(guess) - alpha.J^-1.F`

where `alpha` is relaxation factor

J is the jacobian matrix.

F is the function`((f1),(f2),(f3))`the equations.

Jacobian matrix:

It is the matrix which contains all the possible derivatives of the coupled equations coressponding to the number of variables.

Derivation of the coupled non-linear equations are solved and uploaded in the below link

https://drive.google.com/file/d/1AWHRMkdnQ9KDG9KlNL2Linxj7FITg3NE/view?usp=sharing

And now we can use the function matrix to calculate the Jacobian matrix and solve using Newton raphson solver.

`x_(New) = x_(guess) - alpha.J^-1.F`

The code:

import numpy as np 
import matplotlib.pyplot as plt
from numpy.linalg import inv

def f1(y1,y2,y3,y_old1,h):
	return y_old1+h*(-0.04*y1 +pow(10,4)*y2*y3)-y1

def f2(y1,y2,y3,y_old2,h):
    return y_old2 +h*(0.04*y1-pow(10,4)*y2*y3-3*pow(10,7)*pow(y2,2))-y2

def f3(y1,y2,y3,y_old3,h):
    return y_old3 +h*(3*pow(10,7)*pow(y2,2))-y3

#function for Jacobian matrix
def jacobian(y_new,y_old,h):
    
    J=np.ones((3,3))

    y_old1=y_old[0]
    y_old2=y_old[1]
    y_old3=y_old[2]

    dy=1e-10
    y1=y_new[0]
    y2=y_new[1]
    y3=y_new[2]

    J[0,0]=(f1(y1+dy,y2,y3,y_old[0],h)-f1(y1,y2,y3,y_old[0],h))/dy
    J[0,1]=(f1(y1,y2+dy,y3,y_old[0],h)-f1(y1,y2,y3,y_old[0],h))/dy
    J[0,2]=(f1(y1,y2,y3+dy,y_old[0],h)-f1(y1,y2,y3,y_old[0],h))/dy
    
    J[1,0]=(f2(y1+dy,y2,y3,y_old2,h)-f2(y1,y2,y3,y_old2,h))/dy
    J[1,1]=(f2(y1,y2+dy,y3,y_old2,h)-f2(y1,y2,y3,y_old2,h))/dy
    J[1,2]=(f2(y1,y2,y3+dy,y_old2,h)-f2(y1,y2,y3,y_old2,h))/dy
    
    J[2,0]=(f3(y1+dy,y2,y3,y_old3,h)-f3(y1,y2,y3,y_old3,h))/dy
    J[2,1]=(f3(y1,y2+dy,y3,y_old3,h)-f3(y1,y2,y3,y_old3,h))/dy
    J[2,2]=(f3(y1,y2,y3+dy,y_old3,h)-f3(y1,y2,y3,y_old3,h))/dy

    return J




h=0.1
time=np.arange(0,600,h)
alpha =1


F=np.zeros((3,1))
y_old=np.zeros((3,1))
y_new =np.zeros((3,1))
y_old[0]=1
tol=1e-10
y1=[]
y2=[]
y3=[]

for i in range(0,len(time)):

    y_guess=np.copy(y_old)

    error=9e9
    while error>tol: 
        Jac=jacobian(y_new,y_old,h)
        F[0]=f1(y_guess[0],y_guess[1],y_guess[2],y_old[0],h)
        F[1]=f2(y_guess[0],y_guess[1],y_guess[2],y_old[1],h)
        F[2]=f3(y_guess[0],y_guess[1],y_guess[2],y_old[2],h)

        
        y_new=y_guess - alpha*np.matmul(inv(Jac),F)
        error=max(abs(y_new-y_guess))
        y_guess= y_new
    y_old=y_new
    y1.append(y_new[0])
    y2.append(y_new[1])
    y3.append(y_new[2])

plt.plot(time,y1,label='y1')
plt.plot(time,y2,label='y2')
plt.plot(time,y3,label='y3')
plt.legend()
plt.show()

Plots:

when dt =0.1

When dt=1:

When dt =10:

About the Code:

  • We write codes for the functions f1,f2,f3 and for the jacobian before the main code.
  • In the main code we specify values for all the yold ,dt, error, tolerances specified.
  • And we create three arrays to store the y new values and give some guess values initially as specified in the question.
  • We run the for loop for 10 minutes and while loop until the error > tolerance, we calculate the ynew value using the newton raphson solver by backward differencing scheme.
  • And update the value of yold and yguess at all the time steps.
  • Plot the results finally.

Conclusion:

The implicit scheme is not sensitive here ,it gives almost the same results for dt values less than 1, but the solution gets disturbed when using a larger time step (dt>1). So the ideal step size would be dt=0.1.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.