1 function rb_sim_data = rb_simulation_impes_impl(rmodel, reduced_data, sim_data, dd)
2 %
function rb_sim_data = rb_simulation_impl(rmodel, reduced_data)
3 %
function, which performs a reduced basis online simulation
for
4 % the parameter vector `\mu \in {\cal P} \subset \mathbb{R}^p`, which is
7 % - allowed dependency of data: Nmax, Mmax, N, M, mu
8 % - not allowed dependency of data: H
9 % - allowed dependency of computation: Nmax, Mmax, N, M, mu
10 % - not allowed dependency of computation: H
11 % - Unknown at this stage: ---
13 % The behaviour of this simulation is controlled by the ModelDescr structure
17 % reduced_data: of type TwoPhaseFlow.EiRbReducedDataNode
19 % generated fields of rb_sim_data:
20 % a : 'a(:,k)' is the coefficient vector of the reduced simulation at time
25 % error(
'wrong number of arguments: should be 2');
28 if rmodel.verbose >= 10
29 disp([
'performing simulation for mu = ',mat2str(get_mu(rmodel))]);
33 rmodel.decomp_mode = 2;
35 sat0Ind = get_index(reduced_data,
'sat_init', get_mu(rmodel), rmodel.t);
36 rd_sat0 =
get(reduced_data, sat0Ind);
40 sat_a0 = lincomb_sequence(rd_sat0, descr);
42 % perform simulation loop in time
43 descr.dt = descr.T/descr.nt;
45 sat_N = get_N(rmodel,
'saturation');
46 vel_N = get_N(rmodel,
'velocity');
47 prs_N = get_N(rmodel,
'pressure');
50 sat_a = zeros(sat_N, descr.nt+1); % matrix of saturation RB-coefficients
51 vel_a = zeros(vel_N, descr.nt+1); % matrix of velocity RB-coefficients
52 prs_a = zeros(prs_N, descr.nt+1); % matrix of pressure RB-coefficients
53 exflags = zeros(1, descr.nt+1);
54 outtext = cell(1, descr.nt+1);
56 sat_a(:,1) = sat_a0(1:sat_N);
58 [rd_sat] = get_reduced_data_for_operator(
'L_saturation', rmodel, reduced_data);
59 [rd_vel] = get_reduced_data_for_operator(
'L_velocity', rmodel, reduced_data);
60 [rd_prs] = get_reduced_data_for_operator(
'L_pressure_mean', rmodel, reduced_data);
61 rd_divInd = get_index(reduced_data,
'L_divergence', get_mu(rmodel), rmodel.t);
62 rd_div =
get(reduced_data, rd_divInd);
65 dd_vel = get_by_description(dd.datatree.rb,
'velocity');
66 dd_prs = get_by_description(dd.datatree.rb,
'pressure');
67 vel_a(:,1) = dd_vel.RB
' * dd.model_data.diamondW * sim_data.U(:,2);
68 prs_a(:,1) = dd_prs.RB' * dd.model_data.W * sim_data.P(:,2);
71 % loop over time steps: computation of a(t+1)==a^t
73 descr.t = (t-1)*descr.dt;
75 if rmodel.verbose >= 10
76 disp([
'entered time-loop step ',num2str(t)]);
80 UP_last = [vel_a(:,t); prs_a(:,t)];
81 descr.t = descr.t + descr.dt;
83 fsolve_fun_imp = @(X) sat_fun_imp(descr, sat_a(:,t), X, rd_sat, rd_vel, rd_div, rd_prs);
85 gplmmopts.Px = @(X) box_projection(X, sat_N);
86 gplmmopts.debug =
false;
87 gplmmopts.TolRes = 1e-7;
88 % gplmmopts.HessFun = @(params, jac, dummy, arg) jac
' * (jac * arg);
89 [UP_new, resnorm, FV, exitflag, output] = gplmm(fsolve_fun_imp, UP_last, gplmmopts);
91 exflags(t) = exitflag;
94 vel_a(:, t+1) = UP_new(1:vel_N);
95 prs_a(:, t+1) = UP_new(vel_N+1:end);
97 sat_a(:, t+1) = sat_a(:,t) - descr.dt * sat_fun_es(descr, rd_sat, vel_a(:, t+1), sat_a(:,t));
101 if rmodel.enable_error_estimator
102 error('error estimator is not implemented yet.
');
103 rb_sim_data.Delta = 0;
106 % prepare return parameters
107 rb_sim_data.sat_a = sat_a;
108 rb_sim_data.vel_a = vel_a;
109 rb_sim_data.prs_a = prs_a;
110 rb_sim_data.exit_flags = exflags;
111 rb_sim_data.outputs = outtext;
115 function [reduced_data_op] = get_reduced_data_for_operator(id, rmodel, reduced_data)
117 crbInd = get_index(reduced_data, id, get_mu(rmodel), rmodel.t);
118 reduced_data_op = get(reduced_data, crbInd);
121 if isa(reduced_data_op, 'TwoPhaseFlow.EiRbReducedDataNode
') ...
122 && ( isempty(reduced_data_op.CE) ...
123 || any(size(reduced_data_op.CE) ~= size(reduced_data_op.DE)) )
125 M = reduced_data_op.M;
126 reduced_data_op.CE = reduced_data_op.DE / reduced_data_op.BM;
127 reduced_data_op.CE_red = reduced_data_op.DE(:,1:M) ...
128 / reduced_data_op.BM(1:M, 1:M);
132 function ret = sat_fun_es(descr, rd_sat, vel_a, sat_a)
133 Xsat.S = rd_sat.RB_local_ext.S * sat_a;
134 Xsat.U = rd_sat.RB_local_ext.U * vel_a;
136 msatsat = size(rd_sat.RB_local_ext.S,1);
138 sat_ret = descr.L_saturation.apply(descr, rd_sat, Xsat, rd_sat.TM_local);
139 ret = rd_sat.CE * sat_ret;
142 function [ret, J] = sat_fun_imp(descr, Sold, X, rd_sat, rd_vel, rd_div, rd_prs)
144 vel_N = size(rd_sat.RB_local_ext.U, 2);
148 if descr.linear_velocity
149 vel_Jret = lincomb_sequence(rd_vel, descr);
150 vel_ret = vel_Jret * X(vel_N+1:end) - X(1:vel_N);
152 Xvel.S = rd_vel.RB_local_ext.S * Sold;
153 % Xvel.U = rd_vel.RB_local_ext.U * X(sat_N+1:sat_N+vel_N);
154 Xvel.P = rd_vel.RB_local_ext.P * X(vel_N+1:end);
155 mvelsat = size(rd_vel.RB_local_ext.S,1);
158 % Xvel.Uoff = mvelsat;
159 [vel_ret, dummy, vel_Jret] = descr.L_velocity.apply(descr, rd_vel, Xvel, rd_vel.TM_local);
161 dd = evalin('base
', 'dd
');
162 dd_sat = get_by_description(dd.datatree.rb, 'saturation
');
163 dd_vel = get_by_description(dd.datatree.rb, 'velocity
');
164 dd_prs = get_by_description(dd.datatree.rb, 'pressure
');
165 dd_Lvel = get_by_description(dd.datatree.ei, 'L_velocity
');
166 dd_Xvel.S = dd_sat.RB * Sold;
167 dd_Xvel.P = dd_prs.RB * X(vel_N+1:end);
168 dd_ret = descr.L_velocity.apply(descr, dd.model_data, dd_Xvel);
169 vel_ret_recon_sigma = dd_Lvel.BM \ vel_ret;
170 vel_ret_recon = dd_Lvel.QM * vel_ret_recon_sigma;
171 debug_diff = vel_ret_recon - dd_ret;
172 disp(['linfty-norm:
', num2str(max(abs(debug_diff))), ...
173 ' l2-norm:
', num2str(sqrt(debug_diff' * dd.model_data.diamondW * debug_diff))]);
174 disp([
'TM-linfty-norm: ', num2str(max(abs(dd_ret(dd_Lvel.TM) - vel_ret)))]);
175 vel_ret = dd_vel.RB
' * dd.model_data.diamondW * vel_ret_recon - X(1:vel_N);
177 % vel_ret = rd_vel.CE * vel_ret - X(1:vel_N);
181 [div_Jret, div_bb] = lincomb_sequence(rd_div, descr);
182 prs_Jret = lincomb_sequence(rd_prs, descr);
183 div_ret = div_Jret * (X(1:vel_N)) + div_bb;
184 prs_ret = prs_Jret * (X(vel_N+1:end));
186 ret = [vel_ret; div_ret; prs_ret];
190 if descr.linear_velocity
191 vel_Jret = [zeros(size(vel_Jret,1), vel_N), vel_Jret];
193 vel_Jret = rd_vel.CE * ...
194 [ zeros(size(vel_Jret,1), vel_N), ...
195 vel_Jret(:,mvelsat+1:end) * rd_vel.RB_local_ext.P ];
198 sp_minus_U = sparse(1:vel_N, 1:vel_N, -1, vel_N, size(vel_Jret,2));
199 J = [ vel_Jret + sp_minus_U;...
200 div_Jret, zeros(size(div_Jret,1),prs_N);
201 zeros(1, vel_N), prs_Jret ];
205 function Xproj = box_projection(X, Slength)