1 function reduced_data = stokes_gen_reduced_data(model, detailed_data)
2 %
function reduced_data = stokes_gen_reduced_data(model, detailed_data)
4 % Computes reduced data
for stokes problems
11 pool = gcp(
'nocreate');
14 nWorkers = pool.NumWorkers;
17 N = model.get_rb_size(model, detailed_data);
20 % get matrix and rhs components
21 op = detailed_data.operators;
22 if ~op.componentsAssembled
23 op.assemble_components(model, detailed_data);
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;
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;
37 dirichlet_gids = detailed_data.bc_info.dirichlet_gids;
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);
46 % system matrix complete.
48 K_v_f = cell2mat(op.f_comp);
50 % compute reduced rhs components
51 reduced_data.fN_comp = cell(1, Q_f);
53 reduced_data.fN_comp{q} = detailed_data.RB
' * op.f_comp{q};
56 K_v_a = {zeros(size(K, 1), 0)};
58 K_v_a{i} = zeros(size(K, 1), Q_A);
60 K_v_a{i}(:, q) = op.A_comp{q} * detailed_data.RB(:, i);
64 K_v_a_nl = {zeros(size(K, 1), 0)};
65 reduced_data.N_nl = 0;
67 if N > 0 && model.has_nonlinearity
69 N_nl = size(get(detailed_data.RB, 1), 2);
70 f_dir = detailed_data.bc_info.dirichlet_dof_vector_components;
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);
78 parfor (i = 1:N_nl, nWorkers)
81 tmodel.uh.dofs = RB(:, i);
82 A_nl_comp = model.operators(tmodel, detailed_data);
83 Q_A_nl{i} = length(A_nl_comp);
85 K_v_a_nl{i} = zeros(size(K, 1), N_nl*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);
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};
99 reduced_data.AN_nl_comp = cell(1, N_nl);
101 reduced_data.AN_nl_comp{i} = cell(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);
108 reduced_data.Q_A_nl = Q_A_nl;
109 reduced_data.N_nl = N_nl;
113 K_v_a = cell2mat(K_v_a);
114 K_v_a_nl = cell2mat(K_v_a_nl);
116 reduced_data.AN_comp = cell(1, Q_A);
118 reduced_data.AN_comp{q} = detailed_data.RB
' * K_v_a(:, q:Q_A:N*Q_A);
121 if isfield(model, 'RB_error_indicator
') && ...
122 strcmp(model.RB_error_indicator, 'estimator
')
124 K_v_tot = [K_v_f, K_v_a];
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, :);
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));
138 [v, ind] = VecMat.gram_schmidt_reiterate(v_tot, K, 1000*eps);
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;
146 % constants needed in error estimator
147 if isfield(detailed_data,
'infsup_constant')
148 reduced_data.infsup_constant = detailed_data.infsup_constant;
150 warning('rbmatlab:stokes:gen_reduced_data', ...
151 'no infsup approximation available, default value: 1');
152 reduced_data.infsup_constant = @(mu) 1;
155 if model.has_nonlinearity
156 if isfield(detailed_data, 'rho_sqr')
157 reduced_data.rho_sqr = detailed_data.rho_sqr;
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);