rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
detailed_simulation.m
1 function sim_data = detailed_simulation(dmodel, model_data)
2 % function sim_data = detailed_simulation(dmodel, model_data)
3 % executes a detailed simulation for a given parameter
4 %
5 % required fields of model:
6 % T : final time
7 % nt : number of time-steps
8 % `0 = t_0 \leq t_1 \leq \cdots \leq t^K+1 = T`, i.e. `K+1`.
9 % init_values_algorithm : function pointer for computing the initvalues-DOF
10 % with arguments '(model, model_data)'
11 % - example: fv_init_values()
12 % .
13 % L_E_local_ptr : function pointer to the local space-discretization
14 % operator evaluation with syntax
15 % @code
16 % INC_local = L_local(U_local_ext, ind_local, grid_local_ext)
17 % @endcode
18 % where '*_local' indicates results on a set of elements,
19 % '*_local_ext' includes information including their
20 % neighbours, i.e. the grid must be known also for the
21 % neighbours, the values of the previous timstep must be known
22 % on the neighbours. The subset of elements, which are to be
23 % computed are given in ind_local and the values produced are
24 % 'INC_local'.
25 % A time-step can then be realized by
26 % @code
27 % NU_local = U_local_ext(ind_local) - dt * INC_local
28 % @endcode
29 % - example: fv_conv_explicit_space()
30 % .
31 %
32 % optional fields of model:
33 % data_const_in_time : if this optional field is 1, the time
34 % evolution is performed with constant operators,
35 % i.e. only the initial-time-operators are computed
36 % and used throughout the time simulation.
37 %
38 % Return values:
39 % sim_data: structure holding the `H`-dimensional simulation data.
40 % fl: debug output holding the flux evaluations returned by the
41 % 'L_E_local_ptr' operator.
42 %
43 % Generated fields of sim_data:
44 % U: matrix of size `H \times K+1` holding for each time step the solution
45 % dof vector.
46 % Unewton: matrix of size `H \times K+1+\sum_{k=0}^K n_{\text{Newton}}(k)`
47 % holding for each time step and each Newton iteration the
48 % intermediate solution dof vectors.
49 %
50 
51 
52 % Martin Drohmann 9.12.2007 based on detailed_nonlin_evol_simulation.m by
53 % Bernard Haasdonk
54 
55 if nargin ~= 2
56  error('wrong number of parameters!');
57 end;
58 
59 if dmodel.verbose >= 9
60  disp('entered detailed simulation ');
61 end;
62 
63 if isempty(model_data)
64  model_data = gen_model_data(dmodel);
65 end;
66 
67 
68 % for a detailed simulation we do not need the affine parameter
69 % decomposition
70 dmodel.decomp_mode = 0;
71 
72 model = dmodel.descr;
73 
74 % initial values by midpoint evaluation
75 S0 = model.init_values.evaluate(model,model_data);
76 
77 S = zeros(length(S0(:)),model.nt+1);
78 %Stemp = zeros(length(S0(:)),2*model.nt+2);
79 U = zeros(model_data.gn_edges, model.nt+1);
80 %Utemp = zeros(model_data.gn_edges, 2*model.nt+2);
81 P = zeros(length(S0(:)),model.nt+1);
82 %Ptemp = zeros(length(S0(:)),2*model.nt+2);
83 Stemp = [];
84 Ptemp = [];
85 Utemp = [];
86 exflags = zeros(1, model.nt+1);
87 outtext = cell(1, model.nt+1);
88 Slength = length(S0(:));
89 Ulength = model_data.gn_edges;
90 %totlength = 2*Slength+length(grid.VI);
91 S(:,1) = S0(:);
92 
93 model.dt = model.T / model.nt;
94 
95 for t = 1:model.nt
96  model.t = (t-1)*model.dt;
97  model.tstep = t;
98  if model.verbose > 19
99  disp(['entered time-loop step ',num2str(t), ' for non linear evolution equation']);
100  elseif model.verbose > 9
101  fprintf('.');
102  end;
103  fprintf('.');
104 
105  % V = zeros(totlength, model.newton_steps+1);
106  V_last = [S(:,t); U(:,t); P(:,t)];
107 
108  model.t = model.t + model.dt;
109 
110 % Srhs = model.S_local_ptr(model, model_data, V(1:Slength+Ulength,n), []);
111 % Urhs = model.U_local_ptr(model, model_data, V(Slength+1:end,n), []);
112 % Prhs = model.P_local_ptr(model, model_data, V(Slength+Ulength+1:end,n), []);
113 % gradSM = model.S_op_matrix(model, model_data, V(Slength+1:Slength+Ulength,n), []);
114 % gradUM = model.U_op_matrix(model, model_data, V(1:Slength,n), []);
115 % gradPM = model.P_op_matrix(model, model_data, v(Slength+Ulength+1:end,n), []);
116 
117  fsolve_fun = @(X) sat_fun(model, model_data, S(:,t), X, Slength, Ulength+Slength);
118  %[(X(1:Slength)-S(:,t))./model.dt;zeros(Ulength+Slength+1,1)] ...
119  % + fv_two_phase_space(model, model_data, X, []);
120 
121  %LB = [zeros(Slength,1);-Inf(Ulength,1);-Inf(Slength,1)];
122  %UB = [ones(Slength,1)-100*eps;Inf(Ulength,1);Inf(Slength,1)];
123  %[V_new, resnorm, FV, exitflag, output] = lsqnonlin(fsolve_fun, V_last, LB, UB,...
124  % optimset('Display', 'iter', ...
125  % 'Algorithm', 'trust-region-reflective',...
126  % 'Jacobian', 'on', ...
127  % 'FinDiffType', 'central', ...
128  % 'Diagnostics', 'on', ...
129  % 'DerivativeCheck', 'off'));
130  % [V_new, FV, exitflag, output, jacobian] = fsolve(fsolve_fun, V_last, ...
131  % optimset('LargeScale', 'on', ... %'Algorithm', 'levenberg-marquardt', ...
132  % 'Display', 'iter', ...
133  % 'Jacobian', 'on', ...
134  % 'Diagnostics', 'off', ...
135  % 'DerivativeCheck', 'off'...
136  % ));
137 
138  gplmmopts.Px = @(X) box_projection(X, Slength);
139 % gplmmopts.HessFun = @(params, jac, dummy, arg) jac' * (jac * arg);
140  gplmmopts.Slength = Slength;
141  [V_new, resnorm, FV, exitflag, output, tempsols] = gplmm(fsolve_fun, V_last, gplmmopts);
142 
143  V_new = real(V_new);
144  disp(['t= ', num2str(model.t)]);
145 
146  exflags(t) = exitflag;
147  outtext{t} = output;
148 
149  %% TODO: This is bad! Isn't it?
150  S(:,t+1) = min(V_new(1:Slength),1-eps);
151  Stemp = [Stemp, tempsols(1:Slength,:)];
152  U(:,t+1) = V_new(Slength+1:Slength+Ulength);
153  Utemp = [Utemp, tempsols(Slength+1:Slength+Ulength,:)];
154  P(:,t+1) = V_new(Slength+Ulength+1:end);
155  Ptemp = [Ptemp, tempsols(Slength+Ulength+1:end,:)];
156 
157 end
158 
159 sim_data.S = S;
160 sim_data.Stemp = Stemp;
161 sim_data.U = U;
162 sim_data.Utemp = Utemp;
163 sim_data.P = P;
164 sim_data.Ptemp = Ptemp;
165 sim_data.exit_flags = exflags;
166 sim_data.outputs = outtext;
167 
168 if model.verbose > 9
169  fprintf('\n');
170 end
171 
172 function [ret, J] = sat_fun(descr, model_data, Sold, X, Uoff, Poff)
173 
174  Stemp = X(1:Uoff);
175  % Stemp(Stemp < 0) = 0+eps;
176  % Stemp(Stemp > 1) = 1-eps;
177  arglength = length(X);
178  L_sat_arg.S = Stemp;
179  L_sat_arg.U = X(Uoff+1:Poff);
180  L_sat_arg.Uoff = Uoff;
181  L_sat_arg.m = arglength;
182  [sat_ret, dummy, sat_Jret] = descr.L_saturation.apply(descr, model_data, L_sat_arg);
183  sat_ret = (Stemp - Sold)./descr.dt + sat_ret;
184 
185  L_vel_arg.S = Stemp;
186  L_vel_arg.P = X(Poff+1:end);
187  L_vel_arg.Poff = Poff;
188  L_vel_arg.n = Poff-Uoff;
189  L_vel_arg.m = arglength;
190  [vel_ret, dummy, vel_Jret] = descr.L_velocity.apply(descr, model_data, L_vel_arg);
191 
192  L_div_arg.U = X(Uoff+1:Poff);
193  L_div_arg.Uoff = Uoff;
194  L_div_arg.m = arglength;
195  [div_ret, dummy, div_Jret] = descr.L_divergence.apply(descr, model_data, L_div_arg);
196 
197 % prs_ret = X(Poff+1);
198  [prs_ret, dummy, prs_Jret] = descr.L_pressure.apply(descr, model_data, L_vel_arg);
199 
200  ret = [sat_ret; vel_ret - X(Uoff+1:Poff); div_ret; prs_ret];
201  assert(all(~isnan(ret)));
202  assert(all(~isinf(ret)));
203 
204 % [ret2, Jret2] = fv_two_phase_space(descr, model_data, X);
205 % retlength = length(ret2);
206 
207  if nargout > 1
208 
209  n = size(vel_Jret,1);
210  sp_minus_U = sparse(1:n, Uoff+1:Poff, -1, n,arglength);
211  J = [ sparse(1:Uoff, 1:Uoff, 1/descr.dt * ones(1,Uoff), Uoff, arglength) ...
212  + sat_Jret; ...
213  vel_Jret + sp_minus_U; ...
214  div_Jret; ...
215  prs_Jret ];
216 % zeros(1,Poff), 1, zeros(1,Uoff-1) ];
217 
218 % J2 = sparse(1:Uoff, 1:Uoff, ...
219 % 1/descr.dt * ones(1,Uoff), ...
220 % retlength, arglength) ...
221 % + Jret2;
222 % keyboard;
223  end
224 
225 function Xproj = box_projection(X, Slength)
226 
227  SX = X(1:Slength);
228  SX(SX<0) = eps;
229  upper_bound = 1.0;%0.6359878341047967;
230  SX(SX>upper_bound) = upper_bound-eps;
231  Xproj = [SX; X(Slength+1:end)];
232 
233 % dd = evalin('base', 'dd');
234 % sat_dd = get_by_description(dd.datatree.rb, 'saturation');
235 % vel_dd = get_by_description(dd.datatree.rb, 'velocity');
236 % prs_dd = get_by_description(dd.datatree.rb, 'pressure');
237 % aaa = sat_dd.RB' * dd.model_data.W * SX;
238 % bbb = vel_dd.RB' * dd.model_data.diamondW * X(Slength+1:Slength+size(vel_dd.RB,1));
239 % ccc = prs_dd.RB' * dd.model_data.W * X(Slength+size(vel_dd.RB,1)+1:end);
240 % Xproj = [sat_dd.RB * aaa; vel_dd.RB * bbb; prs_dd.RB * ccc];
241 
242 
243 
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
function [ xnew , resnorm , residual , exitflag , output , tempsols ] = gplmm(funptr, x0, params)
Global projected Levenberg-Marquard method.
Definition: gplmm.m:17