1 function [r_source, r_dirichlet, r_neumann, r_robin] = ...
2 fem_rhs_parts_assembly(model,df_info)
3 %
function [r_source, r_dirichlet, r_neumann, r_robin] = ...
4 % fem_rhs_parts_assembly(model,df_info)
6 %
function assembling the right hand side vector parts
for solving an
7 % elliptic pde with finite elements
9 % - div ( a(x) grad u(x)) + div (b(x) u(x)) + c(x) u(x) = f(x) on Omega
10 % u(x)) = g_D(x) on Gamma_D
11 % a(x) (grad u(x)) n) = g_N(x) on Gamma_N
12 % alpha(x) u(x) + beta(x) a(x) (grad u(x)) n) = g_R(x) on Gamma_R
14 % s = l(u) linear output functional
16 % Here, we denote the functions as
17 % u: scalar 'solution' (if known, for validation purpose)
19 % a: tensor valued 'diffusivity_tensor'
20 % b: vector valued 'velocity'
21 % c: scalar 'reaction'
23 % g_N: scalar 'neumann_values'
24 % g_R: scalar 'robin_values'
25 % alpha: scalar 'robin_alpha'
26 % beta: scalar 'robin_beta'
28 % which are contained in a 'model'.See poisson_model for an
29 % extensive description.
30 % df_info is discrete-function-info containing the grid
31 % global_dof_index, dirichlet_indices, lagrange-nodes and further
32 % fem-information used by the system and the rhs assembly by
33 % fem_rhs_parts_assembly
35 % function allows affine decomposition, i.e. result depending on
38 % Bernard Haasdonk 13.1.2011
40 % modification: data functions of the 'model' are now assumed to be local
45 if model.decomp_mode == 2
49 r_source = model.source([],[],[],model);
53 if model.has_dirichlet_values
58 if model.has_neumann_values
59 r_neumann = model.neumann_values([],[],[],[],model);
63 if model.has_robin_values
64 r_robin = model.robin_values([],[],[],[],model);
67 else % decomp_mode == 1 or 0
69 ndofs = df_info.ndofs;
70 nelements = df_info.grid.nelements;
71 nlagrange_nodes = df_info.nlagrange_nodes;
74 llcoord = lagrange_nodes_edges_llcoord(model.pdeg); % 1d coordinates of lagrange nodes
76 if model.decomp_mode == 0
77 zerovec = zeros(ndofs,1);
79 zerovec = {zeros(ndofs,1)};
82 % right hand side vector assembly
84 % r = (r_i)_i=1...ndofs
86 % r_i = g_D(x_i)
if x_i in \Gamma_D
88 % r_i = r_i_source + r_i_neumann + r_i_robin
90 % r_i_volume = \int_Omega q * phi_i
92 % r_i_neumann = \int_Gamma_N g_N * phi_i
94 % r_i_robin = \int_Gamma_R g_R / beta * phi_i
99 r_source = fem_rhs_volume_part_assembly(...
100 model.source,model,df_info);
105 if model.has_neumann_values
106 r_neumann = fem_rhs_boundary_part_assembly(...
107 @fem_rhs_neumann_integral_kernel,model,df_info,df_info.neumann_elind,df_info.neumann_edgeind);
112 if model.has_robin_values
113 r_robin = fem_rhs_boundary_part_assembly(...
114 @fem_rhs_robin_integral_kernel,model,df_info,df_info.robin_elind,df_info.robin_edgeind);
117 r_dirichlet = zerovec;
118 if model.has_dirichlet_values
119 % dirichlet-treatment: insert dirichlet values into rhs
120 % little loop over local lagrange node index
121 %
this will be repeated in A assembly as these will be kept separated
122 for i=1:nlagrange_nodes
123 % search all elements, in which the i-th Lagrange node is
125 eids = find(df_info.lagrange_edges(i,:)==1);
127 for e = eids; % possibly one point belongs to 2 edges!!
128 elids = find(grid.NBI(:,e)==-1);
129 %if llcoord(i,e) == -1
130 % disp('wrong llcoord values in lagrange_nodes_edges_llcoord!');
132 dirvals = model.
dirichlet_values(grid,elids,e,llcoord(i,e),model); % local model!
133 gids = df_info.global_dof_index(elids,i);
134 if model.decomp_mode == 0
135 r_dirichlet(gids) = dirvals;
136 else % decomp_mode = 1
137 if length(dirvals)~=length(r_dirichlet)
138 r_dirichlet = cell(1,length(r_dirichlet));
139 for q = 1:length(dirvals)
140 r_dirichlet{q} = zeros(ndofs,1);
143 for q = 1:length(dirvals)
144 r_dirichlet{q}(gids) = dirvals{q};
function Udirichlet = dirichlet_values(model, X, Y)
UDIRICHLET = DIRICHLET_VALUES([X],[Y], MODEL) Examples dirichlet_values([0,1,2],[1,1,1],struct(name_dirichlet_values, homogeneous, ... c_dir, 1)) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, xstripes, ... c_dir, [0 1 2], ... dir_borders, [0.3 0.6])) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, box, ... c_dir, 1, ... dir_box_xrange, [0.3 0.6], ... dir_box_yrange, [-0.1 0.1]))
function local_model = elliptic_discrete_model(model)
function creating a model with local functions out of a model with global functions. See detailed description for explanation.