I'm trying solve a system of coupled ordinary differential equations, formed by 7 ODEs in python, using solve_ivp or either implement a fuction for RK4.
The general physical problem is as follows:
Cooling of photovoltaic modules with heat exchanger coupling to the module. In this way, the module generates electrical energy and thermal energy.
I have a polynomial function, G(t) = 9.8385e-13*t^4 - 1.82918e-8*t^3 + 5.991355e-05*t^2 + 2.312059e-1*t + 25, which works for an approximate range of 0 < t < 9000, which represents solar radiation as a function of time of day.
This function was obtained through a "polyfit" applied to real data (file upload here. Its a CSV - https://files.fm/u/9y4evkf6c).
This function is used as input for the ODEs, which represent an electrical and a thermal system as a function of time.
To solve the electrical model, I created some scripts that solve the diode equation for the photovoltaic module in question, and the output of this script is the photovoltaic power (called in the PPV thermal model) generated as a function of the module temperature and radiation. This script works great and solves part of my problem.
My difficulty lies in solving the equations of the thermal model, which receives as input parameters G(t) and PPV.
The equations result in this system:
System of EDOS
Labels:
Tvidro = Tglass = T1
Tcel = Tpv = T2
Ttedlar = T3
Tabs = Tabsorber = T4
Ttubo = Ttube = T5
Tfsai = Tfluid_out = T6
Tiso = Tinsulation = T7
Using method/function for RK4, the complete code is like this (you can go direct to part "#DEFINE MODEL EQUATIONS - ODES)" :
import numpy as np
import matplotlib.pyplot as plt
import csv
from numpy.polynomial.polynomial import polyval
############################################################
with open('directory of data called teste_dados_radiacao',"r") as i:
rawdata = list(csv.reader(i, delimiter = ";"))
exampledata = np.array(rawdata[1:], dtype=float)
xdata = exampledata[:,0]
ydata = exampledata[:,1]
curve = np.array(np.polyfit(xdata, ydata, 4))
rev_curve = np.array(list(reversed(curve)), dtype=float)
print(rev_curve)
#G_ajustado = polyval(xdata, rev_curve)
""" plt.plot(xdata, ydata, label = "dados experimentais")
plt.plot(xdata, model, label = "model")
plt.legend()
plt.show() """
#############################################################
#CONSTANTS
Tamb = 25 #°C #ambient temperatura
SIGMA = 5.67e-8 #W/m2K4
E_VIDRO = 0.90 #between 0.85 e 0.83 #nasrin2017 0.04
VENTO = 2 #m/s
T_GROUND = Tamb + 2 #°C
T_CEU = 0.00552*Tamb**1.5
Vf = 1 #m/s
Do = 10e-3 #m
Di = 8e-3 #m
NS = 6*10 #number of cells
T_F_ENT = 20 #°C
#INPUTS
Tcel = 25
Tv = 25
Tiso = 30
Av = 1.638*0.982
ALPHA_VIDRO = 0.9
L_VIDRO = 3e-3 #m
RHO_VIDRO = 2500 #kg/m3
M_VIDRO = Av*L_VIDRO*RHO_VIDRO #kg
CP_VIDRO = 500 #j/kgK
K_VIDRO = 2 #W/mK
TAU_VIDRO = 0.95
Pac = 0.85
H_CELL = 0.156 #m
A_CELL = NS*H_CELL**2
ALPHA_CELL = 0.9
L_CEL = 3e-3
RHO_CEL = 2330
M_CEL = A_CELL*L_CEL*RHO_CEL #kg - estimated
CP_CEL = 900 #J/kgK
K_CEL = 140 #W/mK
BETA_T = 0.43/100 # %/°C
N_ELE_REF = 0.1368 #13.68%
N_ELE = N_ELE_REF*(1 - BETA_T*(Tcel - 25)) #273 + 25 - tcel kelvin
A_tedlar = Av
L_TEDLAR = 0.33e-3
RHO_TEDLAR = 1500
M_TEDLAR = Av*L_TEDLAR*RHO_TEDLAR
CP_TEDLAR = 1090 #1090 OU 2090
K_TEDLAR = 0.35
ALPHA_TEDLAR = 0.34 #doc nasa ou zero
#parameters
RHO_ABS = 2700
A_ABS = Av
CP_ABS =900
L_ABS = 3e-3 #mm
M_ABS = A_ABS*RHO_ABS*L_ABS
K_ABS = 300
A_ABS_TUBO = 10*1.60*0.01+0.154*9*0.01
A_ABS_ISO = Av-A_ABS_TUBO
RHO_TUBO = 2700
CP_TUBO = 900
N_TUBOS = 10
L_TUBO = N_TUBOS*1.6
M_TUBO = RHO_TUBO*L_TUBO*(3.1415/4)*(Do**2 - Di**2)
K_TUBO = 300
A_TUBO_F = 0.387 #pi*Di*(L*10 VOLTAS + R(156MM)*9)
A_TUBO_ISO = 0.484 #pi*Do*(L*10 VOLTAS + R(156MM)*9)
A_ISO = Av
RHO_ISO = 50
L_ISO = 40e-3
M_ISO = A_ISO*RHO_ISO*L_ISO
CP_ISO = 670
K_ISO = 0.0375
E_ISO = 0.75 #ESTIMATED
RHO_FLUIDO = 997
M_FLUIDO = L_TUBO*(3.1415/4)*Di**2*RHO_FLUIDO
CP_FLUIDO = 4186 #j/kgK
MI_FLUIDO = 0.890e-3 #Pa*s ou N/m2 * s
K_FLUIDO = 0.607
M_PONTO = 0.05 #kg/s ou 0.5 kg/m3
#DIMENSIONLESS
Pr = CP_FLUIDO*MI_FLUIDO/K_FLUIDO #water 25°C
Re = RHO_FLUIDO*Vf*Di/MI_FLUIDO
if (Re<=2300):
Nuf = 4.364
else:
Nuf = 0.023*(Re**0.8)*(Pr*0.4)*Re
#COEFFICIENTS
h_rad_vidro_ceu = SIGMA*E_VIDRO*(Tv**2 - T_CEU)*(Tv + T_CEU)
h_conv_vidro_amb = 2.8 + 3*VENTO
h_conv_tubo_fluido = 0.5*30#Nuf
h_cond_vidro_cel = 1/((L_VIDRO/K_VIDRO) + (L_CEL/K_CEL))
h_cond_cel_tedlar = 1/((L_TEDLAR/K_TEDLAR) + (L_CEL/K_CEL))
h_cond_tedlar_abs = 1/((L_TEDLAR/K_TEDLAR) + (L_ABS/K_ABS))
h_cond_abs_tubo = 1/((L_TUBO/K_TUBO) + (L_ABS/K_ABS))
h_cond_abs_iso = 1/((L_ISO/K_ISO) + (L_ABS/K_ABS))
h_cond_tubo_iso = 1/((L_ISO/K_ISO) + (L_TUBO/K_TUBO))
h_conv_iso_amb = h_conv_vidro_amb
h_rad_iso_ground = SIGMA*E_ISO*(Tiso**2 - T_GROUND**2)*(Tiso + T_GROUND)
#GROUPS
A1 = (1/(M_VIDRO*CP_VIDRO))*(ALPHA_VIDRO*Av)#*G(t)) G_ajustado = polyval(dt,rev_curve)
A2 = (1/(M_VIDRO*CP_VIDRO))*(Av*(h_rad_vidro_ceu + h_conv_vidro_amb + h_cond_vidro_cel))
A3 = (1/(M_VIDRO*CP_VIDRO))*Av*h_cond_vidro_cel
A4 = (1/(M_VIDRO*CP_VIDRO))*Av*(h_conv_vidro_amb + h_rad_vidro_ceu)
A5 = (1/(M_CEL*CP_CEL))*(Pac*A_CELL*TAU_VIDRO*ALPHA_CELL) #*G(t)
A6 = -1*A5*N_ELE #*G(t)
A7 = (1/(M_CEL*CP_CEL))*A_CELL*h_cond_vidro_cel
A8 = (1/(M_CEL*CP_CEL))*A_CELL*(h_cond_vidro_cel + h_cond_cel_tedlar)
A9 = (1/(M_CEL*CP_CEL))*A_CELL*h_cond_cel_tedlar
A10 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*(1 - Pac)*TAU_VIDRO*ALPHA_TEDLAR#G(t)
A11 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*(h_cond_cel_tedlar + h_cond_tedlar_abs)
A12 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*h_cond_cel_tedlar
A13 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*h_cond_tedlar_abs
A14 = (1/(M_ABS*CP_ABS))*A_ABS*h_cond_tedlar_abs
A15 = (1/(M_ABS*CP_ABS))*(A_ABS*h_cond_tedlar_abs + A_ABS_TUBO*h_cond_abs_tubo + A_ABS_ISO*h_cond_abs_iso)
A16 = (1/(M_ABS*CP_ABS))*A_ABS_TUBO*h_cond_abs_tubo
A17 = (1/(M_ABS*CP_ABS))*A_ABS_ISO*h_cond_abs_iso
A18 = (1/(M_TUBO*CP_TUBO))*A_ABS_TUBO*h_cond_abs_tubo
A19 = (1/(M_TUBO*CP_TUBO))*(A_ABS_TUBO*h_cond_abs_tubo + A_TUBO_F*h_conv_tubo_fluido + A_TUBO_ISO*h_cond_tubo_iso)
A20 = (1/(M_TUBO*CP_TUBO))*A_TUBO_F*h_conv_tubo_fluido*0.5
A21 = (1/(M_TUBO*CP_TUBO))*A_TUBO_ISO*h_cond_tubo_iso
A22 = (1/(M_FLUIDO*CP_FLUIDO))*A_TUBO_F*h_conv_tubo_fluido
A23 = (1/(M_FLUIDO*CP_FLUIDO))*(A_TUBO_F*h_conv_tubo_fluido*0.5 + M_PONTO*CP_FLUIDO)
A24 = (1/(M_FLUIDO*CP_FLUIDO))*(T_F_ENT*(M_PONTO*CP_FLUIDO - h_conv_tubo_fluido*A_TUBO_F*0.5))
A25 = (1/(M_ISO*CP_ISO))*A_ABS_ISO*h_cond_abs_iso
A26 = (1/(M_ISO*CP_ISO))*(A_ABS_ISO*h_cond_abs_iso + A_TUBO_ISO*h_cond_tubo_iso + A_ISO*h_conv_iso_amb + A_ISO*h_rad_iso_ground)
A27 = (1/(M_ISO*CP_ISO))*A_TUBO_ISO*h_cond_tubo_iso
A28 = (1/(M_ISO*CP_ISO))*A_ISO*(h_conv_iso_amb*Tamb + h_rad_iso_ground*T_GROUND)
#DEFINE MODEL EQUATIONS - ODES - (GLASS, PV CELL, TEDLAR, ABSORBER, TUBE, FLUID, INSULATION) # dT1dt = A1*G_ajustado - A2*x[0] + A3*x[1] + A4 # dT2dt = A5*G_ajustado - A6*G_ajustado + A7*x[0] - A8*x[1] + A9*x[2]# dT3dt = A10*G_ajustado - A11*x[2] + A12*x[1] +A13*x[3]
def SysEdo(x, k):#tv-x[0] tcel-x[1] ttedlar-x[2] tabs-x[3] ttubo-x[4] tiso-x[5] tfs-x[6]
dT1dt = A1*polyval(k,rev_curve) - A2*x[0] + A3*x[1] + A4
dT2dt = A5*polyval(k,rev_curve) - A6*polyval(k,rev_curve) + A7*x[0] - A8*x[1] + A9*x[2]
dT3dt = A10*polyval(k,rev_curve) - A11*x[2] + A12*x[1] +A13*x[3]
dT4dt = A14*x[2] - A15*x[3] + A16*x[4] + A17*x[5]
dT5dt = A18*x[3] - A19*x[4] + A20*x[6] + A20*T_F_ENT + A21*x[5]
dT6dt = A22*x[4] - A23*x[6] + A24
dT7dt = A25*x[3] - A26*x[5] + A27*x[4] + A28
Tdot = np.array([dT1dt, dT2dt, dT3dt, dT4dt, dT5dt, dT6dt, dT7dt])
return Tdot
#RungeKutta4
def RK4(f, x0, t0, tf, dt):
t = np.arange(t0, tf, dt) #time vector
nt = t.size #lenght of time vector
nx = x0.size #length of state variables?
x = np.zeros((nx,nt)) #initialize 2D vector
x[:,0] = x0 #initial conditions
#RK4 constants
for k in range(nt-1):
k1 = dt*f(t[k], x[:,k],k)
k2 = dt*f(t[k] + dt/2, x[:,k] + k1/2, k)
k3 = dt*f(t[k] + dt/2, x[:,k] + k2/2, k)
k4 = dt*f(t[k] + dt, x[:,k] + k3, k)
dx = (k1 + 2*k2 + 2*k2 + k4)/6
x[:,k+1] = x[:,k] + dx
return x,t
#Define problems
f = lambda t, x, k : SysEdo(x, k)
#initial state - t0 is initial time - tf is final time - dt is time step
x0 = np.array([30, 30, 30, 30, 30, 30, 30])
t0 = 0
tf = 1000
dt = 1
#EDO SOLVE
x, t = RK4(f, x0, t0, tf, dt)
plt.figure()
plt.plot(t, x[0], '-', label='Tvidro')
"""
plt.plot(t, x[1], '-', label='Tpv')
plt.plot(t, x[2], '-', label='Ttedlar')
plt.plot(t, x[3], '-', label='Tabs')
plt.plot(t, x[4], '-', label='Tiso')
plt.plot(t, x[5], '-', label='Ttubo')
plt.plot(t, x[6], '-', label='Tfsai')"""
plt.title('Gráfico')
plt.legend(['Tvidro', 'Tpv', 'Ttedlar', 'Tabs', 'Tiso', 'Ttubo', 'Tfsai'], shadow=False)
plt.xlabel('t (s)')
plt.ylabel('Temperatura (°C)')
plt.xlim(0,20)
plt.ylim(0,150)
plt.grid('on')
plt.show()
Thank you in advance, I am also open to completely start the implementation from scratch if there is a better way to do this with python or matlab.
You can just replace
x, t = RK4(f, x0, t0, tf, dt)
with
t = arange(t0,tf+0.5*dt,dt)
res = solve_ivp(f,(t0,tf),x0,t_eval=t,args=(k,), method="DOP853", atol=1e-6,rtol=1e-8)
x = res.y[0]
Adapt the last 3 parameters to your liking.
Related
I have this relation to which I write the code using python to compute it , I am not sure if the code is right or not. Could you please give me any advice if it is true or how I can improve the code??, thanks
import matplotlib.pyplot as plt
import numpy as np
from scipy.special import comb
from scipy.constants import k
from numpy import arange
p12 = 1 # system initial state 12
w0 = 1 # system
wn = 0 # wb/w0 bath
U = 0.1
N = 50
n = (N/2)
a =0.007
t = 1000# Time
Z = 2**N * (np.cosh(U*wn/2))**N
q12 = []
f11 = []
def Jrange(start, n, step):
numelements = int((stop-start)/float(step))
for i in range(numelements+1):
yield start + i*step
def trange(tstart,tstop,tstep):
tnumelements = int((tstop-tstart)/float(tstep))
for i in range(tnumelements+1):
yield tstart + i*tstep
for t in trange(tstart,tstop,tstep):
roh2 = 0
roh12 = 0
roh1 = 0
roh11 = 0
for J in Jrange (0,stop,1) :
Nj = (comb (N,(n+J))) - (comb (N,(n+J+1)))
for m in arange (-J,J+1):
r1 = np.sqrt (J*(J + 1) - m*(m + 1)) #r+
r2 = np.sqrt (J*(J + 1) - m*(m - 1)) #r-
Omega1 = (w0 - wn) + (4 *a*(m + (1/2)))/(np.sqrt(N)) #Omeg+
gamma1 = np.sqrt( (Omega1**2 /4)+ (4*a**2 * r1**2)/N) # gamma+
Omega2 =-(w0 - wn) - (4 *a*(m - (1/2)))/(np.sqrt(N)) #Omega-
gamma2 = np.sqrt( (Omega2**2 /4)+ (4*a**2 * r2**2)/N)#gamma-
A1 = np.cos(gamma1*t)
B1 = np.sin(gamma1*t)
A2 = np.cos(gamma2*t)
B2 = np.sin(gamma2*t)
C = np.exp(-m*U*wn)
H12 = C * (A1 - 1j*B1*Omega1/(2*gamma1)) * ((A2 +1j*B2*Omega2/(2*gamma2))
H2 = r2**2 * B2**2 * ((4*a**2)/ (gamma2**2 * N))
H1 = A1**2 + B1**2 *((Omega1**2)/ (4 * gamma1**2))
H11 = C * ((p11*H1) + (p22*H2))
roh11 = roh11+H11
roh12 = roh12 + H12
roh2= roh2 +roh12*Nj
roh1 = roh1 + roh11*Nj
Roh12 = roh2*D *p12*np.exp(1j*(w0-wn)*t)
Roh11 = roh1 *D
q12.append(Roh12)
f11.append(Roh11)
I get this error :
ValueError: operands could not be broadcast together with shapes (365,) (2,)
But I'm surprised by this (2,).
How do I know which variable does this dimension (2,) please?
Because none of my variables should have it.
Thank you for your help !
Here, you can see the first script, where I define my function. It include a loop and also another function so I don't know if I can.
I have a lot of variable with (365, ) for the dimension because, it's function of the time, so for 365 days.
I have some fixed variable like the soil parameter, so the dimension for these is (1,)
But I don't know which variable get (2,) dimension ?
import pandas as pd
import numpy as np
def SA(MO = 0,
ETPr = 0,
SWSa = 0,
pb = 1.70 ):
DB = pd.read_excel("~/Documents/Spider/Data/data_base.xlsx", sheet_name = "DB")
DB1 = pd.read_excel("~/Documents/Spider/Bilan_Courgette.xlsx", sheet_name = "sol")
DB2 = pd.read_excel("~/Documents/Spider/Bilan_Courgette.xlsx", sheet_name = "culture")
#Calculs inter. pour déterminer ET0/day
#Array qui reprend "date" en une série 1 -> 365
JourDeLAnnee = pd.Series(range(1,366))
#Mauves
dist_TS = 1+(0.033*np.cos(0.0172 * JourDeLAnnee))
decli_So = 0.409*np.sin((0.0172 * JourDeLAnnee)-1.39)
lat = 0.87266463
ang_Hor_So =np.arccos(-np.tan(lat)*np.tan(decli_So))
gamma = 0.067
#Jaunes
delta = 2504*np.exp((17.27*DB.tsa_by_day)/(DB.tsa_by_day +237.3))/(DB.tsa_by_day +237.3)**2
rg = DB.ens_by_day / 1000000 * 86400
ra = 37.6 * dist_TS * ((ang_Hor_So * np.sin(lat) * np.sin(decli_So)) + \
(np.cos(lat) * np.cos(decli_So) * np.sin(ang_Hor_So)))
rso = (0.75 + (2*0.00001*120)) * ra
tw =(DB.tsa_by_day * np.arctan(0.151977 * ((DB.hra_by_day + 8.313659)**0.5))) + \
np.arctan(DB.tsa_by_day + DB.hra_by_day) - np.arctan(DB.hra_by_day - 1.676331) + \
(0.00391838 * ((DB.hra_by_day)**1.5) * np.arctan(0.023101 * DB.hra_by_day)) - 4.686035
ed = (0.611 * np.exp((17.27 * tw) / (tw + 237.3))) - (0.0008 *(DB.tsa_by_day-tw) * 101.325)
ea =((0.611 * np.exp((17.27*DB.tsa_max) / (DB.tsa_max + 237.3))) + \
(0.611 * np.exp((17.27 * DB.tsa_min) / (DB.tsa_min +237.3)))) / 2.0
rn = (0.77 * rg) - (((1.35 * (rg / rso)) - 0.35) \
* (0.34 - (0.14 * (ed**0.5))) * (4.9E-9) * ((((273+DB.tsa_max)**4)+((273+DB.tsa_min)**4))/2))
#Calcul de G
from typing import List
def get_g_constant(tsa_by_day: List[float], day: int):
assert day >= 1
return 0.38 * (tsa_by_day[day] - tsa_by_day[day-1])
def get_g_for_year(tsa_by_day: List[int]) -> List[float]:
g_list = []
for i in range(1, len(tsa_by_day)):
g_value = get_g_constant(tsa_by_day, i)
g_list.append(g_value)
return g_list
G = get_g_for_year(DB.tsa_by_day)
G = [DB.tsa_by_day[0]] + G
#Le fameux ET0
ET0 = ((0.408 * delta * (rn - G)) + (gamma * (900 /(DB.tsa_by_day + 273)) * DB.vtt_by_day * (ea - ed))) / \
(delta + (0.067*(1+(0.34 * DB.vtt_by_day))))
# Calcul des paramètres du sol
Profil = 500
pb = 100 / ((MO / 224000) + ((100-MO) / (1.64)))
Os = 0.6355+0.0013* DB1.A -0.1631* pb
Or = 0
lnα = (-4.3003) - (0.0097*DB1.A) + (0.0138* DB1.S ) - (0.0992*MO)
lnn = -1.0846-0.0236 * DB1.A -0.0085 * DB1.S +0.0001 * (DB1.S)**2
nn = np.exp(lnn) + 1
m = 1 - (1/nn)
lnK0 = 1.9582 + 0.0308*DB1.S - 0.6142* pb - 0.1566*MO
λ = -1.8642 - 0.1317*DB1.A + 0.0067*DB1.S
α = np.exp(lnα)
K0 = np.exp(lnK0)
θPf2 =(((1 + ((α*(10**2.5))**nn))**(-m))*( Os - Or)) + Or
θPf4 =(((1 + ((α*(10**4.2))**nn))**(-m))*( Os - Or)) + Or
SWS = θPf2 - θPf4
diff = SWS*SWSa
aj = diff / 2
θPf2New = θPf2 + aj
θPf4New = θPf4 - aj
#Calcul du volume de stock p à atteindre
p = 0.04 *(5 - ET0) + DB2.ptab[0]
θp =(1 - p) * ( θPf2New - θPf4New )+ θPf4New
Vp = θp * Profil
#Le fameux ETP
import datetime
DateS = datetime.datetime.strptime('30/03/2019','%d/%m/%Y').timetuple().tm_yday
DateR = datetime.datetime.strptime('15/09/2019','%d/%m/%Y').timetuple().tm_yday
ETP=ET0.copy()
for n in range(364):
if n >= (DateS - 1) and n <= (DateR - 1) :
ETP[n] = ET0[n] * DB2.Kc[0]
else:
ETP[n] = ET0[n] * DB2.SolNu[0]
ETP[0] = 0
ETPNew = ET0.copy()
ETPNew = ETP - ETP * ETPr
#Le Bilan Hydrique
Stock = ET0.copy()
θ = ET0.copy()
Drainage = ET0.copy()
Irrigation = ET0.copy()
Se = ET0.copy()
SeC = ET0.copy()
θ[0] = θPf2New
Stock[0] = θ[0]*Profil
for i in range(364) :
Se[i] = (θ[i] - Or)/( Os - Or)
if Se[i] > 1 :
SeC[i] = 1
else:
SeC[i] = Se[i]
Drainage[i] = K0 *(((SeC[i])**λ )*(1-(1- SeC[i]**(nn/(nn-1)))**m)**2)*10
if Vp[i] - Stock[i] > 0 : #Ici stock non défini
Irrigation[i] = Vp[i] - Stock[i]
else:
Irrigation[i] = 0
Stock[i+1] = Stock[i] + DB.plu_by_day[i] - ETPNew[i] - Drainage[i] + Irrigation[i]
θ[i+1] = Stock[i+1] / Profil
return (Irrigation.sum())
After, i use a second script to do a sensitivity analysis. And It's here, when I run this script, I get the error 'ValueError: operands could not be broadcast together with shapes (365,) (2,)'
import numpy as np
from SALib.analyze import sobol
from SALib.sample import saltelli
from test import*
import matplotlib.pyplot as plt
# Set up dictionary with system parameters
problem = {
'num_vars': 4,
'names': ['MO', 'ETPr', 'SWSa', 'K0'],
'bounds': [[0, 10],
[0, 0.04135],
[0, 0.2615],
[1.40, 1.70],
]}
# Array with n's to use
nsamples = np.arange(50, 400, 50)
# Arrays to store the index estimates
S1_estimates = np.zeros([problem['num_vars'],len(nsamples)])
ST_estimates = np.zeros([problem['num_vars'],len(nsamples)])
# Loop through all n values, create sample, evaluate model and estimate S1 & ST
for i in range(len(nsamples)):
print('n= '+ str(nsamples[i]))
# Generate samples
sampleset = saltelli.sample(problem, nsamples[i],calc_second_order=False)
# Run model for all samples
output = [SA(*sampleset[j,:]) for j in range(len(sampleset))]
# Perform analysis
results = sobol.analyze(problem, np.asarray(output), calc_second_order=False,print_to_console=False)
# Store estimates
ST_estimates[:,i]=results['ST']
S1_estimates[:,i]=results['S1']
np.save('ST_estimates.npy', ST_estimates)
np.save('S1_estimates.npy', S1_estimates)
S1_estimates = np.load('S1_estimates.npy')
ST_estimates = np.load('ST_estimates.npy')
# Generate figure showing evolution of indices
fig = plt.figure(figsize=(18,9))
ax1 = fig.add_subplot(1,2,1)
handles = []
for j in range(problem['num_vars']):
handles += ax1.plot(nsamples, S1_estimates[j,:], linewidth=5)
ax1.set_title('Evolution of S1 index estimates', fontsize=20)
ax1.set_ylabel('S1', fontsize=18)
ax1.set_xlabel('Number of samples (n)', fontsize=18)
ax1.tick_params(axis='both', which='major', labelsize=14)
ax2 = fig.add_subplot(1,2,2)
for j in range(problem['num_vars']):
ax2.plot(nsamples, ST_estimates[j,:], linewidth=5)
ax2.set_title('Evolution of ST index estimates', fontsize=20)
ax2.set_ylabel('ST', fontsize=18)
ax2.tick_params(axis='both', which='major', labelsize=14)
ax2.set_xlabel('Number of samples (n)', fontsize=18)
fig.legend(handles, problem['names'], loc = 'right', fontsize=11)
plt.savefig('indexevolution.png')
# Calculate parameter rankings
S1_ranks = np.zeros_like(S1_estimates)
ST_ranks = np.zeros_like(ST_estimates)
for i in range(len(nsamples)):
orderS1 = np.argsort(S1_estimates[:,i])
orderST = np.argsort(ST_estimates[:,i])
S1_ranks[:,i] = orderS1.argsort()
ST_ranks[:,i] = orderST.argsort()
Thank you for your help !
I am trying to program a neural network and was trying to minimize the cost function using scipy.optimize_bfgs() and after attempting to use this I get the error that "TypeError: cost() takes 3 positional arguments but 4 were given". Where are these four arguments coming from and how can I rectify this?
The cost function is defined by:
def cost(param,X,y):
Theta1 = np.reshape(param[0:106950:1],(75,1426))
Theta2 = np.reshape(param[106950:112650:1],(75,76))
Theta3 = np.reshape(param[112650::1],(1,76))
m = len(X)
J = 0
a1 = X
z2 = np.dot(a1,np.transpose(Theta1))
a2 = sigmoid(z2)
a2 = np.concatenate((np.ones((len(a2),1)),a2),axis=1)
z3 = np.dot(a2,Theta2.T)
a3 = sigmoid(z3)
a3 = np.concatenate((np.ones((len(a3),1)),a3),axis=1)
z4 = np.dot(a3,Theta3.T)
a4 = sigmoid(z4)
h = a4
##Calculate cost
J = np.sum(np.sum(np.multiply(-y,np.log(h)) - np.multiply((1-y),np.log(1-h))))/(2*m)
theta1_reg[:,0] = 0
theta2_reg[:,0] = 0
theta3_reg[:,0] = 0
Reg = (lamb/(2*m))*(np.sum(np.sum(np.square(theta1_reg)))+np.sum(np.sum(np.sqaure(theta2_reg)))+np.sum(np.sum(np.square(theta3_reg))))
J = J + Reg
return J
The gradient is then calculated with:
def grad(param,X,y):
Theta1 = np.reshape(param[0:106950:1],(75,1426))
Theta2 = np.reshape(param[106950:112650:1],(75,76))
Theta3 = np.reshape(param[112650::1],(1,76))
Theta1_grad = np.zeros(Theta1.shape)
Theta2_grad = np.zeros(Theta2.shape)
Theta3_grad = np.zeros(Theta3.shape)
m = len(X)
##Forward propogation
a1 = X
z2 = np.dot(a1,np.transpose(Theta1))
a2 = sigmoid(z2)
a2 = np.concatenate((np.ones((len(a2),1)),a2),axis=1)
z3 = np.dot(a2,Theta2.T)
a3 = sigmoid(z3)
a3 = np.concatenate((np.ones((len(a3),1)),a3),axis=1)
z4 = np.dot(a3,Theta3.T)
a4 = sigmoid(z4)
h = a4
##Backward propogation
d4 = a4 - y
d3 = np.multiply(np.dot(d4,Theta3[:,1:]),sigmoidGradient(z3))
d2 = np.multiply(np.dot(d3,Theta2[:,1:]),sigmoidGradient(z2)) ## or sigmoid(z2) .* ( 1 - sigmoid(z2))
D1 = np.dot(d2.T,a1)
D2 = np.dot(d3.T,a2)
D3 = np.dot(d4.T,a3)
##Unregularized gradients
Theta1_grad = (1/m)*D1
Theta2_grad = (1/m)*D2
Theta3_grad = (1/m)*D3
##Regularize gradients
theta1_reg = Theta1
theta2_reg = Theta2
theta3_reg = Theta3
theta1_reg[:,0] = 0
theta2_reg[:,0] = 0
theta3_reg[:,0] = 0
theta1_reg = (lamb/m)*theta1_reg
theta2_reg = (lamb/m)*theta2_reg
theta3_reg = (lamb/m)*theta3_reg
Theta1_grad = Theta1_grad + theta1_reg
Theta2_grad = Theta2_grad + theta2_reg
Theta3_grad = Theta3_grad + theta3_reg
##Concatenate gradients
grad = np.concatenate((Theta1_grad,Theta2_grad,Theta3_grad),axis=None)
return grad
Other functions defined are
def sigmoid(z):
sig = 1 / (1 + np.exp(z))
return sig
def randInitializeWeights(l_in, l_out):
epsilon = 0.12;
W = np.random.rand(l_out, 1+l_in)*2*epsilon - epsilon;
return W
def sigmoidGradient(z):
g = np.multiply(sigmoid(z),(1-sigmoid(z)))
return g
As an example:
import numpy as np
import scipy.optimize
X = np.random.rand(479,1426)
y1 = np.zeros((frames,1))
y2 = np.ones((framesp,1))
y = np.concatenate((y1,y2),axis=0)
init_param = np.random.rand(112726,)
lamb = 0.5
scipy.optimize.fmin_bfgs(cost,fprime=grad,x0=init_param,args=(param,X,y))
Then the error appears.
Thanks for any help
The arguments passed into the cost functions are the parameters, followed by the extra arguments. The parameters are chosen by the minimization function, the extra arguments are passed through.
When calling fmin_bfgs, only pass the extra arguments as args, not the actual parameters to optimize:
scipy.optimize.fmin_bfgs(..., args=(X,y))
My planets are not rotating in my plot and im not entirely sure why?
As a side note, is there way to scale the planets radius properly with respect to the sun. And could the initial positions(x,y) be the aphelion distance from the sun? But no worries, no need to answer, just looking form some insight. Thank you.
from pylab import*
from matplotlib.animation import *
earth_radius = 6.3781e6#meters earth radius
suns_radius = 696e6#meters suns radius
mercury_radius = 2439.5e3# meters mercury radius
venus_radius = 6052e3 #meters venus radius
SunEarth_dist = 152e9 #distance from sun to earth approx. 1Au = 152e6km
SunMercury_dist = 69.8e9 #meters
SunVenus_dist = 108.9e9#meters
sun_mass = 1.988e30 #m1 : kg
mercury_mass = .330e24#m2: kg
venus_mass = 4.87e24 #m3 : kg
earth_mass = 5.97e24#m4 : kg
#radius of the planets scaled from the sun
r1 = suns_radius
r2 = mercury_radius
r3 = venus_radius
r4 = earth_radius
n = 10000#number of steps
dt = 10000#step size
G = 6.67384*10**(-11)#gravitational constant
def planets():
tmax = dt* n
t = 0
x = 0
#inital position of the planets
x1 = 3844e8*0.8*0
y1 = 3844e8*0.8*0
x2 = 3844e8*0.8
y2 = -3844e8*0.8*0
x3 = -3844e8*0.8
y3 = 3844e8*0.8*0
x4 = -3844e8*0.8*0
y4 = -3844e8*0.8
#intial velocity of each planet
Velocity_xS = 0
Velocity_yS = 0
Velocity_xM = 800
Velocity_yM= 1700
Velocity_xV = 0
Velocity_yV = -1500
Velocity_xE = 2000
Velocity_yE = 0
#distance between the planets
d12 = sqrt((x1-x2)**2+(y1-y2)**2)
d23 = sqrt((x2-x3)**2+(y2-y3)**2)
d13 = sqrt((x1-x3)**2+(y1-y3)**2)
d14 = sqrt((x1-x4)**2+(y1-y4)**2)
d24 = sqrt((x2-x4)**2+(y2-y4)**2)
d34 = sqrt((x3-x4)**2+(y3-y4)**2)
while t < tmax:
Fg12 = (G*sun_mass*mercury_mass)/d12**2
Fgx12 = -Fg12*((x1-x2))/d12
Fgy12 = -Fg12*((y1-y2))/d12
Fgx21 = -Fg12*((x2-x1))/d12
Fgy21 = -Fg12*((y2-y1))/d12
Fg13 = (G*sun_mass*venus_mass)/d13**2
Fgx13 = -Fg13*((x1-x3))/d13
Fgy13 = -Fg13*((y1-y3))/d13
Fgx31 = -Fg13*((x3-x1))/d13
Fgy31 = -Fg13*((y3-y1))/d13
Fg23 = (G*venus_mass*mercury_mass)/d23**2
Fgx23 = -Fg23*((x2-x3))/d23
Fgy23 = -Fg23*((y2-y3))/d23
Fgx32 = -Fg23*((x3-x2))/d23
Fgy32 = -Fg23*((y3-y2))/d23
Fg14 = (G*sun_mass*earth_mass)/d14**2
Fgx14 = -Fg14*((x1-x4))/d14
Fgy14 = -Fg14*((y1-y4))/d14
Fgx41 = -Fg14*((x4-x1))/d14
Fgy41 = -Fg14*((y4-y1))/d14
Fg24 = (G*sun_mass*earth_mass)/d24**2
Fgx24 = -Fg24*((x2-x4))/d24
Fgy24 = -Fg24*((y2-y4))/d24
Fgx42 = -Fg24*((x4-x2))/d24
Fgy42 = -Fg24*((x4-x2))/d24
Fg34 = (G*sun_mass*earth_mass)/d34**2
Fgx34 = -Fg34*((x3-x4))/d34
Fgy34 = -Fg34*((y3-y4))/d34
Fgx43 = -Fg34*((x4-x3))/d34
Fgy43 = -Fg34*((y4-y3))/d34
Acceleration_xS = Fgx12/sun_mass + Fgx13/sun_mass + Fgx14/sun_mass
Acceleration_yS = Fgy12/sun_mass + Fgy13/sun_mass + Fgy14/sun_mass
Acceleration_xM = Fgx21/mercury_mass + Fgx23/mercury_mass + Fgx24/mercury_mass
Acceleration_yM = Fgy21/mercury_mass + Fgy23/mercury_mass + Fgy24/mercury_mass
Acceleration_xV = Fgx32/venus_mass + Fgx31/venus_mass + Fgx34/venus_mass
Acceleration_yV = Fgy32/venus_mass + Fgy31/venus_mass + Fgy34/venus_mass
Acceleration_xE = Fgx41/earth_mass + Fgx42/earth_mass+ Fgx43/earth_mass
Acceleration_yE = Fgy41/earth_mass + Fgy42/earth_mass + Fgx43/earth_mass
Velocity_xS = Velocity_xS +Acceleration_xS*dt
Velocity_yS = Velocity_yS +Acceleration_yS*dt
Velocity_xM = Velocity_xM +Acceleration_xM*dt
Velocity_yM = Velocity_yM +Acceleration_yM*dt
Velocity_xV = Velocity_xV +Acceleration_xV*dt
Velocity_yV = Velocity_yV +Acceleration_yV*dt
Velocity_xE = Velocity_xE +Acceleration_xE*dt
Velocity_yE = Velocity_yE +Acceleration_yE*dt
#update the position of the planets
x1 = x1 + Velocity_xS*dt
y1 = y1 + Velocity_yS*dt
x2 = x2 + Velocity_xM*dt
y2 = y2 + Velocity_yM*dt
x3 = x3 + Velocity_xV*dt
y3 = y3 + Velocity_yV*dt
x4 = x4 + Velocity_xE*dt
y4 = y4 + Velocity_yE*dt
Sun.center = x1,y1
Mercury.center = x2,y2
Venus.center = x3,y3
Earth.center = x4,y4
d12 = sqrt((x1-x2)**2+(y1-y2)**2)
d23 = sqrt((x2-x3)**2+(y2-y3)**2)
d13 = sqrt((x1-x3)**2+(y1-y3)**2)
d14 = sqrt((x1-x4)**2+(y1-y4)**2)
d24 = sqrt((x2-x4)**2+(y2-y4)**2)
d34 = sqrt((x3-x4)**2+(y3-y4)**2)
t = t+dt
return x, t
def initial_points(planets):
x, t = planets[0], planets[1]
line.set_data(t, x)
ctr = Sun.center
ax.set_xlim(ctr[0]-5e12, ctr[0]+5e12)
ax.set_ylim(ctr[1]-5e12, ctr[1]+5e12)
return line
fig = plt.figure()
ax = plt.axes(xlim=(-5e12, 5e12), ylim=(-5e12, 5e12))
ax.set_aspect("equal")
line, = ax.plot([], [], '', ms=10)
Sun = Circle((0,0), r1, fc='yellow')
ax.add_artist(Sun)
Mercury = Circle((0 ,0), r2, fc='brown')
ax.add_artist(Mercury)
Venus = Circle(( 0,0), r3, fc='green')
ax.add_artist(Venus)
Earth = Circle((0,0), r4, fc='red')
ax.add_artist(Earth)
ani = FuncAnimation(fig, initial_points, planets, blit=False,\
interval=10, repeat=True)
plt.show()
I am using ode solver to solve stiff problem (since odeint function could not able to solve it). But by this way also I have some warnings and my plot get saturate at some point. Here is image What should I do? Here is the list of warnings:
DVODE-- Warning..internal T (=R1) and H (=R2) are
such that in the machine, T + H = T on the next step
(H = step size). solver will continue anyway
In above, R1 = 0.3667661010318D+00 R2 = 0.1426374862242D-16
DVODE-- Warning..internal T (=R1) and H (=R2) are
such that in the machine, T + H = T on the next step
(H = step size). solver will continue anyway
In above, R1 = 0.3667661010318D+00 R2 = 0.1426374862242D-16
DVODE-- Above warning has been issued I1 times.
it will not be issued again for this problem
In above message, I1 = 2
DVODE-- At current T (=R1), MXSTEP (=I1) steps
taken on this call before reaching TOUT
In above message, I1 = 500
In above message, R1 = 0.3667661010318D+00
My code:
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as si
def func():
#arguments:::
w = 1./3.
xi = 2.86
phi1 = 1.645
phi2 = 2.* 1.202
gt = 10.**(-60)
Lt = (1.202*gt)/np.pi
Lin = 10.**-5
Lf = 0.49
dt = 0.0001
gin = gt*Lt/Lin
xin = (-np.log((3. - (xi**2)*Lin)/(3. - (xi**2)*Lt)) + np.log(Lin/Lt))/4.0
uin = -(np.log(Lin/Lt))/2.
state0 = [gin,xin,uin]
print state0
def eq(L, state):
g = state[0]
x = state[1]
u = state[2]
N = (-2.*g/(6.*np.pi + 5.*g))*(18./(1. - 2.*L) + 5.*np.log(1.- 2.*L) - phi1 + 6. )
B = (-(2. - N)*L) - ((g/np.pi)* (5.*np.log(1.-2.*L) - phi2 + (5.*N/40.)))
Eqs = np.zeros((3))
gdl = Eqs[0] = ((2.+N)*g)/B
xdl = Eqs[1] = -(2./(3.*(1.+w)))* (1./(1.-(xi**2)*L/3.))*(1./B)
udl = Eqs[2]= 1./B
return Eqs
ode = si.ode(eq)
# BDF method suited to stiff systems of ODEs
ode.set_integrator('vode',nsteps=500,method='bdf')
ode.set_initial_value(state0,Lin)
L = []
G = []
while ode.successful() and ode.t < Lf:
ode.integrate(ode.t + dt)
L.append(ode.t)
G.append(ode.y)
lam = np.vstack(L)
g,x,u = np.vstack(G).T
return g,x,u,lam
r= func()
L = r[3]
g = r[0]
lng = np.log10(g)
x = r[1]
u = r[2]
w = 1./3.
xi = 2.86
O_A = np.zeros(len(L))
q = np.zeros(len(L))
for i in np.arange(len(L)):
O_A[i] = xi**2*L[i]/3.
alpha = 2./ ((3.+3.*w) * (1.- (L[i]*xi**2)/3.) )
q[i] = 1./alpha - 1.
n = np.zeros(len(L)) #eta(n)
b = np.zeros(len(L))
for j in np.arange(len(L)):
n[j] =(-2.*g[j]/(6.*np.pi + 5.*g[j]))*(18./(1. - 2.*L[j]) + 5.*np.log(1.- 2.*L[j]) - 1.645 + 6. )
b[j]= (-(2. - n[j])*L[j]) - ((g[j]/np.pi)* (5.*np.log(1.-2.*L[j]) - 2.* 1.202 + ((5.*n[j])/4.)))
P = np.zeros(len(x))
for k in np.arange(len(x)):
C = (((3. - (xi**2)*L[k])/g[k])**(3./4.)) * (((2.*L[k] + (u[k]*b[k]))*xi**2) + (n[k] * (3.- L[k]*xi**2)) )
P[k] = (np.exp(3.*x[k])) * (np.exp(4.*u[k])) * C
plt.figure()
plt.plot(L,P)
plt.xlabel('Lambda ---->')
plt.ylabel('P ----->')
plt.title('lambda Vs P')
plt.show()