rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
ldg_operators_adv_explicit.m
1 [L_E, b_dir] = ldg_operators_adv_explicit(model,model_data)
2 %[L_E, b_dir] = ldg_operators_adv_explicit(model,model_data)
3 %
4 % function computing the explicit operator matrices for an
5 % advection problem with ldg discretization. As numerical flux,
6 % simple upwinding is used currently. Can be more refined by other
7 % numerical fluxes.
8 
9 % Bernard Haasdonk 30.8.2009
10 
11 disp('to be adjusted!!');
12 keyboard;
13 
14 decomp_mode = model.decomp_mode;
15 
16 if decomp_mode ==2
17  % no not forget the minus - theta^q(v) for the analytical
18  % flux components!
19  v_coeff = params.velocity_coefficients_fct(params);
20  num_flux_matrix_coeff = ldg_edge_num_flux_matrix([],params);
21  L_E = [v_coeff(:);num_flux_matrix_coeff(:)];
22  b_dir = ...
23  error('to_be_implemented')
24 
25 elseif decomp_mode == 1
26  % compute inverted mass matrix, which is multiplied
27  % to all L_E and b_dir components later
28  params.dimrange = model.dimrange;
29  params.pdeg = model.pdeg;
30  Minv = ldg_inv_mass_matrix(params,model_data.grid,model.qdeg);
31  nbasefct = size(Minv,1);
32  nelements = model_data.grid.nelements;
33  nfaces = 3; % triagrid
34 
35  % initialize outputs
36  model.decomp_mode = 2; % coefficients
37  Q_v = length(model.velocity_ptr([],model));
38  Q_num_flux = length(ldg_adv_num_flux_matrix(model));
39  Q_dir = length(model.dirichlet_values_ptr([],model));
40  model.decomp_mode = 1; % components again
41 
42  L_E = cell(1,Q_v+Q_num_flux);
43  b_dir = cell{1,Q_num_flux*Q_dir};
44 
45  % 1. components of L_E: element flux integral
46  % all components of v
47  % entries of L_E_q:
48  % (L_E_q)_(e,i)(e,j) = int_e v_q grad phi_e,i phi_e,j
49 
50  % Integrate 4D-matrix function, but only once evaluating basis
51  L = triaquadrature(model.element_flux_qdeg,...
52  @ldg_element_flux_operator_fct,...
53  model_data.grid,params);
54  % multiply all integrals by Det(DF) in order to have element
55  % integral instead of reference element integral
56  DetDF = repmat(reshape(grid.A*2,[1,1,nelements,1]),...
57  nbasefct,nbasefct,1,Q_v);
58  L = L.*DetDF;
59 
60  % distribute matrix layers into L_E sparse matrix components
61  for q = 1:Q_v
62  L_E{q} = spblkdiag(L(:,:,:,q));
63  end;
64 
65  % 2. components of L_E: numerical flux
66  % all components of ldg_adv_num_flux_matrix
67  % (== comp of v for upwind flux)
68 
69  edge_flux_mat = intervalquadrature(model.edge_flux_qdeg,...
70  @ldg_edge_flux_operator_fct,...
71  model_data.grid,params);
72  %multiply with edgelengths in order to obtain real edge integral
73  EL = repmat(reshape(model_data.grid.EL,[1,1,nelements,nfaces,1]),...
74  [nbasefct,nbasefct,1,1,Q_v]);
75  edge_flux_mat = edge_flux_mat .* EL;
76 
77  % evaluate numerical flux matrix components from edge-flux-matrix
78  edge_num_flux_mat = ldg_edge_num_flux_matrix(edge_flux_mat,model);
79 
80  ...
81 
82  % distribute into further L_E components
83  for q = 1:Q_num_flux
84  L_E{q+Q_v} = sparse(size(Minv));
85  ...
86 
87  end;
88 
89  % 3. components of b_dir
90  % all combinations of bdir and num_flux_matrix components
91  for q1 = 1:Q_num_flux
92  for q2 = 1:Q_dir
93  b_dir{(q1-1)*Q_dir+q2} = zeros(size(Minv,1),1);
94  end;
95  end;
96  ... % efficient integration over all elements at once but only
97  % once evaluating basis functions
98 
99  % invert, such that explicit time discretization can be used
100  for q = 1:length(L_E)
101  L_E{q} = Minv * L_E{q};
102  end;
103  for q = 1:length(b_dir)
104  b_dir{q} = Minv * b_dir{q};
105  end;
106 
107 else % "complete" == decomp_mode = 0
108  % perform above for complete velocity field
109  % should not be a simple linear combination, as a new computation
110  % will be very surely faster.
111  disp('complete evaluation should be accelerated in ldg_operators_adv_explicit');
112  model.decomp_mode = 2;
113  [L_E_coeff, b_dir_coeff] = ldg_operators_adv_explicit(model,model_data);
114  model.decomp_mode = 1;
115  [L_E_comp, b_dir_comp] = ldg_operators_adv_explicit(model,model_data);
116  model.decomp_mode = 0;
117  L_E = lincomb_sequence(L_E_comp,L_E_coeff);
118  b_dir = lincomb_sequence(b_dir_comp,b_dir_coeff);
119 end;
120 
121 %| \docupdate
function res = intervalquadrature(poldeg, func, varargin)
integration of function func over reference interval == unit interval. by Gaussian quadrature exactly...
A triangular conforming grid in two dimensions.
Definition: triagrid.m:17