1 function [sim_data, fl] = 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);
67 % for a detailed simulation we do not need the affine parameter
69 dmodel.decomp_mode = 0;
73 if dmodel.compute_conditions
74 compute_conditions = true;
75 LIconds = zeros(1, model.nt);
78 compute_conditions = false;
81 % initial values by midpoint evaluation
82 U0 = model.init_values_algorithm(model,model_data);
84 U = zeros(length(U0(:)),model.nt+1);
87 if ~isfield(model,'data_const_in_time')
88 model.data_const_in_time = 0;
91 if ~isfield(model, 'newton_regularisation')
92 model.newton_regularisation = 0;
95 fl = cell(model.nt, 1);
97 if model.fv_impl_diff_weight ~= 0 && ~model.newton_solver
98 % diffusive part is computed implicitly.
100 [L_diff_I, const_diff_I] = model.implicit_operators_algorithm(model, model_data, []);
104 model.dt = model.T / model.nt;
110 model.t = (t-1)*model.dt;
113 disp(['entered time-loop step ',num2str(t), ' for non linear evolution equation']);
118 [inc, fluxes] = model.L_E_local_ptr(model, model_data, U(:,t), []);
123 if all([model.fv_impl_conv_weight, model.fv_impl_diff_weight, ...
124 model.fv_impl_react_weight] == [0, 0, 0])
125 % purely
explicit scheme
126 U(:,t+1) = U(:,t) - model.dt * inc;
127 elseif model.newton_solver
128 V = zeros(length(U0(:)),model.newton_steps+1);
129 exprhs = model.dt * inc;
130 V(:,1) = U(:,t) - exprhs;
135 for n=1:model.newton_steps;
136 if model.verbose > 10
137 disp([
'Computing time step no. ', num2str(t), ...
138 ', Newton step no. ', num2str(n), ...
139 '... Residual norm: ']);
141 model.t = model.t + model.dt;
142 Urhs = model.L_I_local_ptr(model, model_data, V(:,n), []);
143 [gradL_I, gL_I_offset] = ...
144 model.implicit_gradient_operators_algorithm(model, model_data, ...
146 if compute_conditions
147 gradLIconds = [gradLIconds, condest(gradL_I)];
149 model.t = model.t - model.dt;
150 gradL_I = gradL_I * model.dt + speye(size(gradL_I));
151 rhs = - V(:,n) + U(:,t) - exprhs - model.dt * Urhs;
153 residual = sqrt(model.inner_product(model, model_data, VU, VU));
155 if model.newton_regularisation
156 [i] = find(Vnew < 0);
158 % epsilon = 0.99*min(-V(i,n)./VU(i));
160 disp(
' == regularisation == ');
162 %Vnew = V(:,n) + epsilon * VU;
166 nres = Vnew - U(:,t) + exprhs + model.dt * Urhs;
167 nres = sqrt(model.inner_product(model, model_data, nres, nres));
168 if model.verbose > 10
169 disp([num2str(residual),
' newton residual: ', num2str(nres)]);
171 if nres < model.newton_epsilon
177 Unewton = [Unewton, V(:,1:n+1)];
178 nlast = nlast + n + 2;
179 else % scheme with implicit parts, but without newton_scheme
180 if ~model.data_const_in_time
182 model.t=model.t+model.dt;
183 [L_diff_I, const_diff_I] = model.implicit_operators_algorithm(model, model_data, []);
184 model.t=model.t-model.dt;
187 inc = inc - const_diff_I;
189 L_I = L_I * model.dt + speye(size(L_I));
190 if compute_conditions
191 LIconds(t) = condest(L_I);
193 % L_I = speye(size(L_diff_I));
196 rhs = U(:,t) - model.dt * inc; % + model.dt * L_diff_I * U(:,t);
198 U(:,t+1) = L_I \ rhs;
199 % [U(:,t+1), flag] = bicgstab(L_I, rhs, 10e-5, 1000);
201 disp([
'error in system solution, solver return flag = ', ...
208 if model.newton_solver && model.verbose > 0
209 disp([
'computation ready: We needed at most ', num2str(nmax),
' Newton steps']);
214 if compute_conditions
215 sim_data.conds.LI = LIconds;
216 sim_data.conds.gradLI = gradLIconds;
219 if model.newton_solver
220 sim_data.Unewton = Unewton;
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 clear_all_caches()
This function clears the caches generated for caching of gradient data in evolution schemes...