I'm currently working on a project to build a solar food dryer and I need to model on Matlab how temperature of the product will change with respect to change in solar radiation, Q .
Q is given by ;
Q =960*(sin(2*pi*Time2/24)).^2; %W/m2
where
Time2 = (1:t:12); %hours
The heat flow equation is given by
Q(t)A = mcp*(T2-T1) + (mw*lw)
where :
mw = 0.706; % Mass of water loss from product in hr (Kg/h)
m = 15; % Mass of product to dry (Kg)
lw = 2260000; % Latent heat of vaporisation of water (J/Kg)
A = 1; % Surface Area of collector (m^2)
cp= 3746; % Specific heat capacity of product (J/Kg/C)
T1 = temperature at t
T2 = temperature at t + dt
Manipulating the heat flow give T2 as ;
T2= (((Q*A*3600) -(mw*lw))/(m*cp)) + T1; % 3600 is there to convert j/s to J/h
however implementing this on Matlab is proving a challenge for me- I'm fairly new to Matlab
This is what I have so far ;
close all
clear;
mw = 0.706; % Mass of water loss from product in hr (Kg/h)
m = 15; % Mass of product to dry (Kg)
lw = 2260000; % Latent heat of vaporisation of water (J/Kg)
A = 1; % Surface Area of Collector (m^2)
cp= 3746; % Specific heat capacity of product (J/Kg/C)
t = 1; % Time step
T = 24; % Initial Temperature (°C)
Time2=(1:t:12); hours
Q=960*(sin(2*pi*Time2/24)).^2; % Solar irradiation in tropical regions at specific time (W/m2)
for j = 1:12
T(j+1)= ((((QQ2(j)*A*j*3600))-(mw*lw))/(m*cp))+ T(1);
end
figure(2)
plot(T)
title('Temperature')
xlabel('time (hours)')
ylabel('Temperature (°C)')
This seems wrong since the mass, m should decrease by mw after each hr and the temperature profile should follow the profile of the solar radiation. i.e peak at the same time
I have been spending days to get my head around this but i'm pretty bad at Matlab so I haven't made any meaningful progress. Any help will be appreciated
So I am not sure if this is what you are looking for Ran, but there are a few points that looked like typos (?) and these would change behaviour. You have QQ2(j) suddenly appears in the middle of your script... I presumed that was just Q[j). Each cycle of your loop you add to t(1) and I think you meant t(j)? And surely the loop should also decrease the m?
So I modified to this...
for j = 1:12
T(j+1)= ((((Q(j)*A*j*3600))-(mw*lw))/(m*cp))+ T(j);
m=m-mw*t;
end
Now T peaks at 12noon.
All that said, I would think a problem like this would be better solved with a differential equation solver like ‘ode45()’, but I would need to see that differential equation before advising how to do that in Matlab, but it shouldn’t be too tricky!
### Hello again Ran, OK you have added the dydx in the the comments now so here is how I would approach this problem, (accepting I don’t know much about this equation itself!):
clear;
global conv;
conv=60*60;
mw = 0.706/conv; % Mass of water loss from product in hr (Kg/h)
m = 15.0; % Mass of product to dry (Kg)
lw = 2260000.0; % Latent heat of vaporisation of water (J/Kg)
A= 1.0; % Surface Area of Collector (m^2)
cp= 3746.0; % Specific heat capacity of product (J/Kg/C)
T = 24.0; % Initial Temperature (°C)
%%
%% for j = 1:12
%% T(j+1)= ((((Q(j)*A*j*3600))-(mw*lw))/(m*cp))+ T(j);
%% m=m-mw*t;
%% end
tspan = [0, 12*conv];
yo=[T;m];
[t,y] = ode45(#(t,y) ode(t, y,[A,mw,lw,cp]), tspan, yo);
yfinal=y;
figure (1)
plot(t./conv,yfinal(:,1))
title('Temperature')
xlabel('time (hours)')
ylabel('Temperature (°C)')
figure (2)
tqs=linspace(0,12);
Qt=960.0*(sin(2.0.*pi.*tqs./(24.0))).^2;
plot(tqs,Qt);
function dydt=ode(t,y,x)
global conv;
A =x(1);
mw =x(2);
lw =x(3);
cp =x(4);
m=y(2);
Q=960*(sin(2*pi*t/(24*conv)))^2; % Solar irradiation in tropical regions at specific time (W/m2)
dydt=[((Q * A)-(mw*lw))/(m*cp);-mw];
end
This gives this output, I think the equations will need a fiddle, but hopefully the structure of the ODE helps?
P.s., I am not convinced that peak temperature would match peak heat input since usually there is a lag. Hottest part of the day is often 3pm in the UK... but I haven’t looked at heat transfer since High School...
Regards R
Related
I am working on the cross-correlation of two signals to calculate delay. But somehow, I could not calculate the delay correctly.
i1, i2, and ti1: data link
here is code:
t = ti1; % 1x2097152 double
t_Step = t(2)-t(1);
t_tmp = [-flip(t(2:end)),t];
x = i1; %1x2097152 complex double
y = i2; % 1x2097152 complex double
corrL=length(x)+length(y)-1;
X=fft(x,corrL); % FFT of x
Y=fft(y,corrL); % FFT of y
Z=X.*(conj(Y)); % Hadamard Product/ frequeny domain
z=fftshift(ifft(Z)); % time domain convertion
Ly=length(z);
tz= t_tmp;
[~,idz] = max(z) % find the index at max point of z
TD = tz(idz)*t_Step % Time Delay
if(TD<0)
distance = -TD * 204357.1915 % speed of light in specific indise is 204357.1915 distance calculation
else(TD<0)
distance = TD * 204357.1915
end
%Plot Section
%Original and delayed signal
plot(t,x,'r',t,y,'g');
legend('Original','Delayed');
%Cross Correlated Signal
[z_max, index] = max(imag(z))
figure
%plot(tz,z,tz(index),y(index),'o'); hold on
plot(tz,z,tz(index),z_max,'o')
xlabel('Time');
ylabel('Magnitude');
title('z signal');
grid
Here is the marked signal which puts the mark in the wrong place:
I was expected to put the mark at the max amplitude point, so somehow I could not put the mark at the extremum point of amplitude. Could you help me to fix that?
I'm trying to solve the following problem using MATLAB but I faced multiple issues. The plot I obtained doesn't seem right even though I tried to obtain the steady-state solution, I got a plot that doesn't look steady.
The problem I'm trying to solve
The incorrect plot I got.
and here is the code
% system parameters
m=1; k=1; c=.1; wn=sqrt(k/m); z=c/2/sqrt(m*k); wd=wn*sqrt(1-z^2);
% initial conditions
x0=0; v0=0;
%% time
dt=.001; tMax=8*pi; t=0:(tMax-0)/999:tMax;
% input
A=1
omega=(2*pi)/10
F=A/2-(4*A/pi^2)*cos(omega*t); Fw=fft(F);
F=k*A*cos(omega*t); Fw=fft(F);
% normalize
y = F/m;
% compute coefficients proportional to the Fourier series coefficients
Yw = fft(y);
% setup the equations to solve the particular solution of the differential equation
% by the method of undetermined coefficients
N=1000
T=10
k = [0:N/2];
w = 2*pi*k/T;
A = wn*wn-w.*w;
B = 2*z*wn*w;
% solve the equation [A B;-B A][real(Xw); imag(Xw)] = [real(Yw); imag(Yw)] equation
% Note that solution can be obtained by writing [A B;-B A] as a scaling + rotation
% of a 2D vector, which we solve using complex number algebra
C = sqrt(A.*A+B.*B);
theta = acos(A./C);
Ywp = exp(j*theta)./C.*Yw([1:N/2+1]);
% build a hermitian-symmetric spectrum
Xw = [Ywp conj(fliplr(Ywp(2:end-1)))];
% bring back to time-domain (function synthesis from Fourier Series coefficients)
x = ifft(Xw);
figure()
plot(t,x)
Your forcing function doesn't look like the triangle wave in the problem. I edited the %% time section of your code into the following and appeared to give a steady state response.
%% time
TP = 10; % forcing time period (10 s)
dt=.001;
tMax= 3*TP; % needs to be multiple of the time period
t=0:(tMax-0)/999:tMax;
% input
A=1; % Forcing amplitude
omega=(2*pi)/TP;
% forcing is a triangle wave
% generate a triangle wave with min/max values of 0/1.
F = 0*t;
for i = 1:length(t)
if mod(t(i), TP) <= TP/2
F(i) = mod(t(i), TP)/(TP/2);
else
F(i) = 2 - mod(t(i), TP)/(TP/2);
end
end
F = F*A; % scale triangle wave by amplitude
% you can also use MATLAB's sawtooth() function if you have the signal
% processing toolbox
I have a question about the use of Matlab to compute solution of stochastic differentials equations. The equations are the 2.2a,b, page 3, in this paper (PDF).
My professor suggested using ode45 with a small time step, but the results do not match with those in the article. In particular the time series and the pdf. I also have a doubt about the definition of the white noise in the function.
Here the code for the integration function:
function dVdt = R_Lang( t,V )
global sigma lambda alpha
W1=sigma*randn(1,1);
W2=sigma*randn(1,1);
dVdt=[alpha*V(1)+lambda*V(1)^3+1/V(1)*0.5*sigma^2+W1;
sigma/V(1)*W2];
end
Main script:
clear variables
close all
global sigma lambda alpha
sigma=sqrt(2*0.0028);
alpha=3.81;
lambda=-5604;
tspan=[0,10];
options = odeset('RelTol',1E-6,'AbsTol',1E-6,'MaxStep',0.05);
A0=random('norm',0,0.5,[2,1]);
[t,L]=ode45(#(t,L) R_Lang(t,L),tspan,A0,options);
If you have any suggestions I'd be grateful.
Here the new code to confront my EM method and 'sde_euler'.
lambda = -5604;
sigma=sqrt(2*0.0028) ;
Rzero = 0.03; % problem parameters
phizero=-1;
dt=1e-5;
T = 0:dt:10;
N=length(T);
Xi1 = sigma*randn(1,N); % Gaussian Noise with variance=sigma^2
Xi2 = sigma*randn(1,N);
alpha=3.81;
Rem = zeros(1,N); % preallocate for efficiency
Rtemp = Rzero;
phiem = zeros(1,N); % preallocate for efficiency
phitemp = phizero;
for j = 1:N
Rtemp = Rtemp + dt*(alpha*Rtemp+lambda*Rtemp^3+sigma^2/(2*Rtemp)) + sigma*Xi1(j);
phitemp=phitemp+sigma/Rtemp*Xi2(j);
phiem(j)=phitemp;
Rem(j) = Rtemp;
end
f = #(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1)/2;
0]; % Drift function
g = #(t,V)[sigma;
sigma/V(1)]; % Diffusion function
A0 = [0.03;0]; % 2-by-1 initial condition
opts = sdeset('RandSeed',1,'SDEType','Ito'); % Set random seed, use Ito formulation
L = sde_euler(f,g,T,A0,opts);
plot(T,Rem,'r')
hold on
plot(T,L(:,1),'b')
Thanks again for the help !
ODEs and SDEs are very different and one should not use tools for ODEs, like ode45, to try to solve SDEs. Looking at the paper you linked to, they used a basic Euler-Maruyama scheme to integrate the system. This a very simple solver to implement yourself.
Before proceeding, you (and your professor!) should take some time to read up on SDEs and how to solve them numerically. I recommend this paper, which includes many Matlab examples:
Desmond J. Higham, 2001, An Algorithmic Introduction to Numerical Simulation of Stochastic Differential Equations, SIAM Rev. (Educ. Sect.), 43 525–46. http://dx.doi.org/10.1137/S0036144500378302
The URL to the Matlab files in the paper won't work; use this one. Note, that as this a 15-year old paper, some of the code related to random number generation is out of date (use rng(1) instead of randn('state',1) to seed the generator).
If you are familiar with ode45 you might look at my SDETools Matlab toolbox on GitHub. It was designed to be fast and has an interface that works very similarly to Matlab's ODE suite. Here is how you might code up your example using the Euler-Maruyma solver:
sigma = 1e-1*sqrt(2*0.0028);
lambda = -5604;
alpha = 3.81;
f = #(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1);
0]; % Drift function
g = #(t,V)[sigma;
sigma/V(1)]; % Diffusion function
dt = 1e-3; % Time step
t = 0:dt:10; % Time vector
A0 = [0.03;-2]; % 2-by-1 initial condition
opts = sdeset('RandSeed',1,'SDEType','Ito'); % Set random seed, use Ito formulation
L = sde_euler(f,g,t,A0,opts); % Integrate
figure;
subplot(211);
plot(t,L(:,2));
ylabel('\phi');
subplot(212);
plot(t,L(:,1));
ylabel('r');
xlabel('t');
I had to reduce the size of sigma or the noise was so large that it could cause the radius variable to go negative. I'm not sure if the paper discusses how they handle this singularity. You can try the 'NonNegative' option within sdeset to try to handle this or you may need to construct your own solver. I also couldn't find what integration time step the paper used. You should also consider contacting the authors of the paper directly.
UPDATE
Here's an Euler-Maruyama implementation that matches the sde_euler code above:
sigma = 1e-1*sqrt(2*0.0028);
lambda = -5604;
alpha = 3.81;
f = #(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1);
0]; % Drift function
g = #(t,V)[sigma;
sigma/V(1)]; % Diffusion function
dt = 1e-3; % Time step
t = 0:dt:10; % Time vector
A0 = [0.03;-2]; % 2-by-1 initial condition
% Create and initialize state vector (L here is transposed relative to sde_euler output)
lt = length(t);
n = length(A0);
L = zeros(n,lt);
L(:,1) = A0;
% Set seed and pre-calculate Wiener increments with order matching sde_euler
rng(1);
r = sqrt(dt)*randn(lt-1,n).';
% General Euler-Maruyama integration loop
for i = 1:lt-1
L(:,i+1) = L(:,i)+f(t(i),L(:,i))*dt+r(:,i).*g(t(i),L(:,i));
end
figure;
subplot(211);
plot(t,L(2,:));
ylabel('\phi');
subplot(212);
plot(t,L(1,:));
ylabel('r');
xlabel('t');
I am solving stochastic differential equation in matlab.
For example:
consider the stochastic differential equation
dx=k A(x,t)dt+ B(x,t)dW(t)
where k is constants, A and B are functions, and dW(t) is Wiener process.
I plot the solution for all t in [0,20]. We know that dW(t) is randomly generated. My question is: I want to know the value of A(x,t), B(x,t), dW(t) for a particular value of t and for particular sub-interval, say [3,6]. What command in Matlab I can use?
Here is the code I used based on a paper by D.Higham:
clear all
close all
t0 = 0; % start time of simulation
tend = 20; % end time
m=2^9; %number of steps in each Brownian path
deltat= tend/m; % time increment for each Brownian path
D=0.1; %diffsuion
R=4;
dt = R*deltat;
dW=sqrt( deltat)*randn(2,m);
theta0=pi*rand(1);
phi0=2*pi*rand(1);
P_initial=[ theta0; phi0];
L = m/ R;
pem=zeros(2,L);
EM_rescale=zeros(2,L);
ptemp=P_initial;
for j=1:L
Winc = sum(dW(:,[ R*(j-1)+1: R*j]),2);
theta=ptemp(1);% updating theta
phi=ptemp(2); % updating phi
%psi=ptemp(3); % updating psi
A=[ D.*cot(theta);...
0];% updating the drift
B=[sqrt(D) 0 ;...
0 sqrt(D)./sin(theta) ]; %% updating the diffusion function
ptemp=ptemp+ dt*A+B*Winc;
pem(1,j)=ptemp(1);%store theta
pem(2,j)=ptemp(2);%store phi
EM_rescale(1,j)=mod(pem(1,j),pi); % re-scale theta
EM_rescale(2,j)=mod(pem(2,j),2*pi); % re-scale phi
end
plot([0:dt:tend],[P_initial,EM_rescale],'--*')
Suppose I want to know all parameters (including random: Brownian) at each specific time point or for any time interval. How to do that?
I'm doing my best to understand your question here, but it's still a bit unclear to me.
Change the loop to:
for ii=1:L
Winc = sum(dW(:,[ R*(ii-1)+1: R*ii]),2);
theta=ptemp(1);% updating theta
phi=ptemp(2); % updating phi
A{ii}=[ D.*cot(theta);...
0];% updating the drift
B{ii}=[sqrt(D) 0 ;...
0 sqrt(D)./sin(theta) ]; %% updating the diffusion function
ptemp = ptemp + dt*A{ii}+B{ii}*Winc;
pem(:,ii) = ptemp;
EM_rescale(1,ii) = mod(pem(1,ii),pi); % re-scale theta
EM_rescale(2,ii) = mod(pem(2,ii),2*pi); % re-scale phi
end
Now, you can get the values of A and B this way:
t = 3;
t_num = round(m/tend*t);
A{t_num}
B{t_num}
ans =
0.0690031455719538
0
ans =
0.316227766016838 0
0 0.38420611784333
I have a 1D heat diffusion code in Matlab which I was using on a timescale of 10s of years and I am now trying to use the same code to work on a scale of millions of years. Obviously if I keep my timestep the same this will take ages to calculate but if I increase my timestep I encounter numerical stability issues.
My questions are:
How should I approach this problem? What affects the maximum stable timestep? And how do I calculate this?
Many thanks,
Alex
close all
clear all
dx = 4; % discretization step in m
dt = 0.0000001; % timestep in Myrs
h=1000; % height of box in m
nx=h/dx+1;
model_lenth=1; %length of model in Myrs
nt=ceil(model_lenth/dt)+1; % number of tsteps to reach end of model
kappa = 1e-6; % thermal diffusivity
x=0:dx:0+h; % finite difference mesh
T=38+0.05.*x; % initial T=Tm everywhere ...
time=zeros(1,nt);
t=0;
Tnew = zeros(1,nx);
%Lower sill
sill_1_thickness=18;
Sill_1_top_position=590;
Sill_1_top=ceil(Sill_1_top_position/dx);
Sill_1_bottom=ceil((Sill_1_top_position+sill_1_thickness)/dx);
%Upper sill
sill_2_thickness=10;
Sill_2_top_position=260;
Sill_2_top=ceil(Sill_2_top_position/dx);
Sill_2_bottom=ceil((Sill_2_top_position+sill_2_thickness)/dx);
%Temperature of dolerite intrusions
Tm=1300;
T(Sill_1_top:Sill_1_bottom)=Tm; %Apply temperature to intrusion 1
% unit conversion to SI:
secinmyr=24*3600*365*1000000; % dt in sec
dt=dt*secinmyr;
%Plot initial conditions
figure(1), clf
f1 = figure(1); %Make full screen
set(f1,'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
plot (T,x,'LineWidth',2)
xlabel('T [^oC]')
ylabel('x[m]')
axis([0 1310 0 1000])
title(' Initial Conditions')
set(gca,'YDir','reverse');
%Main calculation
for it=1:nt
%Apply temperature to upper intrusion
if it==10;
T(Sill_2_top:Sill_2_bottom)=Tm;
end
for i = 2:nx-1
Tnew(i) = T(i) + kappa*dt*(T(i+1) - 2*T(i) + T(i-1))/dx/dx;
end
Tnew(1) = T(1);
Tnew(nx) = T(nx);
time(it) = t;
T = Tnew; %Set old Temp to = new temp for next loop
tmyears=(t/secinmyr);
%Plot a figure which updates in the loop of temperature against depth
figure(2), clf
plot (T,x,'LineWidth',2)
xlabel('T [^oC]')
ylabel('x[m]')
title([' Temperature against Depth after ',num2str(tmyears),' Myrs'])
axis([0 1300 0 1000])
set(gca,'YDir','reverse');%Reverse y axis
%Make full screen
f2 = figure(2);
set(f2,'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
drawnow
t=t+dt;
end
The stability condition for an explicit scheme like FTCS is governed by $r = K dt/dx^2 < 1/2$ or $dt < dx^2/(2K)$ where K is your coefficient of diffusion. This is required in order to make the sign of the 4th order derivative leading truncation error term be negative.
If you do not want to be limited by timestep I suggest using an implicit scheme (albeit at a higher of computational cost than an explicit scheme). This can be achieved simply by using backward Euler for the diffusion term instead of forward Euler. Another option is Crank-Nicholson which is also implicit.
#Isopycnal Oscillation is totally correct in that the maximum stable step is limited in an explicit scheme. Just for reference this is usually referred to as the discrete Fourier number or just Fourier number and can be looked up for different boundary conditions.
also the following may help you for the derivation of the Implicit or Crank-Nicholson scheme and mentions stability Finite-Difference Approximations
to the Heat Equation by Gerald W. Recktenwald.
Sorry I don't have the rep yet to add comments