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
5 % required fields of model:
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()
13 % L_E_local_ptr :
function pointer to the local space-discretization
14 %
operator evaluation with syntax
16 % INC_local = L_local(U_local_ext, ind_local, grid_local_ext)
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
25 % A time-step can then be realized by
27 % NU_local = U_local_ext(ind_local) - dt * INC_local
29 % - example: fv_conv_explicit_space()
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.
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.
43 % Generated fields of sim_data:
44 % U: matrix of size `H \times K+1` holding for each time step the solution
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.
52 % Martin Drohmann 9.12.2007 based on detailed_nonlin_evol_simulation.m by
56 error(
'wrong number of parameters!');
59 if dmodel.verbose >= 9
60 disp(
'entered detailed simulation ');
63 if isempty(model_data)
64 model_data = gen_model_data(dmodel);
68 % for a detailed simulation we do not need the affine parameter
70 dmodel.decomp_mode = 0;
74 % initial values by midpoint evaluation
75 S0 = model.init_values.evaluate(model,model_data);
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);
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);
93 model.dt = model.T / model.nt;
96 model.t = (t-1)*model.dt;
99 disp(['entered time-loop step ',num2str(t), ' for non linear evolution equation']);
105 % V = zeros(totlength, model.newton_steps+1);
106 V_last = [S(:,t); U(:,t); P(:,t)];
108 model.t = model.t + model.dt;
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), []);
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, []);
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'...
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);
144 disp(['t= ', num2str(model.t)]);
146 exflags(t) = exitflag;
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,:)];
160 sim_data.Stemp = Stemp;
162 sim_data.Utemp = Utemp;
164 sim_data.Ptemp = Ptemp;
165 sim_data.exit_flags = exflags;
166 sim_data.outputs = outtext;
172 function [ret, J] = sat_fun(descr, model_data, Sold, X, Uoff, Poff)
175 % Stemp(Stemp < 0) = 0+eps;
176 % Stemp(Stemp > 1) = 1-eps;
177 arglength = length(X);
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;
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);
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);
197 % prs_ret = X(Poff+1);
198 [prs_ret, dummy, prs_Jret] = descr.L_pressure.apply(descr, model_data, L_vel_arg);
200 ret = [sat_ret; vel_ret - X(Uoff+1:Poff); div_ret; prs_ret];
201 assert(all(~isnan(ret)));
202 assert(all(~isinf(ret)));
204 % [ret2, Jret2] = fv_two_phase_space(descr, model_data, X);
205 % retlength = length(ret2);
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) ...
213 vel_Jret + sp_minus_U; ...
216 % zeros(1,Poff), 1, zeros(1,Uoff-1) ];
218 % J2 = sparse(1:Uoff, 1:Uoff, ...
219 % 1/descr.dt * ones(1,Uoff), ...
220 % retlength, arglength) ...
225 function Xproj = box_projection(X, Slength)
229 upper_bound = 1.0;%0.6359878341047967;
230 SX(SX>upper_bound) = upper_bound-eps;
231 Xproj = [SX; X(Slength+1:end)];
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];
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 [ xnew , resnorm , residual , exitflag , output , tempsols ] = gplmm(funptr, x0, params)
Global projected Levenberg-Marquard method.