1 function sim_data = detailed_simulation_galerkin(dmodel, detailed_data)
2 %
function sim_data = detailed_simulation(dmodel, detailed_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 model_data = dd.model_data;
59 error(
'wrong number of parameters!');
62 if dmodel.verbose >= 9
63 disp(
'entered detailed simulation ');
66 if isempty(model_data)
67 model_data = gen_model_data(dmodel);
71 % for a detailed simulation we do not need the affine parameter
73 dmodel.decomp_mode = 0;
77 % initial values by midpoint evaluation
78 S0 = model.init_values.evaluate(model,model_data);
80 dd_sat = get_by_description(dd.datatree.rb, 'saturation');
81 dd_vel = get_by_description(dd.datatree.rb, 'velocity');
82 dd_prs = get_by_description(dd.datatree.rb, 'pressure');
83 sat_N = size(dd_sat.RB, 2);
84 vel_N = size(dd_vel.RB, 2);
85 prs_N = size(dd_prs.RB, 2);
87 S = zeros(length(S0(:)),model.nt+1);
88 U = zeros(model_data.gn_edges, model.nt+1);
89 P = zeros(length(S0(:)),model.nt+1);
90 sat_a = zeros(sat_N, model.nt+1); % matrix of saturation RB-coefficients
91 vel_a = zeros(vel_N, model.nt+1); % matrix of velocity RB-coefficients
92 prs_a = zeros(prs_N, model.nt+1); % matrix of pressure RB-coefficients
93 exflags = zeros(1, model.nt+1);
94 outtext = cell(1, model.nt+1);
95 Slength = length(S0(:));
96 Ulength = model_data.gn_edges;
98 %totlength = 2*Slength+length(grid.VI);
101 dW = model_data.diamondWinv;
102 dd_satl2 = dd_sat.RB';
103 dd_vell2 = dd_vel.RB';
104 dd_prsl2 = dd_prs.RB';
106 sat_a(:,1) = dd_satl2 * W * S(:,1);
107 %sim_data = evalin('base', 'sim_data');
108 %prs_a(:,1) = dd_prsl2 * W * sim_data.P(:,2);
109 %vel_a(:,1) = dd_vell2 * dW * sim_data.U(:,2);
112 model.dt = model.T / model.nt;
115 model.t = (t-1)*model.dt;
118 disp(['entered time-loop step ',num2str(t), ' for non linear evolution equation']);
124 % sat_a(:,t+1) = dd_satl2 * W * sim_data.S(:,t+1);
125 % vel_a(:,t+1) = dd_vell2 * dW * sim_data.U(:,t+1);
126 % prs_a(:,t+1) = dd_prsl2 * W * sim_data.P(:,t+1);
127 % V = zeros(totlength, model.newton_steps+1);
128 V_last = [sat_a(:,t); vel_a(:,t); prs_a(:,t)];
130 model.t = model.t + model.dt;
132 % Srhs = model.S_local_ptr(model, model_data, V(1:Slength+Ulength,n), []);
133 % Urhs = model.U_local_ptr(model, model_data, V(Slength+1:end,n), []);
134 % Prhs = model.P_local_ptr(model, model_data, V(Slength+Ulength+1:end,n), []);
135 % gradSM = model.S_op_matrix(model, model_data, V(Slength+1:Slength+Ulength,n), []);
136 % gradUM = model.U_op_matrix(model, model_data, V(1:Slength,n), []);
137 % gradPM = model.P_op_matrix(model, model_data, v(Slength+Ulength+1:end,n), []);
139 fsolve_fun = @(X) sat_fun(model, model_data, sat_a(:,t), X, dd_sat, dd_vel, dd_prs, dd_satl2, dd_vell2, dd_prsl2);
140 %[(X(1:Slength)-S(:,t))./model.dt;zeros(Ulength+Slength+1,1)] ...
141 % + fv_two_phase_space(model, model_data, X, []);
143 %LB = [zeros(Slength,1);-Inf(Ulength,1);-Inf(Slength,1)];
144 %UB = [ones(Slength,1)-100*eps;Inf(Ulength,1);Inf(Slength,1)];
145 %[V_new, resnorm, FV, exitflag, output] = lsqnonlin(fsolve_fun, V_last, LB, UB,...
146 % optimset('Display', 'iter', ...
147 % 'Algorithm', 'trust-region-reflective',...
148 % 'Jacobian', 'on', ...
149 % 'FinDiffType', 'central', ...
150 % 'Diagnostics', 'on', ...
151 % 'DerivativeCheck', 'off'));
152 % [V_new, FV, exitflag, output, jacobian] = fsolve(fsolve_fun, V_last, ...
153 % optimset('LargeScale', 'on', ... %'Algorithm', 'levenberg-marquardt', ...
154 % 'Display', 'iter', ...
155 % 'Jacobian', 'on', ...
156 % 'Diagnostics', 'off', ...
157 % 'DerivativeCheck', 'off'...
160 gplmmopts.Px = @(X) box_projection(X, Slength);
161 % gplmmopts.HessFun = @(params, jac, dummy, arg) jac' * (jac * arg);
162 gplmmopts.Slength = Slength;
163 [V_new, resnorm, FV, exitflag, output] =
gplmm(fsolve_fun, V_last, gplmmopts);
164 % [V_new, resnorm, FV, exitflag, output] =
newton_raphson(fsolve_fun, V_last, gplmmopts);
166 % sat_a(:,t) = dd_sat.RB' * model_data.W * sim_data.S(:,t);
167 % vel_a(:,t) = dd_vel.RB' * model_data.diamondWinv * sim_data.U(:,t);
168 % prs_a(:,t) = dd_prs.RB' * model_data.W * sim_data.P(:,t);
170 disp(['t= ', num2str(model.t)]);
172 exflags(t) = exitflag;
175 sat_a(:,t+1) = V_new(1:sat_N);
176 vel_a(:,t+1) = V_new(sat_N+1:sat_N+vel_N);
177 prs_a(:,t+1) = V_new(sat_N+vel_N+1:end);
178 S(:,t+1) = dd_sat.RB * sat_a(:,t+1);
179 % Stemp(:,2*t+1:2*t+2) = tempsols(1:Slength,:);
180 U(:,t+1) = dd_vel.RB * vel_a(:,t+1);
181 % Utemp(:,2*t+1:2*t+2) = tempsols(Slength+1:Slength+Ulength,:);
182 P(:,t+1) = dd_prs.RB * prs_a(:,t+1);
183 % Ptemp(:,2*t+1:2*t+2) = tempsols(Slength+Ulength+1:end,:);
187 sim_data.sat_a = sat_a;
188 sim_data.vel_a = vel_a;
189 sim_data.prs_a = prs_a;
191 %sim_data.Stemp = Stemp;
193 %sim_data.Utemp = Utemp;
195 %sim_data.Ptemp = Ptemp;
196 sim_data.exit_flags = exflags;
197 sim_data.outputs = outtext;
203 function [ret, J] = sat_fun(descr, model_data, Sold, X, dd_sat, dd_vel, dd_prs, dd_satl2, dd_vell2, dd_prsl2)
205 model_data = dd_sat.model_data;
207 dW = model_data.diamondWinv;
209 sat_N = size(dd_sat.RB, 2);
210 vel_N = size(dd_vel.RB, 2);
211 prs_N = size(dd_prs.RB, 2);
212 Uoff = size(dd_sat.RB, 1);
213 Poff = Uoff + size(dd_vel.RB, 1);
215 % Stemp(Stemp < 0) = 0+eps;
216 % Stemp(Stemp > 1) = 1-eps;
217 arglength = Poff + size(dd_prs.RB, 1);
218 L_sat_arg.S = dd_sat.RB * X(1:sat_N);
219 L_sat_arg.U = dd_vel.RB * X(sat_N+1:sat_N+vel_N);
220 % L_sat_arg.S = X(1:Uoff);
221 % L_sat_arg.U = X(Uoff+1:Poff);
222 L_sat_arg.Uoff = Uoff;
223 L_sat_arg.m = arglength;
224 [sat_ret, dummy, sat_Jret] = descr.L_saturation.apply(descr, model_data, L_sat_arg);
225 sat_ret = (X(1:sat_N) - Sold)./descr.dt + ( dd_satl2 * W * sat_ret );
226 % sat_ret = ddsatl2 * W * ( (X(1:Uoff) - Sold)./descr.dt + sat_ret );
228 L_vel_arg.S = dd_sat.RB * X(1:sat_N);
229 L_vel_arg.P = dd_prs.RB * X(sat_N+vel_N+1:end);
230 % L_vel_arg.S = X(1:Uoff);
231 % L_vel_arg.P = X(Poff+1:end);
232 L_vel_arg.Poff = Poff;
233 L_vel_arg.n = Poff-Uoff;
234 L_vel_arg.m = arglength;
235 [vel_ret, dummy, vel_Jret] = descr.L_velocity.apply(descr, model_data, L_vel_arg);
237 L_div_arg.U = dd_vel.RB * X(sat_N+1:sat_N+vel_N);
238 % L_div_arg.U = X(Uoff+1:Poff);
239 [div_Jret, div_bb] = descr.L_divergence.full_matrix(descr, model_data);
241 % real_NBI_ind = model_data.grid.NBI > 0 & model_data.grid.NBI < repmat((1:model_data.grid.nelements)', 1, 4);
242 % prs_mat = repmat(dd_prs.RB, 1, 4);
243 % prs_on_edge1 = zeros(1, model_data.gn_edges);
244 % prs_on_edge2 = zeros(1, model_data.gn_edges);
245 % prs_on_edge1(model_data.gEI(real_NBI_ind)) = prs_mat(real_NBI_ind);
246 % prs_on_edge2(model_data.gEI(real_NBI_ind)) = dd_prs.RB(model_data.grid.NBI(real_NB_ind));
247 div_ret = div_Jret * L_div_arg.U + div_bb;
248 % div_ret = div_Jret * L_div_arg.U + div_bb;
250 [prs_ret, dummy, prs_Jret] = descr.L_pressure.apply(descr, model_data, L_vel_arg);
252 % ret = [sat_ret; dd_vel.RB' * dW * (vel_ret) - X(sat_N+1:sat_N+vel_N); div_ret];
253 ret = [sat_ret; dd_vell2 * dW * (vel_ret) - X(sat_N+1:sat_N+vel_N); div_ret; prs_ret];
254 % ret = [sat_ret; dd_vell2 * dW * (vel_ret - X(Uoff+1:Poff)); div_ret; prs_ret];
256 assert(all(~isnan(ret)));
257 assert(all(~isinf(ret)));
259 % [ret2, Jret2] = fv_two_phase_space(descr, model_data, X);
260 % retlength = length(ret2);
265 m = sat_N + vel_N + prs_N;
266 sp_minus_U = sparse(1:n, sat_N+1:sat_N+vel_N, -1, n, m);
267 sat_Jret = dd_satl2 * W * ([sat_Jret(:,1:Uoff) * dd_sat.RB, sat_Jret(:,Uoff+1:Poff) * dd_vel.RB, zeros(Uoff, prs_N)]);
268 vel_Jret = dd_vell2 * dW * ([vel_Jret(:,1:Uoff) * dd_sat.RB, zeros(Poff-Uoff, vel_N), vel_Jret(:,Poff+1:end) * dd_prs.RB]);
269 div_Jret = ([zeros(Uoff, sat_N), div_Jret * dd_vel.RB, zeros(Uoff, prs_N)]);
270 J = [ sparse(1:sat_N, 1:sat_N, 1/descr.dt * ones(1,sat_N), sat_N, m) ...
272 vel_Jret + sp_minus_U; ...
274 zeros(1, sat_N+vel_N), prs_Jret(:,Poff+1:end) * dd_prs.RB ];
277 % sp_minus_U = [zeros(vel_N, Uoff), dd_vell2 * dW * sparse(1:n, 1:n, -1, n, n), zeros(vel_N, arglength - Poff)];
278 % sat_Jret = dd_satl2 * W * ([sat_Jret(:,1:Uoff), sat_Jret(:,Uoff+1:Poff), zeros(Uoff, arglength-Poff)]);
279 % vel_Jret = dd_vell2 * dW * ([vel_Jret(:,1:Uoff), zeros(Poff-Uoff, vel_N), vel_Jret(:,Poff+1:end)]);
280 % div_Jret = ([zeros(Uoff, Uoff), div_Jret, zeros(Uoff, Uoff)]);
281 % J = [ sparse(1:sat_N, 1:sat_N, 1/descr.dt * ones(1,sat_N), sat_N, m) ...
283 % vel_Jret + sp_minus_U; ...
285 % zeros(1, sat_N+vel_N), prs_Jret(:,Poff+1:end) * dd_prs.RB ];
287 % J2 = sparse(1:Uoff, 1:Uoff, ...
288 % 1/descr.dt * ones(1,Uoff), ...
289 % retlength, arglength) ...
294 function Xproj = box_projection(X, Slength)
299 % upper_bound = 1.0;%0.6359878341047967;
300 % SX(SX>upper_bound) = upper_bound-eps;
301 % Xproj = [SX; X(Slength+1:end)];
303 % dd = evalin('base', 'dd');
304 % sat_dd = get_by_description(dd.datatree.rb, 'saturation');
305 % vel_dd = get_by_description(dd.datatree.rb, 'velocity');
306 % prs_dd = get_by_description(dd.datatree.rb, 'pressure');
307 % aaa = sat_dd.RB' * dd.model_data.W * SX;
308 % bbb = vel_dd.RB' * dd.model_data.diamondW * X(Slength+1:Slength+size(vel_dd.RB,1));
309 % ccc = prs_dd.RB' * dd.model_data.W * X(Slength+size(vel_dd.RB,1)+1:end);
310 % 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.
function [ xnew , resnorm , residual , exitflag , output ] = newton_raphson(funptr, x0, params)
Global projected Levenberg-Marquard method.