2 % Implicit Euler discretization of a finite-difference convection-diffusion
5 % This model is constructed in such a way, that it can follow a given
6 % trajectory - or at least it tries to follow it. Use the SIMULATE
function
9 % Andreas Schmidt, 2016
13 mu_names = {
'mu_diffusion',
'mu_adv_y',
'lambda_tracking'};
14 mu_ranges = { [0.1, 2], [0,10], [1, 10]};
27 this.RB_orthonormalize_E = false;
28 this.RB_error_indicator = 'normalized_residual';
29 this.RB_pod_tolerance = 0.85;
30 this.RB_greedy_tolerance = 1e-3;
34 function r = E_comp(this)
35 r = {speye(this.n), ...
36 blkdiag(this.my_2d_matrix(this.n0,
'0',
'0',
'0',
'1'),0) ...
37 blkdiag(this.my_2d_matrix(this.n0,
'0',
'-1',
'0',
'0'),0)};
39 function r = E_coeff(
this)
40 r = [1, -this.dt*this.mu(1), -this.dt*this.mu(2)];
43 function r = A_comp(this)
45 r = {[speye(this.n-1), zeros(this.n-1,1); -C 1]};
47 function r= A_coeff(
this)
51 function r = B_comp(this)
52 v = this.my_2d_vector(this.n0, '( (x>=0.2)&(x<=0.6)&(y>=0.4)&(y<=0.6) )');
53 r = {[10*1/numel(nonzeros(v))*v;0]};
55 function r = B_coeff(
this)
60 v = this.my_2d_vector(this.n0, '1')';
61 r = v/numel(nonzeros(v));
64 function r = C_comp(this)
65 r = {[this.C(), 0], [zeros(1,this.n-1) 1]};
67 function r = C_coeff(
this)
70 function r = R_coeff(this)
74 function s = get_ss(this, model_data, dsim)
75 % GET_SS Get the state space model for simulation purpose
76 % If dsim is provided, a closed-loop simulation is performed.
77 [E,A,B,C,~,R] = this.assemble(model_data);
78 outputName = {
'y(t)',
'u(t)'};
81 if exist(
'dsim',
'var') && ~isempty(dsim)
82 K = inv(R+B'*dsim.Z*dsim.Z'*B)*B'*dsim.Z*dsim.Z'*A;
89 s = dss(A, [B, [zeros(this.n-1,1); 1]], C, [], full(E),this.dt, ...
90 'InputName', {
'u(t)',
'r(t)'}, ...
91 'OutputName', outputName);
94 function [t,y,u,r,x] = simulate(
this, model_data, T, r, sim, x0)
95 % SIMULATE - Simulate the system
for a given time
97 % r ...... reference value or vector
98 % sim .... simulation used
for feedback
100 % This
function returns the following vectors:
101 % t ....... time span
for simulation
102 % y ....... output value
103 % u ....... control signal
104 % r ....... the reference signal
106 if nargin < 5, sim = []; end
107 if nargin < 6, x0 = zeros(this.n,1); end
109 t = (0:this.dt():T)
';
110 if isa(r, 'function_handle
'), r = r(t); end
111 if length(r) == 1, r = ones(length(t),1)*r; end
113 ss = this.get_ss(model_data, sim);
115 [y_,t,x] = lsim(ss, [0*t, r], t, x0);
122 methods(Access=protected)
123 function [A, name] = my_2d_matrix(this,n0,fx_str,fy_str,g_str,mu_str)
125 % Generates the stiffness matrix A for the finite difference
126 % discretization (equidistant grid) of the PDE
128 % mu* laplace(u) - fx du/dx - fy du/dy - g u = r.h.s. on Omega
132 % Omega = (0,1)x(0,1) (unit square).
134 % This function is just used as an easy way to generate test problems
135 % rather than to solve PDEs.
139 % [A, name] = fdm_2d_matrix( n0, fx_str, fy_str, g_str )
143 % n0 number of inner grid points in each dimension;
144 % fx_str string describing the function fx in the space variables
145 % 'x
' and 'y
', e.g., fx_str = 'sin(x+2*y)+3
';
146 % fy_str string describing the function fy in the space variables
148 % g_str string describing the function g in the space variables
153 % A n-x-n sparse stiffness matrix, where n = n0^2;
154 % name string describing the problem.
157 % LYAPACK 1.0 (Thilo Penzl, May 1999)
159 % Input data not completely checked!
167 name = ['FDM-2D: fx=
',fx_str,'; fy=
',fy_str,'; g=
',g_str];
198 ptr = ptr+1; % A(i,i-n)
201 S(ptr) = mu*t2-fyv*t3;
205 ptr = ptr+1; % A(i,i-1)
208 S(ptr) = mu*t2-fxv*t3;
211 ptr = ptr+1; % A(i,i)
217 ptr = ptr+1; % A(i,i+1)
220 S(ptr) = mu*t2+fxv*t3;
224 ptr = ptr+1; % A(i,i+n0)
227 S(ptr) = mu*t2+fyv*t3;
233 A = -sparse(I,J,S,n2,n2);
236 function v = my_2d_vector(this,n0,f_str)
238 % Generates a vector v which contains the values of a function f(x,y)
239 % on an equidistant grid in the interior of the unit square. The grid
240 % points are numbered consistently with those used in the function
243 % This function is just used as an easy way to generate test problems
244 % rather than to solve PDEs.
248 % v = fdm_2d_vector( n0, f_str)
252 % n0 number of inner grid points in each dimension;
253 % f_str string describing the function f in the space variables 'x
'
254 % and 'y
', e.g., f_str = 'sin(x+2*y)+3
'.
258 % v vector of order n = n0^2 containing the values of f(x,y).
261 % LYAPACK 1.0 (Thilo Penzl, May 1999)
263 % Input data not completely checked!
268 error('Wrong number of input parameters.
');
MODEL Main class for the DARE model.
Implicit Euler discretization of a finite-difference convection-diffusion model.
Implementation of the parametric discrete-time algebraic Riccati equation.