The aim is to solve the below equations and plot m with time, i.e. dm/dt
k is unknown and needs to be estimated. For the parameter estimation, the below values for m versus t can be used. This is a dummy dataset, as I would like to get an idea if this problem is solvable. If needed, an initial guesstimate for k can be provided 6e-5 m2/bar.hr.
I have added an initial idea for the code, but not sure if my implementation of the A(H) and P(H) functions in the odes is correct. Also I need a way to estimate for k whilst fitting to the provided m vs t data.
function dydt = diffunTAR(~,y,k, h, A_H, P_H, rho_h, rho_o, wo)
dydt = zeros (2,1);
D = 2.64/1000 %mm/1000 to convert to m
r=D/2
rho_o = 1320 %kg/m3
rho_h = 1000 % kg/m3
wo=648/1000000 %weight component 1 in mg converted to kg
h= 1.5/1000 %1.5mm expressed in m
function A_H= pi*(D/2)^2 + (2/r)*(1+(rho_o/rho_h*y(2)))*(wo/rho_o);
end
function P_H = 5004.6*y(2) + 150.39;
end
%dV/dt
dydt(1)= (k/h)* function A_H* function P_H;
%dH/dt
dydt(2)= (rho_h*k/wo*h)*function A_H*function P_H;
end
tspan = linspace(0,21*24); %time in hrs for 21 days
y0 = [0 6.4800e-04];
[t,y]=ode45(#(t,y) diffunTAR(t,y, k, h, A_H0, rho_h, rho_o, wo), tspan, y0);
updated code after help
function dydt = diffunTAR(~,y,k,h,rho_h,rho_o,wo,L,r)
dydt = zeros (2,1);
%dV/dt
dydt(1)= k/h* AH * PH;
%dH/dt
dydt(2)= (rho_h*k/wo*h) * AH * PH;
AH
PH
function PH
(5004.6*y(2))+150.3;
end
function AH
pi*(r^2)+(2/r)*(1+(rho_o/rho_h*y(2)))*(wo/rho_o);
setInitialConditions (AH, 2*pi*(r)*L+2*pi*(r)^2);
end
end
D = 2.64/1000 %mm/1000 to convert to m
r=D/2
L = 10.6/100 %cm/100 to convert to m
wo=648/1000000 %weight osmotic tablets in mg converted to kg
k=6e-5 %guess for permeability
h= 1.5/1000 %1.5mm expressed in m
rho_o = 1320 %kg/m3
rho_h = 1000 % kg/m3
tspan = linspace(0,21*24); %time in hrs for 21 days
y0 = [0 6.4800e-04];
[t,y]=ode45(#(t,y) diffunTAR(t,y,k,h,rho_h,rho_o,wo,L,r), tspan, y0);
Related
i'm trying to evaluate a G11 symfun in the code below but it fails and keep showing me the variable t that I choose to be set as specified in the code, I even tried to use the 'subs' command but it failed also. I define the necessary symbols and variables but the t variable does not evaluated in just 'G11' symfun, there are another similar symfun such G12 or K12 but the t variable evaluated in them
here is my code
% Defining the variables as symbols.
clear all, close all
clc
syms x xi q_1 q_2 q_3 q_4 q_01 q_02 q_03 q_04 EI Mr M m L t Omega S1 S2 S3
...
S4 S5 S6 S7 S8 w L_dot U U_dot g L_ddot M11 M22
% Defining the general coordinates and the trial function.
L_ddot=0;
g=9.8;
Mr=M/(M+m);
PHI(x,t)=[sqrt(2).* sin(pi.*(xi)) sqrt(2).* sin(2*pi.*(xi)) sqrt(2).*
sin(3.*pi.*(xi)) sqrt(2).* sin(4.*pi.*(xi))];
q_1(t)= S1*exp(sqrt(-1)*w*t);
q_01(t)= S5*exp(sqrt(-1)*w*t);
q_2(t)= S2*exp(sqrt(-1)*w*t);
q_02(t)= S6*exp(sqrt(-1)*w*t);
q_3(t)= S3*exp(sqrt(-1)*w*t);
q_03(t)= S7*exp(sqrt(-1)*w*t);
q_4(t)= S4*exp(sqrt(-1)*w*t);
q_04(t)= S8*exp(sqrt(-1)*w*t);
Q_v(t) =[q_1;q_2;q_3;q_4];
Q_w(t) =[q_01;q_02;q_03;q_04];
V(x,t) = PHI*Q_v(t);
W(x,t) = PHI*Q_w(t);
% Defining the coeficients of the ODE.
U(x,t)=U;
L(x,t)=1+0.1*t;
L_dot(x,t)=diff(L,'t',1);
L_ddot=0;
M11=int(PHI'*PHI,'xi',[0 1]);
M22=M11;
G11=(2*(L_dot/L))* int((2-xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1])+2*Mr*
(U/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1]);
G12=-2*Omega*int(PHI'*PHI,'xi',[0 1]);
G21=-G12;
G22=G11;
K11=(EI/((M+m)*L^4))*int(PHI'*diff(PHI,'xi',4),'xi',[0 1])+ (L_dot/L)^2
*int((2-xi)^2 *...
PHI'*diff(PHI,'xi',2),'xi',[0 1])+ ((L_ddot*L-2*L_dot^2)/L^2)*int((1-
xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1]) ...
+ 2*Mr*(L_dot*U/L^2)*int((2-xi)*PHI'*diff(PHI,'xi',2),'xi',[0 1])+ Mr*
(U/L)^2 *int(PHI'*diff(PHI,'xi',2),'xi',[0 1])-...
(g-((L_ddot-2*L_dot^2)/L))*int((1-xi)*PHI'*diff(PHI,'xi',2),'xi',[0 1])+
(g/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1])-...
Omega^2 * int(PHI'*PHI,'xi',[0 1]);
K12= -2*Omega*(L_dot/L)*int((2-xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1])-2*Mr*
((U*Omega)/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1]);
K21=-K12;
K22=K11;
% evaluating the Coefficient matrices for the time history 1 to 80 seconds
by the stepping of 0.1 .
t=0:0.1:80;
m=8;
M=2;
Mr=0.2;
x=1;
U=2; % the flow velocity
Omega=90;
EI=8.9782;
FUNM11 = matlabFunction(M11);
Mmatrix11 = feval(FUNM11);
FUNG11 = matlabFunction(G11);
Gmatrix11 = feval(FUNG11,t,U,Mr,L_dot,L);
FUNG12 = matlabFunction(G12);
Gmatrix12 = feval(FUNG12, t,x,Omega);
FUNK11 = matlabFunction(K11);
Kmatrix11 = feval(FUNK11, t,M,x,Omega,m,U,EI);
FUNK12 = matlabFunction(K12);
Kmatrix12 = feval(FUNK12, t,M,x,U,m,Omega);
Mmatrix22=Mmatrix11;
Gmatrix21=-Gmatrix12;
Gmatrix22=Gmatrix11;
Kmatrix21=-Kmatrix12;
Kmatrix22=Kmatrix11;
% Assembling the Coeficient matrices
Q=[Q_v;Q_w];
Mmatrix=[Mmatrix11 ,zeros(size(Mmatrix11)); zeros(size(Mmatrix11))
Mmatrix22];
Gmatrix=[Gmatrix11 Gmatrix12; Gmatrix21 Gmatrix22];
Kmatrix=[Kmatrix11 Kmatrix12; Kmatrix21 Kmatrix22];
After assembling my coefficient matrices I try to solve this algebric equation for w:
eqn=det(-w^2.*Mmatrix+i*w.*Gmatrix+Kmatrix)==0;
which w is the frequency of the system.
I've had problems with my code as I've tried to make an integral compute, but it will not for the power, P2.
I've tried using anonymous function handles to use the integral() function on MATLAB as well as just using int(), but it will still not compute. Are the values too small for MATLAB to integrate or am I just missing something small?
Any help or advice would be appreciated to push me in the right direction. Thanks!
The problem in the code is in the bottom of the section labelled "Power Calculations". My integral also gets quite messy if that makes a difference.
%%%%%%%%%%% Parameters %%%%%%%%%%%%
n0 = 1; %air
n1 = 1.4; %layer 1
n2 = 2.62; %layer 2
n3 = 3.5; %silicon
L0 = 650*10^(-9); %centre wavelength
L1 = 200*10^(-9): 10*10^(-9): 2200*10^(-9); %lambda from 200nm to 2200nm
x = ((pi./2).*(L0./L1)); %layer phase thickness
r01 = ((n0 - n1)./(n0 + n1)); %reflection coefficient 01
r12 = ((n1 - n2)./(n1 + n2)); %reflection coefficient 12
r23 = ((n2 - n3)./(n2 + n3)); %reflection coefficient 23
t01 = ((2.*n0)./(n0 + n1)); %transmission coefficient 01
t12 = ((2.*n1)./(n1 + n2)); %transmission coefficient 12
t23 = ((2.*n2)./(n2 + n3)); %transmission coefficient 23
Q1 = [1 r01; r01 1]; %Matrix Q1
Q2 = [1 r12; r12 1]; %Matrix Q2
Q3 = [1 r23; r23 1]; %Matrix Q3
%%%%%%%%%%%% Graph of L vs R %%%%%%%%%%%
R = zeros(size(x));
for i = 1:length(x)
P = [exp(j.*x(i)) 0; 0 exp(-j.*x(i))]; %General Matrix P
T = ((1./(t01.*t12.*t23)).*(Q1*P*Q2*P*Q3)); %Transmission
T11 = T(1,1); %T11 value
T21 = T(2,1); %T21 value
R(i) = ((abs(T21./T11))^2).*100; %Percent reflectivity
end
plot(L1,R)
title('Percent Reflectance vs. wavelength for 2 Layers')
xlabel('Wavelength (m)')
ylabel('Reflectance (%)')
%%%%%%%%%%% Power Calculation %%%%%%%%%%
syms L; %General lamda
y = ((pi./2).*(L0./L)); %Layer phase thickness with variable Lamda
P1 = [exp(j.*y) 0; 0 exp(-j.*y)]; %Matrix P with variable Lambda
T1 = ((1./(t01.*t12.*t23)).*(Q1*P1*Q2*P1*Q3)); %Transmittivity matrix T1
I = ((6.16^(15))./((L.^(5)).*exp(2484./L) - 1)); %Blackbody Irradiance
Tf11 = T1(1,1); %New T11 section of matrix with variable Lambda
Tf2 = (((abs(1./Tf11))^2).*(n3./n0)); %final transmittivity
P1 = Tf2.*I; %Power before integration
L_initial = 200*10^(-9); %Initial wavelength
L_final = 2200*10^(-9); %Final wavelength
P2 = int(P1, L, L_initial, L_final) %Power production
I've refactored your code
to make it easier to read
to improve code reuse
to improve performance
to make it easier to understand
Why do you use so many unnecessary parentheses?!
Anyway, there's a few problems I saw in your code.
You used i as a loop variable, and j as the imaginary unit. It was OK for this one instance, but just barely so. In the future it's better to use 1i or 1j for the imaginary unit, and/or m or ii or something other than i or j as the loop index variable. You're helping yourself and your colleagues; it's just less confusing that way.
Towards the end, you used the variable name P1 twice in a row, and in two different ways. Although it works here, it's confusing! Took me a while to unravel why a matrix-producing function was producing scalars instead...
But by far the biggest problem in your code is the numerical problems with the blackbody irradiance computation. The term
L⁵ · exp(2484/L) - 1
for λ₀ = 200 · 10⁻⁹ m will require computing the quantity
exp(1.242 · 10¹⁰)
which, needless to say, is rather difficult for a computer :) Actually, the problem with your computation is two-fold. First, the exponentiation is definitely out of range of 64 bit IEEE-754 double precision, and will therefore result in ∞. Second, the parentheses are wrong; Planck's law should read
C/L⁵ · 1/(exp(D) - 1)
with C and D the constants (involving Planck's constant, speed of light, and Boltzmann constant), which you've presumably precomputed (I didn't check the values. I do know choice of units can mess these up, so better check).
So, aside from the silly parentheses error, I suspect the main problem is that you simply forgot to rescale λ to nm. Changing everything in the blackbody equation to nm and correcting those parentheses gives the code
I = 6.16^(15) / ( (L*1e+9)^5 * (exp(2484/(L*1e+9)) - 1) );
With this, I got a finite value for the integral of
P2 = 1.052916498836486e-010
But, again, you'd better double-check everything.
Note that I used quadgk(), because it's one of the better ones available on R2010a (which I'm stuck with), but you can just as easily replace this with integral() available on anything newer than R2012a.
Here's the code I ended up with:
function pwr = my_fcn()
% Parameters
n0 = 1; % air
n1 = 1.4; % layer 1
n2 = 2.62; % layer 2
n3 = 3.5; % silicon
L0 = 650e-9; % centre wavelength
% Reflection coefficients
r01 = (n0 - n1)/(n0 + n1);
r12 = (n1 - n2)/(n1 + n2);
r23 = (n2 - n3)/(n2 + n3);
% Transmission coefficients
t01 = (2*n0) / (n0 + n1);
t12 = (2*n1) / (n1 + n2);
t23 = (2*n2) / (n2 + n3);
% Quality factors
Q1 = [1 r01; r01 1];
Q2 = [1 r12; r12 1];
Q3 = [1 r23; r23 1];
% Initial & Final wavelengths
L_initial = 200e-9;
L_final = 2200e-9;
% plot reflectivity for selected lambda range
plot_reflectivity(L_initial, L_final, 1000);
% Compute power production
pwr = quadgk(#power_production, L_initial, L_final);
% Helper functions
% ========================================
% Graph of lambda vs reflectivity
function plot_reflectivity(L_initial, L_final, N)
L = linspace(L_initial, L_final, N);
R = zeros(size(L));
for ii = 1:numel(L)
% Transmission
T = transmittivity(L(ii));
% Percent reflectivity
R(ii) = 100 * abs(T(2,1)/T(1,1))^2 ;
end
plot(L, R)
title('Percent Reflectance vs. wavelength for 2 Layers')
xlabel('Wavelength (m)')
ylabel('Reflectance (%)')
end
% Compute transmittivity matrix for a single wavelength
function T = transmittivity(L)
% Layer phase thickness with variable Lamda
y = pi/2 * L0/L;
% Matrix P with variable Lambda
P1 = [exp(+1j*y) 0
0 exp(-1j*y)];
% Transmittivity matrix T1
T = 1/(t01*t12*t23) * Q1*P1*Q2*P1*Q3;
end
% Power for a specific wavelength. Note that this function
% accepts vector-valued wavelengths; needed for quadgk()
function pwr = power_production(L)
pwr = zeros(size(L));
for ii = 1:numel(L)
% Transmittivity matrix
T1 = transmittivity(L(ii));
% Blackbody Irradiance
I = 6.16^(15) / ( (L(ii)*1e+9)^5 * (exp(2484/(L(ii)*1e+9)) - 1) );
% final transmittivity
Tf2 = abs(1/T1(1))^2 * n3/n0;
% Power before integration
pwr(ii) = Tf2 * I;
end
end
end
My friends and I have been struggling to generate a 2-D plot in MATLAB with
$\eta_1$ and $\eta_2$ both varying in $0:0.01:1$ and the z-axis given by color.
We have a system of 8 differential equations, with HIVinf representing the total new HIV infections in a population over 1 year (HIVinf is obtained by integrating a function of $\eta_1, \eta_2$).
We are looping through $\eta_1$ and $\eta_2$ (two 'for' loops) with the ode45 solver within the 'for' loops.
Based on our prior numerical results, we should be getting much color variation in the 2D-plot. There should be patterns of darkness (high concentration of HIVinfections) along the edges of the plot, and lightness along the diagonals (low concentrations).
However, the following snippet does not produce what we want (I have attached the figure below).
[X,Y] = meshgrid(eta_11,eta_22);
figure;
pcolor(X,Y,AA);
shading interp;
I have attached the code below, as concisely as possible. The function ydot works fine (it is required to run ode45).
We would greatly appreciate if you could help us fix the snippet.
function All()
global Lambda mu mu_A mu_T beta tau eta_1 eta_2 lambda_T rho_1 rho_2 gamma
alpha = 20;
TIME = 365;
eta_11 = zeros(1,alpha);
eta_22 = zeros(1,alpha);
AA = zeros(1,alpha);
BB = zeros(1,alpha);
CC = zeros(1,alpha);
for n = 1:1:alpha
for m = 1:1:alpha
Lambda = 531062;
mu = 1/25550;
mu_A = 1/1460;
mu_T = 1/1825;
beta = 187/365000;
tau = 4/365;
lambda_T = 1/10;
rho_1 = 1/180;
rho_2 = 1/90;
gamma = 1/1000;
eta_1 = (n-1)./(alpha-1);
eta_11(m) = (m-1)./(alpha-1);
eta_2 = (m-1)./(alpha-1);
eta_22(m) = (m-1)./(alpha-1);
y0 = [191564208, 131533276, 2405629, 1805024, 1000000, 1000000, 500000, 500000];
[t,y] = ode45('SimplifiedEqns',[0:1:TIME],y0);
N = y(:,1)+y(:,2)+y(:,3)+y(:,4)+y(:,5)+y(;,6)+y(:,7)+y(:,8);
HIVinf1=[0:1:TIME];
HIVinf2=[beta.*(S+T).*(C1+C2)./N];
HIVinf=trapz(HIVinf1,HIVinf2);
AA(n,m) = HIVinf;
end
end
[X,Y] = meshgrid(eta_11,eta_22);
figure;
pcolor(X,Y,AA);
shading interp;
function ydot = SimplifiedEqns(t,y)
global Lambda mu mu_A mu_T beta tau eta_1 eta_2 lambda_T rho_1 rho_2 gamma
S = y(1);
T = y(2);
H = y(3);
C = y(4);
C1 = y(5);
C2 = y(6);
CM1 = y(7);
CM2 = y(8);
N = S + T + H + C + C1 + C2 + CM1 + CM2;
ydot = zeros(8,1);
ydot(1)=Lambda-mu.*S-beta.*(H+C+C1+C2).*(S./N)-tau.*(T+C).*(S./N);
ydot(2)=tau.*(T+C).*(S./N)-beta.*(H+C+C1+C2).*(T./N)-(mu+mu_T).*T;
ydot(3)=beta.*(H+C+C1+C2).*(S./N)-tau.*(T+C).*(H./N)-(mu+mu_A).*H;
ydot(4)=beta.*(H+C+C1+C2).*(T./N)+tau.*(T+C).*(H./N)- (mu+mu_A+mu_T+lambda_T).*C;
ydot(5)=lambda_T.*C-(mu+mu_A+rho_1+eta_1).*C1;
ydot(6)=rho_1.*C1-(mu+mu_A+rho_2+eta_2).*C2;
ydot(7)=eta_1.*C1-(mu+rho_1+gamma).*CM1;
ydot(8)=eta_2.*C2-(mu+rho_2+gamma.*(rho_1)./(rho_1+rho_2)).*CM2+(rho_1).*CM1;
end
end
Ok, I don't really know much about how the plot should look like, but your eta_11 and eta_22 are variables which are indexed only on the inner loop. That means that when n=1, m=1,2,3,...,alpha your eta_11/eta_22 will be a vector whose elements 1,2,3,...,alpha will be overwritten for every n. Since your meshgrid is outside of the loop, that could be a problem. Usually if you are plotting functions of two variables and you have said variables in 2 nested loops you just ignore the meshgrid. Like this
Option 1:
x=[0:0.01:1];
[x1,x2]=meshgrid(x,x);
y=x1+cos(x2);
contour(x,x,y,30);
Option 2
x=[0:0.01:1];
for i=1:101 %length(x)
for j=1:101
y(i,j)=x1(i)+cos(x2(j)); % It is important to index y with both
% loop variables
end
end
contour(x,x,y,30)
I am having some issues implementing multiple functions in the same m file. The following code includes three functions which are called in the function HeatTransferModel. If I set up the m file exactly like the following, it is unable to recognize the functions RadOnly,analytica and RadConv. However, if I create separate m file for RadOnly,analytica and RadConv, the code works. Do you know why? How can I integrate all these functions in one m file? Sorry about all the unnecessary information.
function HeatTransferModel
global e rho sigma c V Arad Twall Ti tend h Tinf
e = 0.87;
rho = 770; %kg/m3
sigma = 5.67E-08; %Stefan Boltzman constant
c = 1900; %Heat capacity of white oak wood
Lavg = 0.3686;
Wavg = 0.08382;
Havg = 0.05715;
V = 10*Lavg*Wavg*Havg; %Volume of the lumped wood
Arad =2*(Lavg*3*Havg) + 2*(3*Havg*3*Wavg) + Lavg*3*Wavg ; %Surface area of the lump that is exposed to radiation
Twall = 755; %Wall temperature of the furnace
Ti = 300; %Initial temperature of the wood when it is thrown in the furnace
tend = 500; %Seconds
h = 10;
Tinf = 500; %Temperature of the incoming air
[timeODE,TODE] = ode45('RadOnly',[0:1:tend],Ti);
[timeRadConv,TRadConv] = ode45('RadConv',[0,tend],Ti);
timeanalytical = analytical(TODE);
plot(timeODE,TODE,timeanalytical,TODE,timeRadConv,TRadConv);
legend('ODE Solver','Analytical Solution','RadConv');
title('Lumped Capacitance Model')
xlabel('Time [s]')
ylabel('Bulk Wood Temperature [K]')
end
function RadiationODE = RadOnly(t,T)
global e rho sigma c V Arad Twall h Tinf
RadiationODE = -e*Arad*sigma*(T^4 - Twall^4)/(rho*V*c);
end
function time = analytical(T)
global e rho sigma c V Arad Twall Ti
time = ((rho*V*c)./(4*e*Arad*sigma*Twall^3)).*( log( abs((Twall + T)./(Twall-T))) - log(abs((Twall + Ti)./(Twall-Ti))) + 2*( atan(T./Twall) - atan(Ti/Twall)));
end
function RadConvODE = RadConv(t,T)
global e rho sigma c V Arad Twall h Tinf
RadConvODE = -e*Arad*sigma*(T.^4 - Twall^4)./(rho*V*c) + (h*Arad.*(T - Tinf))./(rho*V*c);
end
You can't pass subfunction handles to Ode45, because that is in a different workspace than the primary function.
I wrote this Matlab program that is supposed to solve the IVP du/dx= -5000(u(t) - cos(t)) - sin(t) with u(0)=1. My exact solution should be u(t) = cos(t) but the solution I am getting from Euler's forward in my code is huge in comparison to what it should be and what I calculated but I'm not sure where I've gone wrong in my code. Can you find my error?
function main
dt=5;
u0 = 1;
n=50;
[T,U] = euler(dt, u0, n);
uexact = cos(T);
plot(T,U)
hold on
plot(T, uexact, 'r')
end
function [T,U]= euler( dt, u0, n)
R= dt/n;
T=zeros(1,n+1);
U=zeros(1,n+1);
U(1)=u0;
T(1) = 0;
for j=1:n
U(j+1)= U(j)+ R*(rhs(T(j),U(j)));
T(j+1)= T(j) + R;
end
end
function dP = rhs(t, P)
P = zeros(1,1);
dP = (-5000)*(P - cos(t)) - sin(t);
end
You don not have to set P = zeros(1,1) insde the function that approximate de derivative with the formula.
Moreover, the problem you have is the [numerical unstability of forward Euler method][1]. You need a very small time step to make it converge (because of the large coefficient of P inside function dP).
function main
dt=5;
u0 = 1;
n=50000; % increase the number or subintervals (smaller time step) to get stability
[T,U] = euler(dt, u0, n);
uexact = cos(T);
plot(T,U,'bs')
hold on
plot(T, uexact, 'r')
end
function [T,U]= euler( dt, u0, n)
R= dt/n;
T=zeros(1,n+1);
U=zeros(1,n+1);
U(1)=u0;
T(1) = 0;
for j=1:n
% Implicit method converges
% U(j+1) = ( U(j) - R*(-5000)*cos(T(j)) - R*sin(T(j)))/(1 - R*(-5000));
U(j+1)= U(j)+ R*(rhs(T(j),U(j)));
T(j+1)= T(j) + R;
end
end
function dP = rhs(t, P)
%P = zeros(1,1); %% It must not be here
dP = (-5000)*(P - cos(t)) - sin(t);
end
[1]: http://en.wikipedia.org/wiki/Euler_method