rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
stokes_gen_reduced_data.m
1 function reduced_data = stokes_gen_reduced_data(model, detailed_data)
2 %function reduced_data = stokes_gen_reduced_data(model, detailed_data)
3 %
4 % Computes reduced data for stokes problems
5 
6 
7 reduced_data = [];
8 
9 model.decomp_mode = 1;
10 
11 pool = gcp('nocreate');
12 nWorkers = 0;
13 if ~isempty(pool)
14  nWorkers = pool.NumWorkers;
15 end
16 
17 N = model.get_rb_size(model, detailed_data);
18 reduced_data.N = N;
19 
20 % get matrix and rhs components
21 op = detailed_data.operators;
22 if ~op.componentsAssembled
23  op.assemble_components(model, detailed_data);
24 end
25 
26 Q_A = length(op.A_comp);
27 reduced_data.Q_A = Q_A;
28 Q_f = length(op.f_comp);
29 reduced_data.Q_f = Q_f;
30 
31 % compute components for residual error estimator
32 K = model.get_inner_product_matrix(detailed_data);
33 ndofs = detailed_data.df_info.ndofs;
34 K = K + eps*speye(ndofs);
35 reduced_data.KN = detailed_data.RB' * K * detailed_data.RB;
36 
37 dirichlet_gids = detailed_data.bc_info.dirichlet_gids;
38 
39 if ~isempty(dirichlet_gids)
40  K(dirichlet_gids, :) = 0;
41  K(:, dirichlet_gids) = 0;
42  K_dirichlet = sparse(dirichlet_gids, dirichlet_gids, ...
43  ones(size(dirichlet_gids)), ndofs, ndofs);
44  K = K + K_dirichlet;
45 end
46 % system matrix complete.
47 
48 K_v_f = cell2mat(op.f_comp);
49 
50 % compute reduced rhs components
51 reduced_data.fN_comp = cell(1, Q_f);
52 for q = 1:Q_f
53  reduced_data.fN_comp{q} = detailed_data.RB' * op.f_comp{q};
54 end
55 
56 K_v_a = {zeros(size(K, 1), 0)};
57 for i = 1:N
58  K_v_a{i} = zeros(size(K, 1), Q_A);
59  for q = 1:Q_A
60  K_v_a{i}(:, q) = op.A_comp{q} * detailed_data.RB(:, i);
61  end
62 end
63 
64 K_v_a_nl = {zeros(size(K, 1), 0)};
65 reduced_data.N_nl = 0;
66 Q_A_nl = 0;
67 if N > 0 && model.has_nonlinearity
68 
69  N_nl = size(get(detailed_data.RB, 1), 2);
70  f_dir = detailed_data.bc_info.dirichlet_dof_vector_components;
71 
72  % compute components for each basis function
73  model.uh = Fem.DiscFunc([], detailed_data.df_info);
74  RB = detailed_data.RB;
75  Q_A_nl = cell(1, N_nl);
76  K_v_a_nl = cell(1, N_nl);
77 
78  parfor (i = 1:N_nl, nWorkers)
79 
80  tmodel = model;
81  tmodel.uh.dofs = RB(:, i);
82  A_nl_comp = model.operators(tmodel, detailed_data);
83  Q_A_nl{i} = length(A_nl_comp);
84 
85  K_v_a_nl{i} = zeros(size(K, 1), N_nl*Q_A_nl{i});
86  for q = 1:Q_A_nl{i}
87  K_v_a_nl{i}(:, q:Q_A_nl{i}:N_nl*Q_A_nl{i}) = A_nl_comp{q} * RB(:, 1:N_nl);
88  end
89 
90  for qA = 1:Q_A_nl{i}
91  for qf = 1:length(f_dir)
92  K_v_a{i}(:, (qf-1)*Q_A_nl{i}+qA) = K_v_a{i}(:, (qf-1)*Q_A_nl{i}+qA) + ...
93  A_nl_comp{qA} * f_dir{qf};
94  end
95  end
96  end
97 
98  Q_A_nl = Q_A_nl{1};
99  reduced_data.AN_nl_comp = cell(1, N_nl);
100  for i = 1:N_nl
101  reduced_data.AN_nl_comp{i} = cell(1, Q_A_nl);
102  for q = 1:Q_A_nl
103  reduced_data.AN_nl_comp{i}{q} = ...
104  RB(:, 1:N_nl)' * K_v_a_nl{i}(:, q:Q_A_nl:N_nl*Q_A_nl);
105  end
106  end
107 
108  reduced_data.Q_A_nl = Q_A_nl;
109  reduced_data.N_nl = N_nl;
110 
111 end
112 
113 K_v_a = cell2mat(K_v_a);
114 K_v_a_nl = cell2mat(K_v_a_nl);
115 
116 reduced_data.AN_comp = cell(1, Q_A);
117 for q = 1:Q_A
118  reduced_data.AN_comp{q} = detailed_data.RB' * K_v_a(:, q:Q_A:N*Q_A);
119 end
120 
121 if isfield(model, 'RB_error_indicator') && ...
122  strcmp(model.RB_error_indicator, 'estimator')
123 
124  K_v_tot = [K_v_f, K_v_a];
125  v_tot = K \ K_v_tot;
126  if model.has_nonlinearity
127  n_nl = detailed_data.df_info.values{1}.ndofs;
128  K1 = K(1:n_nl, 1:n_nl);
129  v_tot_nl = K1 \ K_v_a_nl(1:n_nl, :);
130  end
131 
132  if model.has_nonlinearity && nWorkers > 0
133  v = VecMat.gram_schmidt_parallel(v_tot_nl, K1, 1000*eps);
134  v = VecMat.gram_schmidt_parallel(...
135  [[v; zeros(size(v_tot, 1)-n_nl, size(v, 2))], v_tot], ...
136  K, 1000*eps, size(v, 2));
137  else
138  [v, ind] = VecMat.gram_schmidt_reiterate(v_tot, K, 1000*eps);
139  end
140  %v = v_tot;
141 
142  reduced_data.G = v' * [K_v_tot, K_v_a_nl];
143  reduced_data.Q_v = size(reduced_data.G, 2);
144  reduced_data.res_onb_ind = ind;
145 
146  % constants needed in error estimator
147  if isfield(detailed_data, 'infsup_constant')
148  reduced_data.infsup_constant = detailed_data.infsup_constant;
149  else
150  warning('rbmatlab:stokes:gen_reduced_data', ...
151  'no infsup approximation available, default value: 1');
152  reduced_data.infsup_constant = @(mu) 1;
153  end
154 
155  if model.has_nonlinearity
156  if isfield(detailed_data, 'rho_sqr')
157  reduced_data.rho_sqr = detailed_data.rho_sqr;
158  else
159  warning('rbmatlab:stokes:gen_reduced_data', ...
160  'no sobolev embedding constant available, default value: 1/(2*sqrt(2))');
161  reduced_data.rho_sqr = 0.5/sqrt(2);
162  end
163  end
164 
165 end
166 
167 end