rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
rb_simulation_impes_impl.m
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
5 % assumed to be set by IDetailedModel.set_mu()
6 %
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: ---
12 %
13 % The behaviour of this simulation is controlled by the ModelDescr structure
14 % 'rmodel.descr'.
15 %
16 % Parameters:
17 % reduced_data: of type TwoPhaseFlow.EiRbReducedDataNode
18 %
19 % generated fields of rb_sim_data:
20 % a : 'a(:,k)' is the coefficient vector of the reduced simulation at time
21 % `t^{k-1}`
22 %
23 
24 %if ~(nargin == 2)
25 % error('wrong number of arguments: should be 2');
26 %end
27 
28 if rmodel.verbose >= 10
29  disp(['performing simulation for mu = ',mat2str(get_mu(rmodel))]);
30 end;
31 
32 % set init data
33 rmodel.decomp_mode = 2;
34 
35 sat0Ind = get_index(reduced_data, 'sat_init', get_mu(rmodel), rmodel.t);
36 rd_sat0 = get(reduced_data, sat0Ind);
37 
38 descr = rmodel.descr;
39 
40 sat_a0 = lincomb_sequence(rd_sat0, descr);
41 
42 % perform simulation loop in time
43 descr.dt = descr.T/descr.nt;
44 
45 sat_N = get_N(rmodel, 'saturation');
46 vel_N = get_N(rmodel, 'velocity');
47 prs_N = get_N(rmodel, 'pressure');
48 descr.prs_N = prs_N;
49 
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);
55 
56 sat_a(:,1) = sat_a0(1:sat_N);
57 
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);
63 
64 if nargin == 4
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);
69 end
70 
71 % loop over time steps: computation of a(t+1)==a^t
72 for t = 1:descr.nt
73  descr.t = (t-1)*descr.dt;
74  descr.tstep = t;
75  if rmodel.verbose >= 10
76  disp(['entered time-loop step ',num2str(t)]);
77  end;
78  fprintf('.');
79 
80  UP_last = [vel_a(:,t); prs_a(:,t)];
81  descr.t = descr.t + descr.dt;
82 
83  fsolve_fun_imp = @(X) sat_fun_imp(descr, sat_a(:,t), X, rd_sat, rd_vel, rd_div, rd_prs);
84 
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);
90 
91  exflags(t) = exitflag;
92  outtext{t} = output;
93 
94  vel_a(:, t+1) = UP_new(1:vel_N);
95  prs_a(:, t+1) = UP_new(vel_N+1:end);
96 
97  sat_a(:, t+1) = sat_a(:,t) - descr.dt * sat_fun_es(descr, rd_sat, vel_a(:, t+1), sat_a(:,t));
98 
99 end
100 
101 if rmodel.enable_error_estimator
102  error('error estimator is not implemented yet.');
103  rb_sim_data.Delta = 0;
104 end
105 
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;
112 
113 end
114 
115 function [reduced_data_op] = get_reduced_data_for_operator(id, rmodel, reduced_data)
116 
117  crbInd = get_index(reduced_data, id, get_mu(rmodel), rmodel.t);
118  reduced_data_op = get(reduced_data, crbInd);
119 
120 
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)) )
124 
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);
129  end
130 end
131 
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;
135 
136  msatsat = size(rd_sat.RB_local_ext.S,1);
137  Xsat.Uoff = msatsat;
138  sat_ret = descr.L_saturation.apply(descr, rd_sat, Xsat, rd_sat.TM_local);
139  ret = rd_sat.CE * sat_ret;
140 end
141 
142 function [ret, J] = sat_fun_imp(descr, Sold, X, rd_sat, rd_vel, rd_div, rd_prs)
143 
144  vel_N = size(rd_sat.RB_local_ext.U, 2);
145  prs_N = descr.prs_N;
146 
147 
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);
151  else
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);
156  Xvel.Poff = mvelsat;
157  Xvel.n = vel_N;
158  % Xvel.Uoff = mvelsat;
159  [vel_ret, dummy, vel_Jret] = descr.L_velocity.apply(descr, rd_vel, Xvel, rd_vel.TM_local);
160 
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);
176 
177 % vel_ret = rd_vel.CE * vel_ret - X(1:vel_N);
178  end
179 
180 
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));
185 
186  ret = [vel_ret; div_ret; prs_ret];
187 
188  if nargout > 1
189 
190  if descr.linear_velocity
191  vel_Jret = [zeros(size(vel_Jret,1), vel_N), vel_Jret];
192  else
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 ];
196  end
197 
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 ];
202  end
203 end
204 
205 function Xproj = box_projection(X, Slength)
206 
207  Xproj = X;
208 
209 end