1 function ei_rb_proj_data = nonlin_evol_detailed_ei_rb_proj_simulation(model, detailed_data)
2 %
function ei_rb_proj_data = nonlin_evol_detailed_ei_rb_proj_simulation(model, detailed_data)
4 %
function performing a general time evolution and computing the
5 % solution DOF-vector ei_rb_proj_data.U(:,t)
for all times t=1,...,nt+1
6 % instead of the real
explicit operator, the empirical
7 % interpolation
operator given in detailed_data is used.
8 % after each timestep, a projection on the RB-space is performed.
9 % The result of
this function should be identical to a pure
10 % reduced simulation with reconstruction. Additionally, the
11 % sequence of rb-coefficients
'ei_rb_proj_data.a' is returned
13 % required fields of model:
15 % nt : number of time-intervals until T, i.e. nt+1
16 % solution slices are computed
17 % init_values_algorithm: name of
function for computing the
18 % initvalues-DOF with arguments (grid, model)
19 % example: init_values_cog
20 % implicit_operators_algorithm: name of
function for computing the
21 % L_I, b_I-operators with arguments (grid, model)
22 % example fv_operators_implicit
23 % data_const_in_time :
if this optional field is 1, the time
24 % evolution is performed with constant operators,
25 % i.e. only the initial-time-operators are computed
26 % and used throughout the time simulation.
27 % L_E_local_ptr :
function pointer to the local space-discretization
28 %
operator evaluation with syntax
30 % INC_local = L_local(U_local_ext, ind_local,
31 % grid_local_ext, model)
32 % where *_local indicates results on a set of
33 % elements, *_local_ext includes information including
34 % their neighbours, i.e. the grid must be known
35 % also
for the neighbours, the values of the
36 % previous timstep must be known on the
37 % neighbours. The subset of elements, which are
38 % to be computed are given in ind_local and the
39 % values produced are INC_local.
40 % A time-step can then be realized by
41 % NU_local = U_local_ext(ind_local) - dt * INC_local
43 % required fields of model:
44 % M : number of colateral basis vectors, that will be used
for
45 % empirical inteprolation of the
explicit operator
46 % N : number of reduced basis vectors, that will be used
for
47 % projection of the detailed simulations
48 % inner_product_matrix_algorithm: name of method that computes the
49 % matrix
for inner product computation.
51 % Bernard Haasdonk 24.6.2006
54 error(
'wrong number of parameters!');
58 disp([
'entered detailed simulation with interpolation ',...
59 'of the explicit operator and rb-projection']);
62 % prepare online-data
for online-ei-components (e.g. varying M)
63 % offline_data = rb_offline_prep(detailed_data,model);
64 % M is assumed to be set
65 % reduced_data = rb_online_prep(offline_data,model);
66 for oi = 1:length(detailed_data.BM)
67 M = min( model.M, size(detailed_data.BM{oi},2) );
69 % prepare online-data
for online-ei-components (e.g. varying M)
70 % M is assumed to be set
71 QM{oi} = detailed_data.QM{oi}(:,1:M);
72 BM{oi} = detailed_data.BM{oi}(1:M,1:M);
73 TM{oi} = detailed_data.TM{oi}(1:M);
76 if ~isfield(model,
'enable_error_estimator')
77 model.enable_error_estimator = 0;
80 % test of the effect of magic-point exchange
81 %TM = TM(randperm(model.M));
83 model.decomp_mode = 0;
86 RB = detailed_data.RB(:,1:model.N);
88 % initial values by midpoint evaluation
89 U0 = model.init_values_algorithm(model, detailed_data);
91 U = zeros(length(U0(:)),model.nt+1);
92 a = zeros(size(RB,2),model.nt+1);
93 if model.enable_error_estimator
94 reslog = zeros(1, model.nt);
97 a(:,1) = RB' * A * U0(:);
99 model.dt = model.T/model.nt;
100 operators_required = 1;
101 if isempty(model.data_const_in_time)
102 model.data_const_in_time = 0;
105 impl_CRB_ind = detailed_data.implicit_crb_index;
106 expl_CRB_ind = detailed_data.explicit_crb_index;
111 disp(['entered time-loop step ',num2str(t)]);
115 % get matrices and bias-vector
116 if operators_required
117 model.t = (t-1)*model.dt;
119 if all([model.fv_impl_conv_weight, model.fv_impl_diff_weight, model.fv_impl_react_weight] == [0, 0, 0])
120 % purely explicit scheme
122 tmpmodel.decomp_mode = 0;
123 [L_I_space, b_I] = model.implicit_operators_algorithm(model, ...
125 elseif ~model.newton_solver % implicit scheme without
newton steps
126 % get implicit contributions
128 [L_I_red, b_I_red] = ...
129 model.implicit_operators_algorithm(tmpmodel, detailed_data, []);
131 L_I_space = QM{impl_CRB_ind} * (BM{impl_CRB_ind} \ ...
132 L_I_red(TM{impl_CRB_ind},:));
134 b_I = QM{impl_CRB_ind} * (BM{impl_CRB_ind} \ b_I_red(TM{impl_CRB_ind}));
135 L_I_space = sparse(L_I_space);
142 if model.data_const_in_time
143 operators_required = 0;
148 % compute real explicit operator result, but only use the magic-point entries
149 % and perform an empirical interpolation instead
150 inc = model.L_E_local_ptr(model, detailed_data, U(:,t), []);
152 inc_local = inc(TM{expl_CRB_ind});
153 %ei_coefficients = BM \ inc_local;
154 %ei_inc = detailed_data.QM(:,1:model.M)*ei_coefficients;
155 ei_inc = QM{expl_CRB_ind} * (BM{expl_CRB_ind} \ inc_local);
157 % projection on RB space
158 a_inc = RB' * A * ei_inc;
160 if model.newton_solver
161 updelta = zeros(length(U0), model.newton_steps+1);
162 updelta_a = zeros(model.N, model.newton_steps+1);
163 exprhs_a = model.dt * a_inc;
164 updelta_a(:,1) = a(:,t) - exprhs_a;
171 for n=1:model.newton_steps;
172 if model.verbose > 10
173 disp([
'Computing time step no. ', num2str(t), ...
174 ', Newton step no. ', num2str(n), ...
175 '... Residual norm: ']);
177 model.t = model.t + model.dt;
178 Urhs = model.L_I_local_ptr(model, detailed_data, updelta(:,n), []);
180 % project result of L_I onto CRB
181 Urhs_local = Urhs(TM{impl_CRB_ind});
182 Urhs_ei_coeffs = BM{impl_CRB_ind} \ Urhs_local;
183 Urhs_ei = QM{impl_CRB_ind}(:,1:model.M) * Urhs_ei_coeffs;
185 % project Urhs_ei onto RB
186 Urhs_a = RB
' * A * Urhs_ei;
188 % get derivative DL_I (interpolation is done only implicitly)
189 [gradL_I_local, gL_I_offset_local] = ...
190 model.implicit_gradient_operators_algorithm(model, detailed_data, ...
193 model.t = model.t - model.dt;
194 % gL_I_offset_ei = QM{impl_CRB_ind} * (BM{impl_CRB_ind} \ ...
195 % gL_I_offset_local(reduced_data.TM_local));
197 % gradL_I_ei = QM{impl_CRB_ind} * (BM{impl_CRB_ind} \ gradL_I_local);
198 gradL_I_ei = gradL_I_local;
200 % project onto RB space
201 gradL_I_rb = RB' * A * gradL_I_ei * RB;
203 gradL_I_rb = gradL_I_rb * model.dt + speye(size(gradL_I_rb));
205 rhs_a = -updelta_a(:,n) + a(:,t) - exprhs_a - model.dt * Urhs_a;
207 delta_a = gradL_I_rb \ rhs_a;
209 delta = RB * delta_a;
211 residual = sqrt(model.inner_product(model, detailed_data, delta, delta));
212 if model.verbose > 10
213 disp(num2str(residual));
215 updelta(:,n+1) = updelta(:,n) + delta;
216 updelta_a(:,n+1) = updelta_a(:,n) + delta_a;
217 if residual < model.newton_epsilon
222 a(:,t+1) = updelta_a(:,n+1);
223 U(:,t+1) = updelta(:,n+1);
224 Unewton = [ Unewton, updelta(:,1:n+1) ];
226 L_I = L_I_space * model.dt + speye(size(L_I_space));
227 % ei_inc = RB * a_inc;
229 a_rhs = a(:,t) - model.dt * a_inc - model.dt * a_I;
231 % disp(
'check rhs and inc!!');
234 if isequal(L_I, speye(size(L_I)))
237 U(:,t+1) = RB * a(:,t+1);
239 % solve linear system
240 % disp('check symmetry and choose solver accordingly!');
242 % nonsymmetric solvers:
243 % [U(:,t+1), flag] = bicgstab(L_I,rhs,[],1000);
244 % [U(:,t+1), flag] = cgs(L_I,rhs,[],1000);
246 % symmetric solver, non pd:
248 % see bug_symmlq.mat for a very strange bug: cannot solve identity system!
249 % reported to matlab central, but no solution up to now.
250 % [U(:,t+1), flag] = symmlq(L_I,rhs,[],1000);
252 % [U(:,t+1), flag] = minres(L_I,rhs,[],1000);
253 % symmetric solver, pd:
254 a(:,t+1) = RB' * A * L_I * RB \ a_rhs;
255 U(:,t+1) = RB * a(:,t+1);
256 % [U(:,t+1), flag] = bicgstab(L_I,rhs,[],1000);
258 disp(['error in system solution, solver return flag = ', ...
263 % plot_element_data(grid,U(:,t),params);
267 if model.enable_error_estimator
268 % compute `\delta t R^k` explicitly and store in reslog(t)
269 residuum = U(:,t) - U(:,t+1) - model.dt * ei_inc;
270 reslog(t) = sqrt(residuum' * A * residuum);
271 % res2 = -model.dt * (ei_inc - RB * a_inc);
272 % norm(res2) - norm(residuum) < 10*eps
278 if model.newton_solver && model.
verbose > 0
279 disp(['computation ready: We needed at most ', num2str(nmax), ' Newton steps']);
287 ei_rb_proj_data.U = U;
288 ei_rb_proj_data.a = a;
290 if model.newton_solver
291 ei_rb_proj_data.Unewton = Unewton;
294 if model.enable_error_estimator
295 ei_rb_proj_data.reslog = reslog;
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
function [ descr , rdescr , dmodel , rmodel ] = newton(steps, combined, M_by_N_ratio, noof_ei_extensions, use_laplacian, model_size, random, num_cpus, Mstrich)
small script demonstrating a buckley leverett problem discretization and RB model reduction ...